diff --git a/.gitattributes b/.gitattributes
index 47cae08bda325a7b6884c4f975b872b99dbac299..8f3a4c679169706b0858d96299b31197727709ad 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -39,3 +39,4 @@ ComfyUI/comfy/__pycache__/model_patcher.cpython-312.pyc filter=lfs diff=lfs merg
ComfyUI/comfy/__pycache__/sd.cpython-312.pyc filter=lfs diff=lfs merge=lfs -text
ComfyUI/comfy/__pycache__/supported_models.cpython-312.pyc filter=lfs diff=lfs merge=lfs -text
ComfyUI/comfy/k_diffusion/__pycache__/sampling.cpython-312.pyc filter=lfs diff=lfs merge=lfs -text
+ComfyUI/comfy/ldm/sam3/__pycache__/tracker.cpython-312.pyc filter=lfs diff=lfs merge=lfs -text
diff --git a/ComfyUI/comfy/ldm/flux/__pycache__/redux.cpython-312.pyc b/ComfyUI/comfy/ldm/flux/__pycache__/redux.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..7c7a92cf97bbfdf34b2af2e8fad08d9a02f361b2
Binary files /dev/null and b/ComfyUI/comfy/ldm/flux/__pycache__/redux.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/flux/controlnet.py b/ComfyUI/comfy/ldm/flux/controlnet.py
new file mode 100644
index 0000000000000000000000000000000000000000..7dcf82bbf3e8e9a369dda0df39f37f0653514747
--- /dev/null
+++ b/ComfyUI/comfy/ldm/flux/controlnet.py
@@ -0,0 +1,208 @@
+#Original code can be found on: https://github.com/XLabs-AI/x-flux/blob/main/src/flux/controlnet.py
+#modified to support different types of flux controlnets
+
+import torch
+import math
+from torch import Tensor, nn
+from einops import rearrange, repeat
+
+from .layers import (timestep_embedding)
+
+from .model import Flux
+import comfy.ldm.common_dit
+
+class MistolineCondDownsamplBlock(nn.Module):
+ def __init__(self, dtype=None, device=None, operations=None):
+ super().__init__()
+ self.encoder = nn.Sequential(
+ operations.Conv2d(3, 16, 3, padding=1, dtype=dtype, device=device),
+ nn.SiLU(),
+ operations.Conv2d(16, 16, 1, dtype=dtype, device=device),
+ nn.SiLU(),
+ operations.Conv2d(16, 16, 3, padding=1, dtype=dtype, device=device),
+ nn.SiLU(),
+ operations.Conv2d(16, 16, 3, padding=1, stride=2, dtype=dtype, device=device),
+ nn.SiLU(),
+ operations.Conv2d(16, 16, 3, padding=1, dtype=dtype, device=device),
+ nn.SiLU(),
+ operations.Conv2d(16, 16, 3, padding=1, stride=2, dtype=dtype, device=device),
+ nn.SiLU(),
+ operations.Conv2d(16, 16, 3, padding=1, dtype=dtype, device=device),
+ nn.SiLU(),
+ operations.Conv2d(16, 16, 3, padding=1, stride=2, dtype=dtype, device=device),
+ nn.SiLU(),
+ operations.Conv2d(16, 16, 1, dtype=dtype, device=device),
+ nn.SiLU(),
+ operations.Conv2d(16, 16, 3, padding=1, dtype=dtype, device=device)
+ )
+
+ def forward(self, x):
+ return self.encoder(x)
+
+class MistolineControlnetBlock(nn.Module):
+ def __init__(self, hidden_size, dtype=None, device=None, operations=None):
+ super().__init__()
+ self.linear = operations.Linear(hidden_size, hidden_size, dtype=dtype, device=device)
+ self.act = nn.SiLU()
+
+ def forward(self, x):
+ return self.act(self.linear(x))
+
+
+class ControlNetFlux(Flux):
+ def __init__(self, latent_input=False, num_union_modes=0, mistoline=False, control_latent_channels=None, image_model=None, dtype=None, device=None, operations=None, **kwargs):
+ super().__init__(final_layer=False, dtype=dtype, device=device, operations=operations, **kwargs)
+
+ self.main_model_double = 19
+ self.main_model_single = 38
+
+ self.mistoline = mistoline
+ # add ControlNet blocks
+ if self.mistoline:
+ control_block = lambda : MistolineControlnetBlock(self.hidden_size, dtype=dtype, device=device, operations=operations)
+ else:
+ control_block = lambda : operations.Linear(self.hidden_size, self.hidden_size, dtype=dtype, device=device)
+
+ self.controlnet_blocks = nn.ModuleList([])
+ for _ in range(self.params.depth):
+ self.controlnet_blocks.append(control_block())
+
+ self.controlnet_single_blocks = nn.ModuleList([])
+ for _ in range(self.params.depth_single_blocks):
+ self.controlnet_single_blocks.append(control_block())
+
+ self.num_union_modes = num_union_modes
+ self.controlnet_mode_embedder = None
+ if self.num_union_modes > 0:
+ self.controlnet_mode_embedder = operations.Embedding(self.num_union_modes, self.hidden_size, dtype=dtype, device=device)
+
+ self.gradient_checkpointing = False
+ self.latent_input = latent_input
+ if control_latent_channels is None:
+ control_latent_channels = self.in_channels
+ else:
+ control_latent_channels *= 2 * 2 #patch size
+
+ self.pos_embed_input = operations.Linear(control_latent_channels, self.hidden_size, bias=True, dtype=dtype, device=device)
+ if not self.latent_input:
+ if self.mistoline:
+ self.input_cond_block = MistolineCondDownsamplBlock(dtype=dtype, device=device, operations=operations)
+ else:
+ self.input_hint_block = nn.Sequential(
+ operations.Conv2d(3, 16, 3, padding=1, dtype=dtype, device=device),
+ nn.SiLU(),
+ operations.Conv2d(16, 16, 3, padding=1, dtype=dtype, device=device),
+ nn.SiLU(),
+ operations.Conv2d(16, 16, 3, padding=1, stride=2, dtype=dtype, device=device),
+ nn.SiLU(),
+ operations.Conv2d(16, 16, 3, padding=1, dtype=dtype, device=device),
+ nn.SiLU(),
+ operations.Conv2d(16, 16, 3, padding=1, stride=2, dtype=dtype, device=device),
+ nn.SiLU(),
+ operations.Conv2d(16, 16, 3, padding=1, dtype=dtype, device=device),
+ nn.SiLU(),
+ operations.Conv2d(16, 16, 3, padding=1, stride=2, dtype=dtype, device=device),
+ nn.SiLU(),
+ operations.Conv2d(16, 16, 3, padding=1, dtype=dtype, device=device)
+ )
+
+ def forward_orig(
+ self,
+ img: Tensor,
+ img_ids: Tensor,
+ controlnet_cond: Tensor,
+ txt: Tensor,
+ txt_ids: Tensor,
+ timesteps: Tensor,
+ y: Tensor,
+ guidance: Tensor = None,
+ control_type: Tensor = None,
+ ) -> Tensor:
+ if img.ndim != 3 or txt.ndim != 3:
+ raise ValueError("Input img and txt tensors must have 3 dimensions.")
+
+ if y is None:
+ y = torch.zeros((img.shape[0], self.params.vec_in_dim), device=img.device, dtype=img.dtype)
+ else:
+ y = y[:, :self.params.vec_in_dim]
+
+ # running on sequences img
+ img = self.img_in(img)
+
+ controlnet_cond = self.pos_embed_input(controlnet_cond)
+ img = img + controlnet_cond
+ vec = self.time_in(timestep_embedding(timesteps, 256))
+ if self.params.guidance_embed:
+ vec = vec + self.guidance_in(timestep_embedding(guidance, 256))
+ vec = vec + self.vector_in(y)
+ txt = self.txt_in(txt)
+
+ if self.controlnet_mode_embedder is not None and len(control_type) > 0:
+ control_cond = self.controlnet_mode_embedder(torch.tensor(control_type, device=img.device), out_dtype=img.dtype).unsqueeze(0).repeat((txt.shape[0], 1, 1))
+ txt = torch.cat([control_cond, txt], dim=1)
+ txt_ids = torch.cat([txt_ids[:,:1], txt_ids], dim=1)
+
+ ids = torch.cat((txt_ids, img_ids), dim=1)
+ pe = self.pe_embedder(ids)
+
+ controlnet_double = ()
+
+ for i in range(len(self.double_blocks)):
+ img, txt = self.double_blocks[i](img=img, txt=txt, vec=vec, pe=pe)
+ controlnet_double = controlnet_double + (self.controlnet_blocks[i](img),)
+
+ img = torch.cat((txt, img), 1)
+
+ controlnet_single = ()
+
+ for i in range(len(self.single_blocks)):
+ img = self.single_blocks[i](img, vec=vec, pe=pe)
+ controlnet_single = controlnet_single + (self.controlnet_single_blocks[i](img[:, txt.shape[1] :, ...]),)
+
+ repeat = math.ceil(self.main_model_double / len(controlnet_double))
+ if self.latent_input:
+ out_input = ()
+ for x in controlnet_double:
+ out_input += (x,) * repeat
+ else:
+ out_input = (controlnet_double * repeat)
+
+ out = {"input": out_input[:self.main_model_double]}
+ if len(controlnet_single) > 0:
+ repeat = math.ceil(self.main_model_single / len(controlnet_single))
+ out_output = ()
+ if self.latent_input:
+ for x in controlnet_single:
+ out_output += (x,) * repeat
+ else:
+ out_output = (controlnet_single * repeat)
+ out["output"] = out_output[:self.main_model_single]
+ return out
+
+ def forward(self, x, timesteps, context, y=None, guidance=None, hint=None, **kwargs):
+ patch_size = 2
+ if self.latent_input:
+ hint = comfy.ldm.common_dit.pad_to_patch_size(hint, (patch_size, patch_size))
+ elif self.mistoline:
+ hint = hint * 2.0 - 1.0
+ hint = self.input_cond_block(hint)
+ else:
+ hint = hint * 2.0 - 1.0
+ hint = self.input_hint_block(hint)
+
+ hint = rearrange(hint, "b c (h ph) (w pw) -> b (h w) (c ph pw)", ph=patch_size, pw=patch_size)
+
+ bs, c, h, w = x.shape
+ x = comfy.ldm.common_dit.pad_to_patch_size(x, (patch_size, patch_size))
+
+ img = rearrange(x, "b c (h ph) (w pw) -> b (h w) (c ph pw)", ph=patch_size, pw=patch_size)
+
+ h_len = ((h + (patch_size // 2)) // patch_size)
+ w_len = ((w + (patch_size // 2)) // patch_size)
+ img_ids = torch.zeros((h_len, w_len, 3), device=x.device, dtype=x.dtype)
+ img_ids[..., 1] = img_ids[..., 1] + torch.linspace(0, h_len - 1, steps=h_len, device=x.device, dtype=x.dtype)[:, None]
+ img_ids[..., 2] = img_ids[..., 2] + torch.linspace(0, w_len - 1, steps=w_len, device=x.device, dtype=x.dtype)[None, :]
+ img_ids = repeat(img_ids, "h w c -> b (h w) c", b=bs)
+
+ txt_ids = torch.zeros((bs, context.shape[1], 3), device=x.device, dtype=x.dtype)
+ return self.forward_orig(img, img_ids, hint, context, txt_ids, timesteps, y, guidance, control_type=kwargs.get("control_type", []))
diff --git a/ComfyUI/comfy/ldm/flux/layers.py b/ComfyUI/comfy/ldm/flux/layers.py
new file mode 100644
index 0000000000000000000000000000000000000000..e28d704b43522588dcf44e2c88adc80fd9a7db9f
--- /dev/null
+++ b/ComfyUI/comfy/ldm/flux/layers.py
@@ -0,0 +1,372 @@
+import math
+from dataclasses import dataclass
+
+import torch
+from torch import Tensor, nn
+
+from .math import attention, rope
+
+# Fix import for some custom nodes, TODO: delete eventually.
+RMSNorm = None
+
+class EmbedND(nn.Module):
+ def __init__(self, dim: int, theta: int, axes_dim: list):
+ super().__init__()
+ self.dim = dim
+ self.theta = theta
+ self.axes_dim = axes_dim
+
+ def forward(self, ids: Tensor) -> Tensor:
+ n_axes = ids.shape[-1]
+ emb = torch.cat(
+ [rope(ids[..., i], self.axes_dim[i], self.theta) for i in range(n_axes)],
+ dim=-3,
+ )
+
+ return emb.unsqueeze(1)
+
+
+def timestep_embedding(t: Tensor, dim, max_period=10000, time_factor: float = 1000.0):
+ """
+ Create sinusoidal timestep embeddings.
+ :param t: a 1-D Tensor of N indices, one per batch element.
+ These may be fractional.
+ :param dim: the dimension of the output.
+ :param max_period: controls the minimum frequency of the embeddings.
+ :return: an (N, D) Tensor of positional embeddings.
+ """
+ t = time_factor * t
+ half = dim // 2
+ freqs = torch.exp(-math.log(max_period) * torch.arange(start=0, end=half, dtype=torch.float32, device=t.device) / half)
+
+ args = t[:, None].float() * freqs[None]
+ embedding = torch.cat([torch.cos(args), torch.sin(args)], dim=-1)
+ if dim % 2:
+ embedding = torch.cat([embedding, torch.zeros_like(embedding[:, :1])], dim=-1)
+ if torch.is_floating_point(t):
+ embedding = embedding.to(t)
+ return embedding
+
+class MLPEmbedder(nn.Module):
+ def __init__(self, in_dim: int, hidden_dim: int, bias=True, dtype=None, device=None, operations=None):
+ super().__init__()
+ self.in_layer = operations.Linear(in_dim, hidden_dim, bias=bias, dtype=dtype, device=device)
+ self.silu = nn.SiLU()
+ self.out_layer = operations.Linear(hidden_dim, hidden_dim, bias=bias, dtype=dtype, device=device)
+
+ def forward(self, x: Tensor) -> Tensor:
+ return self.out_layer(self.silu(self.in_layer(x)))
+
+class YakMLP(nn.Module):
+ def __init__(self, hidden_size: int, intermediate_size: int, dtype=None, device=None, operations=None):
+ super().__init__()
+ self.hidden_size = hidden_size
+ self.intermediate_size = intermediate_size
+ self.gate_proj = operations.Linear(self.hidden_size, self.intermediate_size, bias=True, dtype=dtype, device=device)
+ self.up_proj = operations.Linear(self.hidden_size, self.intermediate_size, bias=True, dtype=dtype, device=device)
+ self.down_proj = operations.Linear(self.intermediate_size, self.hidden_size, bias=True, dtype=dtype, device=device)
+ self.act_fn = nn.SiLU()
+
+ def forward(self, x: Tensor) -> Tensor:
+ down_proj = self.down_proj(self.act_fn(self.gate_proj(x)) * self.up_proj(x))
+ return down_proj
+
+def build_mlp(hidden_size, mlp_hidden_dim, mlp_silu_act=False, yak_mlp=False, dtype=None, device=None, operations=None):
+ if yak_mlp:
+ return YakMLP(hidden_size, mlp_hidden_dim, dtype=dtype, device=device, operations=operations)
+ if mlp_silu_act:
+ return nn.Sequential(
+ operations.Linear(hidden_size, mlp_hidden_dim * 2, bias=False, dtype=dtype, device=device),
+ SiLUActivation(),
+ operations.Linear(mlp_hidden_dim, hidden_size, bias=False, dtype=dtype, device=device),
+ )
+ else:
+ return nn.Sequential(
+ operations.Linear(hidden_size, mlp_hidden_dim, bias=True, dtype=dtype, device=device),
+ nn.GELU(approximate="tanh"),
+ operations.Linear(mlp_hidden_dim, hidden_size, bias=True, dtype=dtype, device=device),
+ )
+
+
+class QKNorm(torch.nn.Module):
+ def __init__(self, dim: int, dtype=None, device=None, operations=None):
+ super().__init__()
+ self.query_norm = operations.RMSNorm(dim, dtype=dtype, device=device)
+ self.key_norm = operations.RMSNorm(dim, dtype=dtype, device=device)
+
+ def forward(self, q: Tensor, k: Tensor, v: Tensor) -> tuple:
+ q = self.query_norm(q)
+ k = self.key_norm(k)
+ return q.to(v), k.to(v)
+
+
+class SelfAttention(nn.Module):
+ def __init__(self, dim: int, num_heads: int = 8, qkv_bias: bool = False, proj_bias: bool = True, dtype=None, device=None, operations=None):
+ super().__init__()
+ self.num_heads = num_heads
+ head_dim = dim // num_heads
+
+ self.qkv = operations.Linear(dim, dim * 3, bias=qkv_bias, dtype=dtype, device=device)
+ self.norm = QKNorm(head_dim, dtype=dtype, device=device, operations=operations)
+ self.proj = operations.Linear(dim, dim, bias=proj_bias, dtype=dtype, device=device)
+
+
+@dataclass
+class ModulationOut:
+ shift: Tensor
+ scale: Tensor
+ gate: Tensor
+
+
+class Modulation(nn.Module):
+ def __init__(self, dim: int, double: bool, bias=True, dtype=None, device=None, operations=None):
+ super().__init__()
+ self.is_double = double
+ self.multiplier = 6 if double else 3
+ self.lin = operations.Linear(dim, self.multiplier * dim, bias=bias, dtype=dtype, device=device)
+
+ def forward(self, vec: Tensor) -> tuple:
+ if vec.ndim == 2:
+ vec = vec[:, None, :]
+ out = self.lin(nn.functional.silu(vec)).chunk(self.multiplier, dim=-1)
+
+ return (
+ ModulationOut(*out[:3]),
+ ModulationOut(*out[3:]) if self.is_double else None,
+ )
+
+
+def apply_mod(tensor, m_mult, m_add=None, modulation_dims=None):
+ if modulation_dims is None:
+ if m_add is not None:
+ return torch.addcmul(m_add, tensor, m_mult)
+ else:
+ return tensor * m_mult
+ else:
+ for d in modulation_dims:
+ tensor[:, d[0]:d[1]] *= m_mult[:, d[2]:d[2] + 1]
+ if m_add is not None:
+ tensor[:, d[0]:d[1]] += m_add[:, d[2]:d[2] + 1]
+ return tensor
+
+
+class SiLUActivation(nn.Module):
+ def __init__(self):
+ super().__init__()
+ self.gate_fn = nn.SiLU()
+
+ def forward(self, x: Tensor) -> Tensor:
+ x1, x2 = x.chunk(2, dim=-1)
+ return self.gate_fn(x1) * x2
+
+
+class DoubleStreamBlock(nn.Module):
+ def __init__(self, hidden_size: int, num_heads: int, mlp_ratio: float, qkv_bias: bool = False, modulation=True, mlp_silu_act=False, proj_bias=True, yak_mlp=False, dtype=None, device=None, operations=None):
+ super().__init__()
+
+ mlp_hidden_dim = int(hidden_size * mlp_ratio)
+ self.num_heads = num_heads
+ self.hidden_size = hidden_size
+ self.modulation = modulation
+
+ if self.modulation:
+ self.img_mod = Modulation(hidden_size, double=True, dtype=dtype, device=device, operations=operations)
+
+ self.img_norm1 = operations.LayerNorm(hidden_size, elementwise_affine=False, eps=1e-6, dtype=dtype, device=device)
+ self.img_attn = SelfAttention(dim=hidden_size, num_heads=num_heads, qkv_bias=qkv_bias, proj_bias=proj_bias, dtype=dtype, device=device, operations=operations)
+
+ self.img_norm2 = operations.LayerNorm(hidden_size, elementwise_affine=False, eps=1e-6, dtype=dtype, device=device)
+
+ self.img_mlp = build_mlp(hidden_size, mlp_hidden_dim, mlp_silu_act=mlp_silu_act, yak_mlp=yak_mlp, dtype=dtype, device=device, operations=operations)
+
+ if self.modulation:
+ self.txt_mod = Modulation(hidden_size, double=True, dtype=dtype, device=device, operations=operations)
+
+ self.txt_norm1 = operations.LayerNorm(hidden_size, elementwise_affine=False, eps=1e-6, dtype=dtype, device=device)
+ self.txt_attn = SelfAttention(dim=hidden_size, num_heads=num_heads, qkv_bias=qkv_bias, proj_bias=proj_bias, dtype=dtype, device=device, operations=operations)
+
+ self.txt_norm2 = operations.LayerNorm(hidden_size, elementwise_affine=False, eps=1e-6, dtype=dtype, device=device)
+
+ self.txt_mlp = build_mlp(hidden_size, mlp_hidden_dim, mlp_silu_act=mlp_silu_act, yak_mlp=yak_mlp, dtype=dtype, device=device, operations=operations)
+
+ def forward(self, img: Tensor, txt: Tensor, vec: Tensor, pe: Tensor, attn_mask=None, modulation_dims_img=None, modulation_dims_txt=None, transformer_options={}):
+ if self.modulation:
+ img_mod1, img_mod2 = self.img_mod(vec)
+ txt_mod1, txt_mod2 = self.txt_mod(vec)
+ else:
+ (img_mod1, img_mod2), (txt_mod1, txt_mod2) = vec
+
+ transformer_patches = transformer_options.get("patches", {})
+ extra_options = transformer_options.copy()
+
+ # prepare image for attention
+ img_modulated = self.img_norm1(img)
+ img_modulated = apply_mod(img_modulated, (1 + img_mod1.scale), img_mod1.shift, modulation_dims_img)
+ img_qkv = self.img_attn.qkv(img_modulated)
+ del img_modulated
+ img_q, img_k, img_v = img_qkv.view(img_qkv.shape[0], img_qkv.shape[1], 3, self.num_heads, -1).permute(2, 0, 3, 1, 4)
+ del img_qkv
+ img_q, img_k = self.img_attn.norm(img_q, img_k, img_v)
+
+ # prepare txt for attention
+ txt_modulated = self.txt_norm1(txt)
+ txt_modulated = apply_mod(txt_modulated, (1 + txt_mod1.scale), txt_mod1.shift, modulation_dims_txt)
+ txt_qkv = self.txt_attn.qkv(txt_modulated)
+ del txt_modulated
+ txt_q, txt_k, txt_v = txt_qkv.view(txt_qkv.shape[0], txt_qkv.shape[1], 3, self.num_heads, -1).permute(2, 0, 3, 1, 4)
+ del txt_qkv
+ txt_q, txt_k = self.txt_attn.norm(txt_q, txt_k, txt_v)
+
+ q = torch.cat((txt_q, img_q), dim=2)
+ del txt_q, img_q
+ k = torch.cat((txt_k, img_k), dim=2)
+ del txt_k, img_k
+ v = torch.cat((txt_v, img_v), dim=2)
+ del txt_v, img_v
+
+ extra_options["img_slice"] = [txt.shape[1], q.shape[2]]
+ if "attn1_patch" in transformer_patches:
+ patch = transformer_patches["attn1_patch"]
+ for p in patch:
+ out = p(q, k, v, pe=pe, attn_mask=attn_mask, extra_options=extra_options)
+ q, k, v, pe, attn_mask = out.get("q", q), out.get("k", k), out.get("v", v), out.get("pe", pe), out.get("attn_mask", attn_mask)
+
+ # run actual attention
+ attn = attention(q, k, v, pe=pe, mask=attn_mask, transformer_options=transformer_options)
+ del q, k, v
+
+ if "attn1_output_patch" in transformer_patches:
+ patch = transformer_patches["attn1_output_patch"]
+ for p in patch:
+ attn = p(attn, extra_options)
+
+ txt_attn, img_attn = attn[:, : txt.shape[1]], attn[:, txt.shape[1]:]
+
+ # calculate the img bloks
+ img += apply_mod(self.img_attn.proj(img_attn), img_mod1.gate, None, modulation_dims_img)
+ del img_attn
+ img += apply_mod(self.img_mlp(apply_mod(self.img_norm2(img), (1 + img_mod2.scale), img_mod2.shift, modulation_dims_img)), img_mod2.gate, None, modulation_dims_img)
+
+ # calculate the txt bloks
+ txt += apply_mod(self.txt_attn.proj(txt_attn), txt_mod1.gate, None, modulation_dims_txt)
+ del txt_attn
+ txt += apply_mod(self.txt_mlp(apply_mod(self.txt_norm2(txt), (1 + txt_mod2.scale), txt_mod2.shift, modulation_dims_txt)), txt_mod2.gate, None, modulation_dims_txt)
+
+ if txt.dtype == torch.float16:
+ txt = torch.nan_to_num(txt, nan=0.0, posinf=65504, neginf=-65504)
+
+ return img, txt
+
+
+class SingleStreamBlock(nn.Module):
+ """
+ A DiT block with parallel linear layers as described in
+ https://arxiv.org/abs/2302.05442 and adapted modulation interface.
+ """
+
+ def __init__(
+ self,
+ hidden_size: int,
+ num_heads: int,
+ mlp_ratio: float = 4.0,
+ qk_scale: float = None,
+ modulation=True,
+ mlp_silu_act=False,
+ bias=True,
+ yak_mlp=False,
+ dtype=None,
+ device=None,
+ operations=None
+ ):
+ super().__init__()
+ self.hidden_dim = hidden_size
+ self.num_heads = num_heads
+ head_dim = hidden_size // num_heads
+ self.scale = qk_scale or head_dim**-0.5
+
+ self.mlp_hidden_dim = int(hidden_size * mlp_ratio)
+
+ self.mlp_hidden_dim_first = self.mlp_hidden_dim
+ self.yak_mlp = yak_mlp
+ if mlp_silu_act:
+ self.mlp_hidden_dim_first = int(hidden_size * mlp_ratio * 2)
+ self.mlp_act = SiLUActivation()
+ else:
+ self.mlp_act = nn.GELU(approximate="tanh")
+
+ if self.yak_mlp:
+ self.mlp_hidden_dim_first *= 2
+ self.mlp_act = nn.SiLU()
+
+ # qkv and mlp_in
+ self.linear1 = operations.Linear(hidden_size, hidden_size * 3 + self.mlp_hidden_dim_first, bias=bias, dtype=dtype, device=device)
+ # proj and mlp_out
+ self.linear2 = operations.Linear(hidden_size + self.mlp_hidden_dim, hidden_size, bias=bias, dtype=dtype, device=device)
+
+ self.norm = QKNorm(head_dim, dtype=dtype, device=device, operations=operations)
+
+ self.hidden_size = hidden_size
+ self.pre_norm = operations.LayerNorm(hidden_size, elementwise_affine=False, eps=1e-6, dtype=dtype, device=device)
+
+ if modulation:
+ self.modulation = Modulation(hidden_size, double=False, dtype=dtype, device=device, operations=operations)
+ else:
+ self.modulation = None
+
+ def forward(self, x: Tensor, vec: Tensor, pe: Tensor, attn_mask=None, modulation_dims=None, transformer_options={}) -> Tensor:
+ if self.modulation:
+ mod, _ = self.modulation(vec)
+ else:
+ mod = vec
+
+ transformer_patches = transformer_options.get("patches", {})
+ extra_options = transformer_options.copy()
+
+ qkv, mlp = torch.split(self.linear1(apply_mod(self.pre_norm(x), (1 + mod.scale), mod.shift, modulation_dims)), [3 * self.hidden_size, self.mlp_hidden_dim_first], dim=-1)
+
+ q, k, v = qkv.view(qkv.shape[0], qkv.shape[1], 3, self.num_heads, -1).permute(2, 0, 3, 1, 4)
+ del qkv
+ q, k = self.norm(q, k, v)
+
+ if "attn1_patch" in transformer_patches:
+ patch = transformer_patches["attn1_patch"]
+ for p in patch:
+ out = p(q, k, v, pe=pe, attn_mask=attn_mask, extra_options=extra_options)
+ q, k, v, pe, attn_mask = out.get("q", q), out.get("k", k), out.get("v", v), out.get("pe", pe), out.get("attn_mask", attn_mask)
+
+ # compute attention
+ attn = attention(q, k, v, pe=pe, mask=attn_mask, transformer_options=transformer_options)
+ del q, k, v
+
+ if "attn1_output_patch" in transformer_patches:
+ patch = transformer_patches["attn1_output_patch"]
+ for p in patch:
+ attn = p(attn, extra_options)
+
+ # compute activation in mlp stream, cat again and run second linear layer
+ if self.yak_mlp:
+ mlp = self.mlp_act(mlp[..., self.mlp_hidden_dim_first // 2:]) * mlp[..., :self.mlp_hidden_dim_first // 2]
+ else:
+ mlp = self.mlp_act(mlp)
+ output = self.linear2(torch.cat((attn, mlp), 2))
+ x += apply_mod(output, mod.gate, None, modulation_dims)
+ if x.dtype == torch.float16:
+ x = torch.nan_to_num(x, nan=0.0, posinf=65504, neginf=-65504)
+ return x
+
+
+class LastLayer(nn.Module):
+ def __init__(self, hidden_size: int, patch_size: int, out_channels: int, bias=True, dtype=None, device=None, operations=None):
+ super().__init__()
+ self.norm_final = operations.LayerNorm(hidden_size, elementwise_affine=False, eps=1e-6, dtype=dtype, device=device)
+ self.linear = operations.Linear(hidden_size, patch_size * patch_size * out_channels, bias=bias, dtype=dtype, device=device)
+ self.adaLN_modulation = nn.Sequential(nn.SiLU(), operations.Linear(hidden_size, 2 * hidden_size, bias=bias, dtype=dtype, device=device))
+
+ def forward(self, x: Tensor, vec: Tensor, modulation_dims=None) -> Tensor:
+ if vec.ndim == 2:
+ vec = vec[:, None, :]
+
+ shift, scale = self.adaLN_modulation(vec).chunk(2, dim=-1)
+ x = apply_mod(self.norm_final(x), (1 + scale), shift, modulation_dims)
+ x = self.linear(x)
+ return x
diff --git a/ComfyUI/comfy/ldm/flux/math.py b/ComfyUI/comfy/ldm/flux/math.py
new file mode 100644
index 0000000000000000000000000000000000000000..891dea7dd0f8f3df19390a338a3a63d9c7c16ca6
--- /dev/null
+++ b/ComfyUI/comfy/ldm/flux/math.py
@@ -0,0 +1,58 @@
+import torch
+from einops import rearrange
+from torch import Tensor
+
+from comfy.ldm.modules.attention import optimized_attention
+import comfy.model_management
+import comfy.quant_ops
+
+
+def attention(q: Tensor, k: Tensor, v: Tensor, pe: Tensor, mask=None, transformer_options={}) -> Tensor:
+ if pe is not None:
+ q, k = apply_rope(q, k, pe)
+ heads = q.shape[1]
+ x = optimized_attention(q, k, v, heads, skip_reshape=True, mask=mask, transformer_options=transformer_options)
+ return x
+
+def rope(pos: Tensor, dim: int, theta: int) -> Tensor:
+ assert dim % 2 == 0
+ if not comfy.model_management.supports_fp64(pos.device):
+ device = torch.device("cpu")
+ else:
+ device = pos.device
+
+ scale = torch.linspace(0, (dim - 2) / dim, steps=dim//2, dtype=torch.float64, device=device)
+ omega = 1.0 / (theta**scale)
+ out = torch.einsum("...n,d->...nd", pos.to(dtype=torch.float32, device=device), omega)
+ out = torch.stack([torch.cos(out), -torch.sin(out), torch.sin(out), torch.cos(out)], dim=-1)
+ out = rearrange(out, "b n d (i j) -> b n d i j", i=2, j=2)
+ return out.to(dtype=torch.float32, device=pos.device)
+
+
+def _apply_rope1(x: Tensor, freqs_cis: Tensor):
+ x_ = x.to(dtype=freqs_cis.dtype).reshape(*x.shape[:-1], -1, 1, 2)
+ if x_.shape[2] != 1 and freqs_cis.shape[2] != 1 and x_.shape[2] != freqs_cis.shape[2]:
+ freqs_cis = freqs_cis[:, :, :x_.shape[2]]
+
+ x_out = freqs_cis[..., 0] * x_[..., 0]
+ x_out.addcmul_(freqs_cis[..., 1], x_[..., 1])
+
+ return x_out.reshape(*x.shape).type_as(x)
+
+
+def _apply_rope(xq: Tensor, xk: Tensor, freqs_cis: Tensor):
+ return apply_rope1(xq, freqs_cis), apply_rope1(xk, freqs_cis)
+
+
+def apply_rope(xq, xk, freqs_cis):
+ if comfy.model_management.in_training:
+ return _apply_rope(xq, xk, freqs_cis)
+ else:
+ return comfy.quant_ops.ck.apply_rope(xq, xk, freqs_cis)
+
+
+def apply_rope1(x, freqs_cis):
+ if comfy.model_management.in_training:
+ return _apply_rope1(x, freqs_cis)
+ else:
+ return comfy.quant_ops.ck.apply_rope1(x, freqs_cis)
diff --git a/ComfyUI/comfy/ldm/flux/model.py b/ComfyUI/comfy/ldm/flux/model.py
new file mode 100644
index 0000000000000000000000000000000000000000..2020326c28d3c21a22fa12c37f9ef8d3c6bace5b
--- /dev/null
+++ b/ComfyUI/comfy/ldm/flux/model.py
@@ -0,0 +1,408 @@
+#Original code can be found on: https://github.com/black-forest-labs/flux
+
+from dataclasses import dataclass
+
+import torch
+from torch import Tensor, nn
+from einops import rearrange, repeat
+import comfy.ldm.common_dit
+import comfy.patcher_extension
+
+from .layers import (
+ DoubleStreamBlock,
+ EmbedND,
+ LastLayer,
+ MLPEmbedder,
+ SingleStreamBlock,
+ timestep_embedding,
+ Modulation,
+)
+
+@dataclass
+class FluxParams:
+ in_channels: int
+ out_channels: int
+ vec_in_dim: int
+ context_in_dim: int
+ hidden_size: int
+ mlp_ratio: float
+ num_heads: int
+ depth: int
+ depth_single_blocks: int
+ axes_dim: list
+ theta: int
+ patch_size: int
+ qkv_bias: bool
+ guidance_embed: bool
+ txt_ids_dims: list
+ global_modulation: bool = False
+ mlp_silu_act: bool = False
+ ops_bias: bool = True
+ default_ref_method: str = "offset"
+ ref_index_scale: float = 1.0
+ yak_mlp: bool = False
+ txt_norm: bool = False
+
+
+def invert_slices(slices, length):
+ sorted_slices = sorted(slices)
+ result = []
+ current = 0
+
+ for start, end in sorted_slices:
+ if current < start:
+ result.append((current, start))
+ current = max(current, end)
+
+ if current < length:
+ result.append((current, length))
+
+ return result
+
+
+class Flux(nn.Module):
+ """
+ Transformer model for flow matching on sequences.
+ """
+
+ def __init__(self, image_model=None, final_layer=True, dtype=None, device=None, operations=None, **kwargs):
+ super().__init__()
+ self.dtype = dtype
+ params = FluxParams(**kwargs)
+ self.params = params
+ self.patch_size = params.patch_size
+ self.in_channels = params.in_channels * params.patch_size * params.patch_size
+ self.out_channels = params.out_channels * params.patch_size * params.patch_size
+ if params.hidden_size % params.num_heads != 0:
+ raise ValueError(
+ f"Hidden size {params.hidden_size} must be divisible by num_heads {params.num_heads}"
+ )
+ pe_dim = params.hidden_size // params.num_heads
+ if sum(params.axes_dim) != pe_dim:
+ raise ValueError(f"Got {params.axes_dim} but expected positional dim {pe_dim}")
+ self.hidden_size = params.hidden_size
+ self.num_heads = params.num_heads
+ self.pe_embedder = EmbedND(dim=pe_dim, theta=params.theta, axes_dim=params.axes_dim)
+ self.img_in = operations.Linear(self.in_channels, self.hidden_size, bias=params.ops_bias, dtype=dtype, device=device)
+ self.time_in = MLPEmbedder(in_dim=256, hidden_dim=self.hidden_size, bias=params.ops_bias, dtype=dtype, device=device, operations=operations)
+ if params.vec_in_dim is not None:
+ self.vector_in = MLPEmbedder(params.vec_in_dim, self.hidden_size, dtype=dtype, device=device, operations=operations)
+ else:
+ self.vector_in = None
+
+ self.guidance_in = (
+ MLPEmbedder(in_dim=256, hidden_dim=self.hidden_size, bias=params.ops_bias, dtype=dtype, device=device, operations=operations) if params.guidance_embed else nn.Identity()
+ )
+ self.txt_in = operations.Linear(params.context_in_dim, self.hidden_size, bias=params.ops_bias, dtype=dtype, device=device)
+
+ if params.txt_norm:
+ self.txt_norm = operations.RMSNorm(params.context_in_dim, dtype=dtype, device=device)
+ else:
+ self.txt_norm = None
+
+ self.double_blocks = nn.ModuleList(
+ [
+ DoubleStreamBlock(
+ self.hidden_size,
+ self.num_heads,
+ mlp_ratio=params.mlp_ratio,
+ qkv_bias=params.qkv_bias,
+ modulation=params.global_modulation is False,
+ mlp_silu_act=params.mlp_silu_act,
+ proj_bias=params.ops_bias,
+ yak_mlp=params.yak_mlp,
+ dtype=dtype, device=device, operations=operations
+ )
+ for _ in range(params.depth)
+ ]
+ )
+
+ self.single_blocks = nn.ModuleList(
+ [
+ SingleStreamBlock(self.hidden_size, self.num_heads, mlp_ratio=params.mlp_ratio, modulation=params.global_modulation is False, mlp_silu_act=params.mlp_silu_act, bias=params.ops_bias, yak_mlp=params.yak_mlp, dtype=dtype, device=device, operations=operations)
+ for _ in range(params.depth_single_blocks)
+ ]
+ )
+
+ if final_layer:
+ self.final_layer = LastLayer(self.hidden_size, 1, self.out_channels, bias=params.ops_bias, dtype=dtype, device=device, operations=operations)
+
+ if params.global_modulation:
+ self.double_stream_modulation_img = Modulation(
+ self.hidden_size,
+ double=True,
+ bias=False,
+ dtype=dtype, device=device, operations=operations
+ )
+ self.double_stream_modulation_txt = Modulation(
+ self.hidden_size,
+ double=True,
+ bias=False,
+ dtype=dtype, device=device, operations=operations
+ )
+ self.single_stream_modulation = Modulation(
+ self.hidden_size, double=False, bias=False, dtype=dtype, device=device, operations=operations
+ )
+
+ def forward_orig(
+ self,
+ img: Tensor,
+ img_ids: Tensor,
+ txt: Tensor,
+ txt_ids: Tensor,
+ timesteps: Tensor,
+ y: Tensor,
+ guidance: Tensor = None,
+ control = None,
+ timestep_zero_index=None,
+ transformer_options={},
+ attn_mask: Tensor = None,
+ ) -> Tensor:
+
+ transformer_options = transformer_options.copy()
+ patches = transformer_options.get("patches", {})
+ patches_replace = transformer_options.get("patches_replace", {})
+ if img.ndim != 3 or txt.ndim != 3:
+ raise ValueError("Input img and txt tensors must have 3 dimensions.")
+
+ # running on sequences img
+ img = self.img_in(img)
+ vec = self.time_in(timestep_embedding(timesteps, 256).to(img.dtype))
+ if self.params.guidance_embed:
+ if guidance is not None:
+ vec = vec + self.guidance_in(timestep_embedding(guidance, 256).to(img.dtype))
+
+ if self.vector_in is not None:
+ if y is None:
+ y = torch.zeros((img.shape[0], self.params.vec_in_dim), device=img.device, dtype=img.dtype)
+ vec = vec + self.vector_in(y[:, :self.params.vec_in_dim])
+
+ if self.txt_norm is not None:
+ txt = self.txt_norm(txt)
+ txt = self.txt_in(txt)
+
+ if "post_input" in patches:
+ for p in patches["post_input"]:
+ out = p({"img": img, "txt": txt, "img_ids": img_ids, "txt_ids": txt_ids, "transformer_options": transformer_options})
+ img = out["img"]
+ txt = out["txt"]
+ img_ids = out["img_ids"]
+ txt_ids = out["txt_ids"]
+
+ if img_ids is not None:
+ ids = torch.cat((txt_ids, img_ids), dim=1)
+ pe = self.pe_embedder(ids)
+ else:
+ pe = None
+
+ vec_orig = vec
+ txt_vec = vec
+ extra_kwargs = {}
+ if timestep_zero_index is not None:
+ modulation_dims = []
+ batch = vec.shape[0] // 2
+ vec_orig = vec_orig.reshape(2, batch, vec.shape[1]).movedim(0, 1)
+ invert = invert_slices(timestep_zero_index, img.shape[1])
+ for s in invert:
+ modulation_dims.append((s[0], s[1], 0))
+ for s in timestep_zero_index:
+ modulation_dims.append((s[0], s[1], 1))
+ extra_kwargs["modulation_dims_img"] = modulation_dims
+ txt_vec = vec[:batch]
+
+ if self.params.global_modulation:
+ vec = (self.double_stream_modulation_img(vec_orig), self.double_stream_modulation_txt(txt_vec))
+
+ blocks_replace = patches_replace.get("dit", {})
+ transformer_options["total_blocks"] = len(self.double_blocks)
+ transformer_options["block_type"] = "double"
+ for i, block in enumerate(self.double_blocks):
+ transformer_options["block_index"] = i
+ if ("double_block", i) in blocks_replace:
+ def block_wrap(args):
+ out = {}
+ out["img"], out["txt"] = block(img=args["img"],
+ txt=args["txt"],
+ vec=args["vec"],
+ pe=args["pe"],
+ attn_mask=args.get("attn_mask"),
+ transformer_options=args.get("transformer_options"),
+ **extra_kwargs)
+ return out
+
+ out = blocks_replace[("double_block", i)]({"img": img,
+ "txt": txt,
+ "vec": vec,
+ "pe": pe,
+ "attn_mask": attn_mask,
+ "transformer_options": transformer_options},
+ {"original_block": block_wrap})
+ txt = out["txt"]
+ img = out["img"]
+ else:
+ img, txt = block(img=img,
+ txt=txt,
+ vec=vec,
+ pe=pe,
+ attn_mask=attn_mask,
+ transformer_options=transformer_options,
+ **extra_kwargs)
+
+ if control is not None: # Controlnet
+ control_i = control.get("input")
+ if i < len(control_i):
+ add = control_i[i]
+ if add is not None:
+ img[:, :add.shape[1]] += add
+
+ if img.dtype == torch.float16:
+ img = torch.nan_to_num(img, nan=0.0, posinf=65504, neginf=-65504)
+
+ img = torch.cat((txt, img), 1)
+
+ if self.params.global_modulation:
+ vec, _ = self.single_stream_modulation(vec_orig)
+
+ extra_kwargs = {}
+ if timestep_zero_index is not None:
+ lambda a: 0 if a == 0 else a + txt.shape[1]
+ modulation_dims_combined = list(map(lambda x: (0 if x[0] == 0 else x[0] + txt.shape[1], x[1] + txt.shape[1], x[2]), modulation_dims))
+ extra_kwargs["modulation_dims"] = modulation_dims_combined
+
+ transformer_options["total_blocks"] = len(self.single_blocks)
+ transformer_options["block_type"] = "single"
+ transformer_options["img_slice"] = [txt.shape[1], img.shape[1]]
+ for i, block in enumerate(self.single_blocks):
+ transformer_options["block_index"] = i
+ if ("single_block", i) in blocks_replace:
+ def block_wrap(args):
+ out = {}
+ out["img"] = block(args["img"],
+ vec=args["vec"],
+ pe=args["pe"],
+ attn_mask=args.get("attn_mask"),
+ transformer_options=args.get("transformer_options"),
+ **extra_kwargs)
+ return out
+
+ out = blocks_replace[("single_block", i)]({"img": img,
+ "vec": vec,
+ "pe": pe,
+ "attn_mask": attn_mask,
+ "transformer_options": transformer_options},
+ {"original_block": block_wrap})
+ img = out["img"]
+ else:
+ img = block(img, vec=vec, pe=pe, attn_mask=attn_mask, transformer_options=transformer_options, **extra_kwargs)
+
+ if control is not None: # Controlnet
+ control_o = control.get("output")
+ if i < len(control_o):
+ add = control_o[i]
+ if add is not None:
+ img[:, txt.shape[1] : txt.shape[1] + add.shape[1], ...] += add
+
+ img = img[:, txt.shape[1] :, ...]
+
+ extra_kwargs = {}
+ if timestep_zero_index is not None:
+ extra_kwargs["modulation_dims"] = modulation_dims
+
+ img = self.final_layer(img, vec_orig, **extra_kwargs) # (N, T, patch_size ** 2 * out_channels)
+ return img
+
+ def process_img(self, x, index=0, h_offset=0, w_offset=0, transformer_options={}):
+ bs, c, h, w = x.shape
+ patch_size = self.patch_size
+ x = comfy.ldm.common_dit.pad_to_patch_size(x, (patch_size, patch_size))
+
+ img = rearrange(x, "b c (h ph) (w pw) -> b (h w) (c ph pw)", ph=patch_size, pw=patch_size)
+ h_len = ((h + (patch_size // 2)) // patch_size)
+ w_len = ((w + (patch_size // 2)) // patch_size)
+
+ h_offset = ((h_offset + (patch_size // 2)) // patch_size)
+ w_offset = ((w_offset + (patch_size // 2)) // patch_size)
+
+ steps_h = h_len
+ steps_w = w_len
+
+ rope_options = transformer_options.get("rope_options", None)
+ if rope_options is not None:
+ h_len = (h_len - 1.0) * rope_options.get("scale_y", 1.0) + 1.0
+ w_len = (w_len - 1.0) * rope_options.get("scale_x", 1.0) + 1.0
+
+ index += rope_options.get("shift_t", 0.0)
+ h_offset += rope_options.get("shift_y", 0.0)
+ w_offset += rope_options.get("shift_x", 0.0)
+
+ img_ids = torch.zeros((steps_h, steps_w, len(self.params.axes_dim)), device=x.device, dtype=torch.float32)
+ img_ids[:, :, 0] = img_ids[:, :, 1] + index
+ img_ids[:, :, 1] = img_ids[:, :, 1] + torch.linspace(h_offset, h_len - 1 + h_offset, steps=steps_h, device=x.device, dtype=torch.float32).unsqueeze(1)
+ img_ids[:, :, 2] = img_ids[:, :, 2] + torch.linspace(w_offset, w_len - 1 + w_offset, steps=steps_w, device=x.device, dtype=torch.float32).unsqueeze(0)
+ return img, repeat(img_ids, "h w c -> b (h w) c", b=bs)
+
+ def forward(self, x, timestep, context, y=None, guidance=None, ref_latents=None, control=None, transformer_options={}, **kwargs):
+ return comfy.patcher_extension.WrapperExecutor.new_class_executor(
+ self._forward,
+ self,
+ comfy.patcher_extension.get_all_wrappers(comfy.patcher_extension.WrappersMP.DIFFUSION_MODEL, transformer_options)
+ ).execute(x, timestep, context, y, guidance, ref_latents, control, transformer_options, **kwargs)
+
+ def _forward(self, x, timestep, context, y=None, guidance=None, ref_latents=None, control=None, transformer_options={}, **kwargs):
+ bs, c, h_orig, w_orig = x.shape
+ patch_size = self.patch_size
+
+ h_len = ((h_orig + (patch_size // 2)) // patch_size)
+ w_len = ((w_orig + (patch_size // 2)) // patch_size)
+ img, img_ids = self.process_img(x, transformer_options=transformer_options)
+ img_tokens = img.shape[1]
+ timestep_zero_index = None
+ if ref_latents is not None:
+ ref_num_tokens = []
+ h = 0
+ w = 0
+ index = 0
+ ref_latents_method = kwargs.get("ref_latents_method", self.params.default_ref_method)
+ timestep_zero = ref_latents_method == "index_timestep_zero"
+ for ref in ref_latents:
+ if ref_latents_method in ("index", "index_timestep_zero"):
+ index += self.params.ref_index_scale
+ h_offset = 0
+ w_offset = 0
+ elif ref_latents_method == "uxo":
+ index = 0
+ h_offset = h_len * patch_size + h
+ w_offset = w_len * patch_size + w
+ h += ref.shape[-2]
+ w += ref.shape[-1]
+ else:
+ index = 1
+ h_offset = 0
+ w_offset = 0
+ if ref.shape[-2] + h > ref.shape[-1] + w:
+ w_offset = w
+ else:
+ h_offset = h
+ h = max(h, ref.shape[-2] + h_offset)
+ w = max(w, ref.shape[-1] + w_offset)
+
+ kontext, kontext_ids = self.process_img(ref, index=index, h_offset=h_offset, w_offset=w_offset, transformer_options=transformer_options)
+ img = torch.cat([img, kontext], dim=1)
+ img_ids = torch.cat([img_ids, kontext_ids], dim=1)
+ ref_num_tokens.append(kontext.shape[1])
+ if timestep_zero:
+ if index > 0:
+ timestep = torch.cat([timestep, timestep * 0], dim=0)
+ timestep_zero_index = [[img_tokens, img_ids.shape[1]]]
+ transformer_options = transformer_options.copy()
+ transformer_options["reference_image_num_tokens"] = ref_num_tokens
+
+ txt_ids = torch.zeros((bs, context.shape[1], len(self.params.axes_dim)), device=x.device, dtype=torch.float32)
+
+ if len(self.params.txt_ids_dims) > 0:
+ for i in self.params.txt_ids_dims:
+ txt_ids[:, :, i] = torch.linspace(0, context.shape[1] - 1, steps=context.shape[1], device=x.device, dtype=torch.float32)
+
+ out = self.forward_orig(img, img_ids, context, txt_ids, timestep, y, guidance, control, timestep_zero_index=timestep_zero_index, transformer_options=transformer_options, attn_mask=kwargs.get("attention_mask", None))
+ out = out[:, :img_tokens]
+ return rearrange(out, "b (h w) (c ph pw) -> b c (h ph) (w pw)", h=h_len, w=w_len, ph=self.patch_size, pw=self.patch_size)[:,:,:h_orig,:w_orig]
diff --git a/ComfyUI/comfy/ldm/flux/redux.py b/ComfyUI/comfy/ldm/flux/redux.py
new file mode 100644
index 0000000000000000000000000000000000000000..527e83164ea2fd1bdf7431f3791ebede00895051
--- /dev/null
+++ b/ComfyUI/comfy/ldm/flux/redux.py
@@ -0,0 +1,25 @@
+import torch
+import comfy.ops
+
+ops = comfy.ops.manual_cast
+
+class ReduxImageEncoder(torch.nn.Module):
+ def __init__(
+ self,
+ redux_dim: int = 1152,
+ txt_in_features: int = 4096,
+ device=None,
+ dtype=None,
+ ) -> None:
+ super().__init__()
+
+ self.redux_dim = redux_dim
+ self.device = device
+ self.dtype = dtype
+
+ self.redux_up = ops.Linear(redux_dim, txt_in_features * 3, dtype=dtype)
+ self.redux_down = ops.Linear(txt_in_features * 3, txt_in_features, dtype=dtype)
+
+ def forward(self, sigclip_embeds) -> torch.Tensor:
+ projected_x = self.redux_down(torch.nn.functional.silu(self.redux_up(sigclip_embeds)))
+ return projected_x
diff --git a/ComfyUI/comfy/ldm/genmo/joint_model/__pycache__/asymm_models_joint.cpython-312.pyc b/ComfyUI/comfy/ldm/genmo/joint_model/__pycache__/asymm_models_joint.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..74a65696f14c0d5d6a7d2d284ca3cc6306b91bb4
Binary files /dev/null and b/ComfyUI/comfy/ldm/genmo/joint_model/__pycache__/asymm_models_joint.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/genmo/joint_model/__pycache__/layers.cpython-312.pyc b/ComfyUI/comfy/ldm/genmo/joint_model/__pycache__/layers.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..adffeb8c87697472d198cdeed738f877b0a013b7
Binary files /dev/null and b/ComfyUI/comfy/ldm/genmo/joint_model/__pycache__/layers.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/genmo/joint_model/__pycache__/rope_mixed.cpython-312.pyc b/ComfyUI/comfy/ldm/genmo/joint_model/__pycache__/rope_mixed.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..2611e6b37fa7572254314d48cd4a2c85a95b5adc
Binary files /dev/null and b/ComfyUI/comfy/ldm/genmo/joint_model/__pycache__/rope_mixed.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/genmo/joint_model/__pycache__/temporal_rope.cpython-312.pyc b/ComfyUI/comfy/ldm/genmo/joint_model/__pycache__/temporal_rope.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..a75e6724bfa8e433f4e4dd0328ca22beea2b9fdc
Binary files /dev/null and b/ComfyUI/comfy/ldm/genmo/joint_model/__pycache__/temporal_rope.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/genmo/joint_model/__pycache__/utils.cpython-312.pyc b/ComfyUI/comfy/ldm/genmo/joint_model/__pycache__/utils.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..9e4149225629059ec17900c17b6d5d1d2b7d703b
Binary files /dev/null and b/ComfyUI/comfy/ldm/genmo/joint_model/__pycache__/utils.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/genmo/joint_model/asymm_models_joint.py b/ComfyUI/comfy/ldm/genmo/joint_model/asymm_models_joint.py
new file mode 100644
index 0000000000000000000000000000000000000000..5c1bb4d42330bdc76a6fc415f2283871fd4f730c
--- /dev/null
+++ b/ComfyUI/comfy/ldm/genmo/joint_model/asymm_models_joint.py
@@ -0,0 +1,561 @@
+#original code from https://github.com/genmoai/models under apache 2.0 license
+#adapted to ComfyUI
+
+from typing import Dict, List, Optional, Tuple
+
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+from einops import rearrange
+# from flash_attn import flash_attn_varlen_qkvpacked_func
+from comfy.ldm.modules.attention import optimized_attention
+
+from .layers import (
+ FeedForward,
+ PatchEmbed,
+ TimestepEmbedder,
+)
+
+from .rope_mixed import (
+ compute_mixed_rotation,
+ create_position_matrix,
+)
+from .temporal_rope import apply_rotary_emb_qk_real
+from .utils import (
+ AttentionPool,
+ modulate,
+)
+
+import comfy.ldm.common_dit
+import comfy.ops
+
+
+def modulated_rmsnorm(x, scale, eps=1e-6):
+ # Normalize and modulate
+ x_normed = comfy.ldm.common_dit.rms_norm(x, eps=eps)
+ x_modulated = x_normed * (1 + scale.unsqueeze(1))
+
+ return x_modulated
+
+
+def residual_tanh_gated_rmsnorm(x, x_res, gate, eps=1e-6):
+ # Apply tanh to gate
+ tanh_gate = torch.tanh(gate).unsqueeze(1)
+
+ # Normalize and apply gated scaling
+ x_normed = comfy.ldm.common_dit.rms_norm(x_res, eps=eps) * tanh_gate
+
+ # Apply residual connection
+ output = x + x_normed
+
+ return output
+
+class AsymmetricAttention(nn.Module):
+ def __init__(
+ self,
+ dim_x: int,
+ dim_y: int,
+ num_heads: int = 8,
+ qkv_bias: bool = True,
+ qk_norm: bool = False,
+ attn_drop: float = 0.0,
+ update_y: bool = True,
+ out_bias: bool = True,
+ attend_to_padding: bool = False,
+ softmax_scale: Optional[float] = None,
+ device: Optional[torch.device] = None,
+ dtype=None,
+ operations=None,
+ ):
+ super().__init__()
+ self.dim_x = dim_x
+ self.dim_y = dim_y
+ self.num_heads = num_heads
+ self.head_dim = dim_x // num_heads
+ self.attn_drop = attn_drop
+ self.update_y = update_y
+ self.attend_to_padding = attend_to_padding
+ self.softmax_scale = softmax_scale
+ if dim_x % num_heads != 0:
+ raise ValueError(
+ f"dim_x={dim_x} should be divisible by num_heads={num_heads}"
+ )
+
+ # Input layers.
+ self.qkv_bias = qkv_bias
+ self.qkv_x = operations.Linear(dim_x, 3 * dim_x, bias=qkv_bias, device=device, dtype=dtype)
+ # Project text features to match visual features (dim_y -> dim_x)
+ self.qkv_y = operations.Linear(dim_y, 3 * dim_x, bias=qkv_bias, device=device, dtype=dtype)
+
+ # Query and key normalization for stability.
+ assert qk_norm
+ self.q_norm_x = operations.RMSNorm(self.head_dim, eps=1e-5, device=device, dtype=dtype)
+ self.k_norm_x = operations.RMSNorm(self.head_dim, eps=1e-5, device=device, dtype=dtype)
+ self.q_norm_y = operations.RMSNorm(self.head_dim, eps=1e-5, device=device, dtype=dtype)
+ self.k_norm_y = operations.RMSNorm(self.head_dim, eps=1e-5, device=device, dtype=dtype)
+
+ # Output layers. y features go back down from dim_x -> dim_y.
+ self.proj_x = operations.Linear(dim_x, dim_x, bias=out_bias, device=device, dtype=dtype)
+ self.proj_y = (
+ operations.Linear(dim_x, dim_y, bias=out_bias, device=device, dtype=dtype)
+ if update_y
+ else nn.Identity()
+ )
+
+ def forward(
+ self,
+ x: torch.Tensor, # (B, N, dim_x)
+ y: torch.Tensor, # (B, L, dim_y)
+ scale_x: torch.Tensor, # (B, dim_x), modulation for pre-RMSNorm.
+ scale_y: torch.Tensor, # (B, dim_y), modulation for pre-RMSNorm.
+ crop_y,
+ transformer_options={},
+ **rope_rotation,
+ ) -> Tuple[torch.Tensor, torch.Tensor]:
+ rope_cos = rope_rotation.get("rope_cos")
+ rope_sin = rope_rotation.get("rope_sin")
+ # Pre-norm for visual features
+ x = modulated_rmsnorm(x, scale_x) # (B, M, dim_x) where M = N / cp_group_size
+
+ # Process visual features
+ # qkv_x = self.qkv_x(x) # (B, M, 3 * dim_x)
+ # assert qkv_x.dtype == torch.bfloat16
+ # qkv_x = all_to_all_collect_tokens(
+ # qkv_x, self.num_heads
+ # ) # (3, B, N, local_h, head_dim)
+
+ # Process text features
+ y = modulated_rmsnorm(y, scale_y) # (B, L, dim_y)
+ q_y, k_y, v_y = self.qkv_y(y).view(y.shape[0], y.shape[1], 3, self.num_heads, -1).unbind(2) # (B, N, local_h, head_dim)
+
+ q_y = self.q_norm_y(q_y)
+ k_y = self.k_norm_y(k_y)
+
+ # Split qkv_x into q, k, v
+ q_x, k_x, v_x = self.qkv_x(x).view(x.shape[0], x.shape[1], 3, self.num_heads, -1).unbind(2) # (B, N, local_h, head_dim)
+ q_x = self.q_norm_x(q_x)
+ q_x = apply_rotary_emb_qk_real(q_x, rope_cos, rope_sin)
+ k_x = self.k_norm_x(k_x)
+ k_x = apply_rotary_emb_qk_real(k_x, rope_cos, rope_sin)
+
+ q = torch.cat([q_x, q_y[:, :crop_y]], dim=1).transpose(1, 2)
+ k = torch.cat([k_x, k_y[:, :crop_y]], dim=1).transpose(1, 2)
+ v = torch.cat([v_x, v_y[:, :crop_y]], dim=1).transpose(1, 2)
+
+ xy = optimized_attention(q,
+ k,
+ v, self.num_heads, skip_reshape=True, transformer_options=transformer_options)
+
+ x, y = torch.tensor_split(xy, (q_x.shape[1],), dim=1)
+ x = self.proj_x(x)
+ o = torch.zeros(y.shape[0], q_y.shape[1], y.shape[-1], device=y.device, dtype=y.dtype)
+ o[:, :y.shape[1]] = y
+
+ y = self.proj_y(o)
+ # print("ox", x)
+ # print("oy", y)
+ return x, y
+
+
+class AsymmetricJointBlock(nn.Module):
+ def __init__(
+ self,
+ hidden_size_x: int,
+ hidden_size_y: int,
+ num_heads: int,
+ *,
+ mlp_ratio_x: float = 8.0, # Ratio of hidden size to d_model for MLP for visual tokens.
+ mlp_ratio_y: float = 4.0, # Ratio of hidden size to d_model for MLP for text tokens.
+ update_y: bool = True, # Whether to update text tokens in this block.
+ device: Optional[torch.device] = None,
+ dtype=None,
+ operations=None,
+ **block_kwargs,
+ ):
+ super().__init__()
+ self.update_y = update_y
+ self.hidden_size_x = hidden_size_x
+ self.hidden_size_y = hidden_size_y
+ self.mod_x = operations.Linear(hidden_size_x, 4 * hidden_size_x, device=device, dtype=dtype)
+ if self.update_y:
+ self.mod_y = operations.Linear(hidden_size_x, 4 * hidden_size_y, device=device, dtype=dtype)
+ else:
+ self.mod_y = operations.Linear(hidden_size_x, hidden_size_y, device=device, dtype=dtype)
+
+ # Self-attention:
+ self.attn = AsymmetricAttention(
+ hidden_size_x,
+ hidden_size_y,
+ num_heads=num_heads,
+ update_y=update_y,
+ device=device,
+ dtype=dtype,
+ operations=operations,
+ **block_kwargs,
+ )
+
+ # MLP.
+ mlp_hidden_dim_x = int(hidden_size_x * mlp_ratio_x)
+ assert mlp_hidden_dim_x == int(1536 * 8)
+ self.mlp_x = FeedForward(
+ in_features=hidden_size_x,
+ hidden_size=mlp_hidden_dim_x,
+ multiple_of=256,
+ ffn_dim_multiplier=None,
+ device=device,
+ dtype=dtype,
+ operations=operations,
+ )
+
+ # MLP for text not needed in last block.
+ if self.update_y:
+ mlp_hidden_dim_y = int(hidden_size_y * mlp_ratio_y)
+ self.mlp_y = FeedForward(
+ in_features=hidden_size_y,
+ hidden_size=mlp_hidden_dim_y,
+ multiple_of=256,
+ ffn_dim_multiplier=None,
+ device=device,
+ dtype=dtype,
+ operations=operations,
+ )
+
+ def forward(
+ self,
+ x: torch.Tensor,
+ c: torch.Tensor,
+ y: torch.Tensor,
+ transformer_options={},
+ **attn_kwargs,
+ ):
+ """Forward pass of a block.
+
+ Args:
+ x: (B, N, dim) tensor of visual tokens
+ c: (B, dim) tensor of conditioned features
+ y: (B, L, dim) tensor of text tokens
+ num_frames: Number of frames in the video. N = num_frames * num_spatial_tokens
+
+ Returns:
+ x: (B, N, dim) tensor of visual tokens after block
+ y: (B, L, dim) tensor of text tokens after block
+ """
+ N = x.size(1)
+
+ c = F.silu(c)
+ mod_x = self.mod_x(c)
+ scale_msa_x, gate_msa_x, scale_mlp_x, gate_mlp_x = mod_x.chunk(4, dim=1)
+
+ mod_y = self.mod_y(c)
+ if self.update_y:
+ scale_msa_y, gate_msa_y, scale_mlp_y, gate_mlp_y = mod_y.chunk(4, dim=1)
+ else:
+ scale_msa_y = mod_y
+
+ # Self-attention block.
+ x_attn, y_attn = self.attn(
+ x,
+ y,
+ scale_x=scale_msa_x,
+ scale_y=scale_msa_y,
+ transformer_options=transformer_options,
+ **attn_kwargs,
+ )
+
+ assert x_attn.size(1) == N
+ x = residual_tanh_gated_rmsnorm(x, x_attn, gate_msa_x)
+ if self.update_y:
+ y = residual_tanh_gated_rmsnorm(y, y_attn, gate_msa_y)
+
+ # MLP block.
+ x = self.ff_block_x(x, scale_mlp_x, gate_mlp_x)
+ if self.update_y:
+ y = self.ff_block_y(y, scale_mlp_y, gate_mlp_y)
+
+ return x, y
+
+ def ff_block_x(self, x, scale_x, gate_x):
+ x_mod = modulated_rmsnorm(x, scale_x)
+ x_res = self.mlp_x(x_mod)
+ x = residual_tanh_gated_rmsnorm(x, x_res, gate_x) # Sandwich norm
+ return x
+
+ def ff_block_y(self, y, scale_y, gate_y):
+ y_mod = modulated_rmsnorm(y, scale_y)
+ y_res = self.mlp_y(y_mod)
+ y = residual_tanh_gated_rmsnorm(y, y_res, gate_y) # Sandwich norm
+ return y
+
+
+class FinalLayer(nn.Module):
+ """
+ The final layer of DiT.
+ """
+
+ def __init__(
+ self,
+ hidden_size,
+ patch_size,
+ out_channels,
+ device: Optional[torch.device] = None,
+ dtype=None,
+ operations=None,
+ ):
+ super().__init__()
+ self.norm_final = operations.LayerNorm(
+ hidden_size, elementwise_affine=False, eps=1e-6, device=device, dtype=dtype
+ )
+ self.mod = operations.Linear(hidden_size, 2 * hidden_size, device=device, dtype=dtype)
+ self.linear = operations.Linear(
+ hidden_size, patch_size * patch_size * out_channels, device=device, dtype=dtype
+ )
+
+ def forward(self, x, c):
+ c = F.silu(c)
+ shift, scale = self.mod(c).chunk(2, dim=1)
+ x = modulate(self.norm_final(x), shift, scale)
+ x = self.linear(x)
+ return x
+
+
+class AsymmDiTJoint(nn.Module):
+ """
+ Diffusion model with a Transformer backbone.
+
+ Ingests text embeddings instead of a label.
+ """
+
+ def __init__(
+ self,
+ *,
+ patch_size=2,
+ in_channels=4,
+ hidden_size_x=1152,
+ hidden_size_y=1152,
+ depth=48,
+ num_heads=16,
+ mlp_ratio_x=8.0,
+ mlp_ratio_y=4.0,
+ use_t5: bool = False,
+ t5_feat_dim: int = 4096,
+ t5_token_length: int = 256,
+ learn_sigma=True,
+ patch_embed_bias: bool = True,
+ timestep_mlp_bias: bool = True,
+ attend_to_padding: bool = False,
+ timestep_scale: Optional[float] = None,
+ use_extended_posenc: bool = False,
+ posenc_preserve_area: bool = False,
+ rope_theta: float = 10000.0,
+ image_model=None,
+ device: Optional[torch.device] = None,
+ dtype=None,
+ operations=None,
+ **block_kwargs,
+ ):
+ super().__init__()
+
+ self.dtype = dtype
+ self.learn_sigma = learn_sigma
+ self.in_channels = in_channels
+ self.out_channels = in_channels * 2 if learn_sigma else in_channels
+ self.patch_size = patch_size
+ self.num_heads = num_heads
+ self.hidden_size_x = hidden_size_x
+ self.hidden_size_y = hidden_size_y
+ self.head_dim = (
+ hidden_size_x // num_heads
+ ) # Head dimension and count is determined by visual.
+ self.attend_to_padding = attend_to_padding
+ self.use_extended_posenc = use_extended_posenc
+ self.posenc_preserve_area = posenc_preserve_area
+ self.use_t5 = use_t5
+ self.t5_token_length = t5_token_length
+ self.t5_feat_dim = t5_feat_dim
+ self.rope_theta = (
+ rope_theta # Scaling factor for frequency computation for temporal RoPE.
+ )
+
+ self.x_embedder = PatchEmbed(
+ patch_size=patch_size,
+ in_chans=in_channels,
+ embed_dim=hidden_size_x,
+ bias=patch_embed_bias,
+ dtype=dtype,
+ device=device,
+ operations=operations
+ )
+ # Conditionings
+ # Timestep
+ self.t_embedder = TimestepEmbedder(
+ hidden_size_x, bias=timestep_mlp_bias, timestep_scale=timestep_scale, dtype=dtype, device=device, operations=operations
+ )
+
+ if self.use_t5:
+ # Caption Pooling (T5)
+ self.t5_y_embedder = AttentionPool(
+ t5_feat_dim, num_heads=8, output_dim=hidden_size_x, dtype=dtype, device=device, operations=operations
+ )
+
+ # Dense Embedding Projection (T5)
+ self.t5_yproj = operations.Linear(
+ t5_feat_dim, hidden_size_y, bias=True, dtype=dtype, device=device
+ )
+
+ # Initialize pos_frequencies as an empty parameter.
+ self.pos_frequencies = nn.Parameter(
+ torch.empty(3, self.num_heads, self.head_dim // 2, dtype=dtype, device=device)
+ )
+
+ assert not self.attend_to_padding
+
+ # for depth 48:
+ # b = 0: AsymmetricJointBlock, update_y=True
+ # b = 1: AsymmetricJointBlock, update_y=True
+ # ...
+ # b = 46: AsymmetricJointBlock, update_y=True
+ # b = 47: AsymmetricJointBlock, update_y=False. No need to update text features.
+ blocks = []
+ for b in range(depth):
+ # Joint multi-modal block
+ update_y = b < depth - 1
+ block = AsymmetricJointBlock(
+ hidden_size_x,
+ hidden_size_y,
+ num_heads,
+ mlp_ratio_x=mlp_ratio_x,
+ mlp_ratio_y=mlp_ratio_y,
+ update_y=update_y,
+ attend_to_padding=attend_to_padding,
+ device=device,
+ dtype=dtype,
+ operations=operations,
+ **block_kwargs,
+ )
+
+ blocks.append(block)
+ self.blocks = nn.ModuleList(blocks)
+
+ self.final_layer = FinalLayer(
+ hidden_size_x, patch_size, self.out_channels, dtype=dtype, device=device, operations=operations
+ )
+
+ def embed_x(self, x: torch.Tensor) -> torch.Tensor:
+ """
+ Args:
+ x: (B, C=12, T, H, W) tensor of visual tokens
+
+ Returns:
+ x: (B, C=3072, N) tensor of visual tokens with positional embedding.
+ """
+ return self.x_embedder(x) # Convert BcTHW to BCN
+
+ def prepare(
+ self,
+ x: torch.Tensor,
+ sigma: torch.Tensor,
+ t5_feat: torch.Tensor,
+ t5_mask: torch.Tensor,
+ ):
+ """Prepare input and conditioning embeddings."""
+ # Visual patch embeddings with positional encoding.
+ T, H, W = x.shape[-3:]
+ pH, pW = H // self.patch_size, W // self.patch_size
+ x = self.embed_x(x) # (B, N, D), where N = T * H * W / patch_size ** 2
+ assert x.ndim == 3
+
+ pH, pW = H // self.patch_size, W // self.patch_size
+ N = T * pH * pW
+ assert x.size(1) == N
+ pos = create_position_matrix(
+ T, pH=pH, pW=pW, device=x.device, dtype=torch.float32
+ ) # (N, 3)
+ rope_cos, rope_sin = compute_mixed_rotation(
+ freqs=comfy.ops.cast_to(self.pos_frequencies, dtype=x.dtype, device=x.device), pos=pos
+ ) # Each are (N, num_heads, dim // 2)
+
+ c_t = self.t_embedder(1 - sigma, out_dtype=x.dtype) # (B, D)
+
+ t5_y_pool = self.t5_y_embedder(t5_feat, t5_mask) # (B, D)
+
+ c = c_t + t5_y_pool
+
+ y_feat = self.t5_yproj(t5_feat) # (B, L, t5_feat_dim) --> (B, L, D)
+
+ return x, c, y_feat, rope_cos, rope_sin
+
+ def forward(
+ self,
+ x: torch.Tensor,
+ timestep: torch.Tensor,
+ context: List[torch.Tensor],
+ attention_mask: List[torch.Tensor],
+ num_tokens=256,
+ packed_indices: Dict[str, torch.Tensor] = None,
+ rope_cos: torch.Tensor = None,
+ rope_sin: torch.Tensor = None,
+ control=None, transformer_options={}, **kwargs
+ ):
+ patches_replace = transformer_options.get("patches_replace", {})
+ y_feat = context
+ y_mask = attention_mask
+ sigma = timestep
+ """Forward pass of DiT.
+
+ Args:
+ x: (B, C, T, H, W) tensor of spatial inputs (images or latent representations of images)
+ sigma: (B,) tensor of noise standard deviations
+ y_feat: List((B, L, y_feat_dim) tensor of caption token features. For SDXL text encoders: L=77, y_feat_dim=2048)
+ y_mask: List((B, L) boolean tensor indicating which tokens are not padding)
+ packed_indices: Dict with keys for Flash Attention. Result of compute_packed_indices.
+ """
+ B, _, T, H, W = x.shape
+
+ x, c, y_feat, rope_cos, rope_sin = self.prepare(
+ x, sigma, y_feat, y_mask
+ )
+ del y_mask
+
+ blocks_replace = patches_replace.get("dit", {})
+ for i, block in enumerate(self.blocks):
+ if ("double_block", i) in blocks_replace:
+ def block_wrap(args):
+ out = {}
+ out["img"], out["txt"] = block(
+ args["img"],
+ args["vec"],
+ args["txt"],
+ rope_cos=args["rope_cos"],
+ rope_sin=args["rope_sin"],
+ crop_y=args["num_tokens"],
+ transformer_options=args["transformer_options"]
+ )
+ return out
+ out = blocks_replace[("double_block", i)]({"img": x, "txt": y_feat, "vec": c, "rope_cos": rope_cos, "rope_sin": rope_sin, "num_tokens": num_tokens, "transformer_options": transformer_options}, {"original_block": block_wrap})
+ y_feat = out["txt"]
+ x = out["img"]
+ else:
+ x, y_feat = block(
+ x,
+ c,
+ y_feat,
+ rope_cos=rope_cos,
+ rope_sin=rope_sin,
+ crop_y=num_tokens,
+ transformer_options=transformer_options,
+ ) # (B, M, D), (B, L, D)
+ del y_feat # Final layers don't use dense text features.
+
+ x = self.final_layer(x, c) # (B, M, patch_size ** 2 * out_channels)
+ x = rearrange(
+ x,
+ "B (T hp wp) (p1 p2 c) -> B c T (hp p1) (wp p2)",
+ T=T,
+ hp=H // self.patch_size,
+ wp=W // self.patch_size,
+ p1=self.patch_size,
+ p2=self.patch_size,
+ c=self.out_channels,
+ )
+
+ return -x
diff --git a/ComfyUI/comfy/ldm/genmo/joint_model/layers.py b/ComfyUI/comfy/ldm/genmo/joint_model/layers.py
new file mode 100644
index 0000000000000000000000000000000000000000..e310bd717833b29e3730894370a55cd49802de93
--- /dev/null
+++ b/ComfyUI/comfy/ldm/genmo/joint_model/layers.py
@@ -0,0 +1,153 @@
+#original code from https://github.com/genmoai/models under apache 2.0 license
+#adapted to ComfyUI
+
+import collections.abc
+import math
+from itertools import repeat
+from typing import Callable, Optional
+
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+from einops import rearrange
+import comfy.ldm.common_dit
+
+
+# From PyTorch internals
+def _ntuple(n):
+ def parse(x):
+ if isinstance(x, collections.abc.Iterable) and not isinstance(x, str):
+ return tuple(x)
+ return tuple(repeat(x, n))
+
+ return parse
+
+
+to_2tuple = _ntuple(2)
+
+
+class TimestepEmbedder(nn.Module):
+ def __init__(
+ self,
+ hidden_size: int,
+ frequency_embedding_size: int = 256,
+ *,
+ bias: bool = True,
+ timestep_scale: Optional[float] = None,
+ dtype=None,
+ device=None,
+ operations=None,
+ ):
+ super().__init__()
+ self.mlp = nn.Sequential(
+ operations.Linear(frequency_embedding_size, hidden_size, bias=bias, dtype=dtype, device=device),
+ nn.SiLU(),
+ operations.Linear(hidden_size, hidden_size, bias=bias, dtype=dtype, device=device),
+ )
+ self.frequency_embedding_size = frequency_embedding_size
+ self.timestep_scale = timestep_scale
+
+ @staticmethod
+ def timestep_embedding(t, dim, max_period=10000):
+ half = dim // 2
+ freqs = torch.arange(start=0, end=half, dtype=torch.float32, device=t.device)
+ freqs.mul_(-math.log(max_period) / half).exp_()
+ args = t[:, None].float() * freqs[None]
+ embedding = torch.cat([torch.cos(args), torch.sin(args)], dim=-1)
+ if dim % 2:
+ embedding = torch.cat(
+ [embedding, torch.zeros_like(embedding[:, :1])], dim=-1
+ )
+ return embedding
+
+ def forward(self, t, out_dtype):
+ if self.timestep_scale is not None:
+ t = t * self.timestep_scale
+ t_freq = self.timestep_embedding(t, self.frequency_embedding_size).to(dtype=out_dtype)
+ t_emb = self.mlp(t_freq)
+ return t_emb
+
+
+class FeedForward(nn.Module):
+ def __init__(
+ self,
+ in_features: int,
+ hidden_size: int,
+ multiple_of: int,
+ ffn_dim_multiplier: Optional[float],
+ device: Optional[torch.device] = None,
+ dtype=None,
+ operations=None,
+ ):
+ super().__init__()
+ # keep parameter count and computation constant compared to standard FFN
+ hidden_size = int(2 * hidden_size / 3)
+ # custom dim factor multiplier
+ if ffn_dim_multiplier is not None:
+ hidden_size = int(ffn_dim_multiplier * hidden_size)
+ hidden_size = multiple_of * ((hidden_size + multiple_of - 1) // multiple_of)
+
+ self.hidden_dim = hidden_size
+ self.w1 = operations.Linear(in_features, 2 * hidden_size, bias=False, device=device, dtype=dtype)
+ self.w2 = operations.Linear(hidden_size, in_features, bias=False, device=device, dtype=dtype)
+
+ def forward(self, x):
+ x, gate = self.w1(x).chunk(2, dim=-1)
+ x = self.w2(F.silu(x) * gate)
+ return x
+
+
+class PatchEmbed(nn.Module):
+ def __init__(
+ self,
+ patch_size: int = 16,
+ in_chans: int = 3,
+ embed_dim: int = 768,
+ norm_layer: Optional[Callable] = None,
+ flatten: bool = True,
+ bias: bool = True,
+ dynamic_img_pad: bool = False,
+ dtype=None,
+ device=None,
+ operations=None,
+ ):
+ super().__init__()
+ self.patch_size = to_2tuple(patch_size)
+ self.flatten = flatten
+ self.dynamic_img_pad = dynamic_img_pad
+
+ self.proj = operations.Conv2d(
+ in_chans,
+ embed_dim,
+ kernel_size=patch_size,
+ stride=patch_size,
+ bias=bias,
+ device=device,
+ dtype=dtype,
+ )
+ assert norm_layer is None
+ self.norm = (
+ norm_layer(embed_dim, device=device) if norm_layer else nn.Identity()
+ )
+
+ def forward(self, x):
+ B, _C, T, H, W = x.shape
+ if not self.dynamic_img_pad:
+ assert H % self.patch_size[0] == 0, f"Input height ({H}) should be divisible by patch size ({self.patch_size[0]})."
+ assert W % self.patch_size[1] == 0, f"Input width ({W}) should be divisible by patch size ({self.patch_size[1]})."
+ else:
+ pad_h = (self.patch_size[0] - H % self.patch_size[0]) % self.patch_size[0]
+ pad_w = (self.patch_size[1] - W % self.patch_size[1]) % self.patch_size[1]
+ x = F.pad(x, (0, pad_w, 0, pad_h))
+
+ x = rearrange(x, "B C T H W -> (B T) C H W", B=B, T=T)
+ x = comfy.ldm.common_dit.pad_to_patch_size(x, self.patch_size, padding_mode='circular')
+ x = self.proj(x)
+
+ # Flatten temporal and spatial dimensions.
+ if not self.flatten:
+ raise NotImplementedError("Must flatten output.")
+ x = rearrange(x, "(B T) C H W -> B (T H W) C", B=B, T=T)
+
+ x = self.norm(x)
+ return x
diff --git a/ComfyUI/comfy/ldm/genmo/joint_model/rope_mixed.py b/ComfyUI/comfy/ldm/genmo/joint_model/rope_mixed.py
new file mode 100644
index 0000000000000000000000000000000000000000..dee3fa21f5318a610321fc9372553d618462f773
--- /dev/null
+++ b/ComfyUI/comfy/ldm/genmo/joint_model/rope_mixed.py
@@ -0,0 +1,88 @@
+#original code from https://github.com/genmoai/models under apache 2.0 license
+
+# import functools
+import math
+
+import torch
+
+
+def centers(start: float, stop, num, dtype=None, device=None):
+ """linspace through bin centers.
+
+ Args:
+ start (float): Start of the range.
+ stop (float): End of the range.
+ num (int): Number of points.
+ dtype (torch.dtype): Data type of the points.
+ device (torch.device): Device of the points.
+
+ Returns:
+ centers (Tensor): Centers of the bins. Shape: (num,).
+ """
+ edges = torch.linspace(start, stop, num + 1, dtype=dtype, device=device)
+ return (edges[:-1] + edges[1:]) / 2
+
+
+# @functools.lru_cache(maxsize=1)
+def create_position_matrix(
+ T: int,
+ pH: int,
+ pW: int,
+ device: torch.device,
+ dtype: torch.dtype,
+ *,
+ target_area: float = 36864,
+):
+ """
+ Args:
+ T: int - Temporal dimension
+ pH: int - Height dimension after patchify
+ pW: int - Width dimension after patchify
+
+ Returns:
+ pos: [T * pH * pW, 3] - position matrix
+ """
+ # Create 1D tensors for each dimension
+ t = torch.arange(T, dtype=dtype)
+
+ # Positionally interpolate to area 36864.
+ # (3072x3072 frame with 16x16 patches = 192x192 latents).
+ # This automatically scales rope positions when the resolution changes.
+ # We use a large target area so the model is more sensitive
+ # to changes in the learned pos_frequencies matrix.
+ scale = math.sqrt(target_area / (pW * pH))
+ w = centers(-pW * scale / 2, pW * scale / 2, pW)
+ h = centers(-pH * scale / 2, pH * scale / 2, pH)
+
+ # Use meshgrid to create 3D grids
+ grid_t, grid_h, grid_w = torch.meshgrid(t, h, w, indexing="ij")
+
+ # Stack and reshape the grids.
+ pos = torch.stack([grid_t, grid_h, grid_w], dim=-1) # [T, pH, pW, 3]
+ pos = pos.view(-1, 3) # [T * pH * pW, 3]
+ pos = pos.to(dtype=dtype, device=device)
+
+ return pos
+
+
+def compute_mixed_rotation(
+ freqs: torch.Tensor,
+ pos: torch.Tensor,
+):
+ """
+ Project each 3-dim position into per-head, per-head-dim 1D frequencies.
+
+ Args:
+ freqs: [3, num_heads, num_freqs] - learned rotation frequency (for t, row, col) for each head position
+ pos: [N, 3] - position of each token
+ num_heads: int
+
+ Returns:
+ freqs_cos: [N, num_heads, num_freqs] - cosine components
+ freqs_sin: [N, num_heads, num_freqs] - sine components
+ """
+ assert freqs.ndim == 3
+ freqs_sum = torch.einsum("Nd,dhf->Nhf", pos.to(freqs), freqs)
+ freqs_cos = torch.cos(freqs_sum)
+ freqs_sin = torch.sin(freqs_sum)
+ return freqs_cos, freqs_sin
diff --git a/ComfyUI/comfy/ldm/genmo/joint_model/temporal_rope.py b/ComfyUI/comfy/ldm/genmo/joint_model/temporal_rope.py
new file mode 100644
index 0000000000000000000000000000000000000000..88f5d6d26151db0c8ad0a89fcf748c45d4b89bc0
--- /dev/null
+++ b/ComfyUI/comfy/ldm/genmo/joint_model/temporal_rope.py
@@ -0,0 +1,34 @@
+#original code from https://github.com/genmoai/models under apache 2.0 license
+
+# Based on Llama3 Implementation.
+import torch
+
+
+def apply_rotary_emb_qk_real(
+ xqk: torch.Tensor,
+ freqs_cos: torch.Tensor,
+ freqs_sin: torch.Tensor,
+) -> torch.Tensor:
+ """
+ Apply rotary embeddings to input tensors using the given frequency tensor without complex numbers.
+
+ Args:
+ xqk (torch.Tensor): Query and/or Key tensors to apply rotary embeddings. Shape: (B, S, *, num_heads, D)
+ Can be either just query or just key, or both stacked along some batch or * dim.
+ freqs_cos (torch.Tensor): Precomputed cosine frequency tensor.
+ freqs_sin (torch.Tensor): Precomputed sine frequency tensor.
+
+ Returns:
+ torch.Tensor: The input tensor with rotary embeddings applied.
+ """
+ # Split the last dimension into even and odd parts
+ xqk_even = xqk[..., 0::2]
+ xqk_odd = xqk[..., 1::2]
+
+ # Apply rotation
+ cos_part = (xqk_even * freqs_cos - xqk_odd * freqs_sin).type_as(xqk)
+ sin_part = (xqk_even * freqs_sin + xqk_odd * freqs_cos).type_as(xqk)
+
+ # Interleave the results back into the original shape
+ out = torch.stack([cos_part, sin_part], dim=-1).flatten(-2)
+ return out
diff --git a/ComfyUI/comfy/ldm/genmo/joint_model/utils.py b/ComfyUI/comfy/ldm/genmo/joint_model/utils.py
new file mode 100644
index 0000000000000000000000000000000000000000..1b399d5d2128b7f5c7be141c3d8e7047df93b273
--- /dev/null
+++ b/ComfyUI/comfy/ldm/genmo/joint_model/utils.py
@@ -0,0 +1,102 @@
+#original code from https://github.com/genmoai/models under apache 2.0 license
+#adapted to ComfyUI
+
+from typing import Optional
+
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+
+
+def modulate(x, shift, scale):
+ return x * (1 + scale.unsqueeze(1)) + shift.unsqueeze(1)
+
+
+def pool_tokens(x: torch.Tensor, mask: torch.Tensor, *, keepdim=False) -> torch.Tensor:
+ """
+ Pool tokens in x using mask.
+
+ NOTE: We assume x does not require gradients.
+
+ Args:
+ x: (B, L, D) tensor of tokens.
+ mask: (B, L) boolean tensor indicating which tokens are not padding.
+
+ Returns:
+ pooled: (B, D) tensor of pooled tokens.
+ """
+ assert x.size(1) == mask.size(1) # Expected mask to have same length as tokens.
+ assert x.size(0) == mask.size(0) # Expected mask to have same batch size as tokens.
+ mask = mask[:, :, None].to(dtype=x.dtype)
+ mask = mask / mask.sum(dim=1, keepdim=True).clamp(min=1)
+ pooled = (x * mask).sum(dim=1, keepdim=keepdim)
+ return pooled
+
+
+class AttentionPool(nn.Module):
+ def __init__(
+ self,
+ embed_dim: int,
+ num_heads: int,
+ output_dim: int = None,
+ device: Optional[torch.device] = None,
+ dtype=None,
+ operations=None,
+ ):
+ """
+ Args:
+ spatial_dim (int): Number of tokens in sequence length.
+ embed_dim (int): Dimensionality of input tokens.
+ num_heads (int): Number of attention heads.
+ output_dim (int): Dimensionality of output tokens. Defaults to embed_dim.
+ """
+ super().__init__()
+ self.num_heads = num_heads
+ self.to_kv = operations.Linear(embed_dim, 2 * embed_dim, device=device, dtype=dtype)
+ self.to_q = operations.Linear(embed_dim, embed_dim, device=device, dtype=dtype)
+ self.to_out = operations.Linear(embed_dim, output_dim or embed_dim, device=device, dtype=dtype)
+
+ def forward(self, x, mask):
+ """
+ Args:
+ x (torch.Tensor): (B, L, D) tensor of input tokens.
+ mask (torch.Tensor): (B, L) boolean tensor indicating which tokens are not padding.
+
+ NOTE: We assume x does not require gradients.
+
+ Returns:
+ x (torch.Tensor): (B, D) tensor of pooled tokens.
+ """
+ D = x.size(2)
+
+ # Construct attention mask, shape: (B, 1, num_queries=1, num_keys=1+L).
+ attn_mask = mask[:, None, None, :].bool() # (B, 1, 1, L).
+ attn_mask = F.pad(attn_mask, (1, 0), value=True) # (B, 1, 1, 1+L).
+
+ # Average non-padding token features. These will be used as the query.
+ x_pool = pool_tokens(x, mask, keepdim=True) # (B, 1, D)
+
+ # Concat pooled features to input sequence.
+ x = torch.cat([x_pool, x], dim=1) # (B, L+1, D)
+
+ # Compute queries, keys, values. Only the mean token is used to create a query.
+ kv = self.to_kv(x) # (B, L+1, 2 * D)
+ q = self.to_q(x[:, 0]) # (B, D)
+
+ # Extract heads.
+ head_dim = D // self.num_heads
+ kv = kv.unflatten(2, (2, self.num_heads, head_dim)) # (B, 1+L, 2, H, head_dim)
+ kv = kv.transpose(1, 3) # (B, H, 2, 1+L, head_dim)
+ k, v = kv.unbind(2) # (B, H, 1+L, head_dim)
+ q = q.unflatten(1, (self.num_heads, head_dim)) # (B, H, head_dim)
+ q = q.unsqueeze(2) # (B, H, 1, head_dim)
+
+ # Compute attention.
+ x = F.scaled_dot_product_attention(
+ q, k, v, attn_mask=attn_mask, dropout_p=0.0
+ ) # (B, H, 1, head_dim)
+
+ # Concatenate heads and run output.
+ x = x.squeeze(2).flatten(1, 2) # (B, D = H * head_dim)
+ x = self.to_out(x)
+ return x
diff --git a/ComfyUI/comfy/ldm/genmo/vae/__pycache__/model.cpython-312.pyc b/ComfyUI/comfy/ldm/genmo/vae/__pycache__/model.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..2abddac13e0ff9036f226a708ca94d415de23039
Binary files /dev/null and b/ComfyUI/comfy/ldm/genmo/vae/__pycache__/model.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/genmo/vae/model.py b/ComfyUI/comfy/ldm/genmo/vae/model.py
new file mode 100644
index 0000000000000000000000000000000000000000..1bde0c1ed7372be184e634777b9e27b67692b1f4
--- /dev/null
+++ b/ComfyUI/comfy/ldm/genmo/vae/model.py
@@ -0,0 +1,711 @@
+#original code from https://github.com/genmoai/models under apache 2.0 license
+#adapted to ComfyUI
+
+from typing import List, Optional, Tuple, Union
+from functools import partial
+import math
+
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+from einops import rearrange
+
+from comfy.ldm.modules.attention import optimized_attention
+
+import comfy.ops
+ops = comfy.ops.disable_weight_init
+
+# import mochi_preview.dit.joint_model.context_parallel as cp
+# from mochi_preview.vae.cp_conv import cp_pass_frames, gather_all_frames
+
+
+def cast_tuple(t, length=1):
+ return t if isinstance(t, tuple) else ((t,) * length)
+
+
+class GroupNormSpatial(ops.GroupNorm):
+ """
+ GroupNorm applied per-frame.
+ """
+
+ def forward(self, x: torch.Tensor, *, chunk_size: int = 8):
+ B, C, T, H, W = x.shape
+ x = rearrange(x, "B C T H W -> (B T) C H W")
+ # Run group norm in chunks.
+ output = torch.empty_like(x)
+ for b in range(0, B * T, chunk_size):
+ output[b : b + chunk_size] = super().forward(x[b : b + chunk_size])
+ return rearrange(output, "(B T) C H W -> B C T H W", B=B, T=T)
+
+class PConv3d(ops.Conv3d):
+ def __init__(
+ self,
+ in_channels,
+ out_channels,
+ kernel_size: Union[int, Tuple[int, int, int]],
+ stride: Union[int, Tuple[int, int, int]],
+ causal: bool = True,
+ context_parallel: bool = True,
+ **kwargs,
+ ):
+ self.causal = causal
+ self.context_parallel = context_parallel
+ kernel_size = cast_tuple(kernel_size, 3)
+ stride = cast_tuple(stride, 3)
+ height_pad = (kernel_size[1] - 1) // 2
+ width_pad = (kernel_size[2] - 1) // 2
+
+ super().__init__(
+ in_channels=in_channels,
+ out_channels=out_channels,
+ kernel_size=kernel_size,
+ stride=stride,
+ dilation=(1, 1, 1),
+ padding=(0, height_pad, width_pad),
+ **kwargs,
+ )
+
+ def forward(self, x: torch.Tensor):
+ # Compute padding amounts.
+ context_size = self.kernel_size[0] - 1
+ if self.causal:
+ pad_front = context_size
+ pad_back = 0
+ else:
+ pad_front = context_size // 2
+ pad_back = context_size - pad_front
+
+ # Apply padding.
+ assert self.padding_mode == "replicate" # DEBUG
+ mode = "constant" if self.padding_mode == "zeros" else self.padding_mode
+ x = F.pad(x, (0, 0, 0, 0, pad_front, pad_back), mode=mode)
+ return super().forward(x)
+
+
+class Conv1x1(ops.Linear):
+ """*1x1 Conv implemented with a linear layer."""
+
+ def __init__(self, in_features: int, out_features: int, *args, **kwargs):
+ super().__init__(in_features, out_features, *args, **kwargs)
+
+ def forward(self, x: torch.Tensor):
+ """Forward pass.
+
+ Args:
+ x: Input tensor. Shape: [B, C, *] or [B, *, C].
+
+ Returns:
+ x: Output tensor. Shape: [B, C', *] or [B, *, C'].
+ """
+ x = x.movedim(1, -1)
+ x = super().forward(x)
+ x = x.movedim(-1, 1)
+ return x
+
+
+class DepthToSpaceTime(nn.Module):
+ def __init__(
+ self,
+ temporal_expansion: int,
+ spatial_expansion: int,
+ ):
+ super().__init__()
+ self.temporal_expansion = temporal_expansion
+ self.spatial_expansion = spatial_expansion
+
+ # When printed, this module should show the temporal and spatial expansion factors.
+ def extra_repr(self):
+ return f"texp={self.temporal_expansion}, sexp={self.spatial_expansion}"
+
+ def forward(self, x: torch.Tensor):
+ """Forward pass.
+
+ Args:
+ x: Input tensor. Shape: [B, C, T, H, W].
+
+ Returns:
+ x: Rearranged tensor. Shape: [B, C/(st*s*s), T*st, H*s, W*s].
+ """
+ x = rearrange(
+ x,
+ "B (C st sh sw) T H W -> B C (T st) (H sh) (W sw)",
+ st=self.temporal_expansion,
+ sh=self.spatial_expansion,
+ sw=self.spatial_expansion,
+ )
+
+ # cp_rank, _ = cp.get_cp_rank_size()
+ if self.temporal_expansion > 1: # and cp_rank == 0:
+ # Drop the first self.temporal_expansion - 1 frames.
+ # This is because we always want the 3x3x3 conv filter to only apply
+ # to the first frame, and the first frame doesn't need to be repeated.
+ assert all(x.shape)
+ x = x[:, :, self.temporal_expansion - 1 :]
+ assert all(x.shape)
+
+ return x
+
+
+def norm_fn(
+ in_channels: int,
+ affine: bool = True,
+):
+ return GroupNormSpatial(affine=affine, num_groups=32, num_channels=in_channels)
+
+
+class ResBlock(nn.Module):
+ """Residual block that preserves the spatial dimensions."""
+
+ def __init__(
+ self,
+ channels: int,
+ *,
+ affine: bool = True,
+ attn_block: Optional[nn.Module] = None,
+ causal: bool = True,
+ prune_bottleneck: bool = False,
+ padding_mode: str,
+ bias: bool = True,
+ ):
+ super().__init__()
+ self.channels = channels
+
+ assert causal
+ self.stack = nn.Sequential(
+ norm_fn(channels, affine=affine),
+ nn.SiLU(inplace=True),
+ PConv3d(
+ in_channels=channels,
+ out_channels=channels // 2 if prune_bottleneck else channels,
+ kernel_size=(3, 3, 3),
+ stride=(1, 1, 1),
+ padding_mode=padding_mode,
+ bias=bias,
+ causal=causal,
+ ),
+ norm_fn(channels, affine=affine),
+ nn.SiLU(inplace=True),
+ PConv3d(
+ in_channels=channels // 2 if prune_bottleneck else channels,
+ out_channels=channels,
+ kernel_size=(3, 3, 3),
+ stride=(1, 1, 1),
+ padding_mode=padding_mode,
+ bias=bias,
+ causal=causal,
+ ),
+ )
+
+ self.attn_block = attn_block if attn_block else nn.Identity()
+
+ def forward(self, x: torch.Tensor):
+ """Forward pass.
+
+ Args:
+ x: Input tensor. Shape: [B, C, T, H, W].
+ """
+ residual = x
+ x = self.stack(x)
+ x = x + residual
+ del residual
+
+ return self.attn_block(x)
+
+
+class Attention(nn.Module):
+ def __init__(
+ self,
+ dim: int,
+ head_dim: int = 32,
+ qkv_bias: bool = False,
+ out_bias: bool = True,
+ qk_norm: bool = True,
+ ) -> None:
+ super().__init__()
+ self.head_dim = head_dim
+ self.num_heads = dim // head_dim
+ self.qk_norm = qk_norm
+
+ self.qkv = nn.Linear(dim, 3 * dim, bias=qkv_bias)
+ self.out = nn.Linear(dim, dim, bias=out_bias)
+
+ def forward(
+ self,
+ x: torch.Tensor,
+ ) -> torch.Tensor:
+ """Compute temporal self-attention.
+
+ Args:
+ x: Input tensor. Shape: [B, C, T, H, W].
+ chunk_size: Chunk size for large tensors.
+
+ Returns:
+ x: Output tensor. Shape: [B, C, T, H, W].
+ """
+ B, _, T, H, W = x.shape
+
+ if T == 1:
+ # No attention for single frame.
+ x = x.movedim(1, -1) # [B, C, T, H, W] -> [B, T, H, W, C]
+ qkv = self.qkv(x)
+ _, _, x = qkv.chunk(3, dim=-1) # Throw away queries and keys.
+ x = self.out(x)
+ return x.movedim(-1, 1) # [B, T, H, W, C] -> [B, C, T, H, W]
+
+ # 1D temporal attention.
+ x = rearrange(x, "B C t h w -> (B h w) t C")
+ qkv = self.qkv(x)
+
+ # Input: qkv with shape [B, t, 3 * num_heads * head_dim]
+ # Output: x with shape [B, num_heads, t, head_dim]
+ q, k, v = qkv.view(qkv.shape[0], qkv.shape[1], 3, self.num_heads, self.head_dim).transpose(1, 3).unbind(2)
+
+ if self.qk_norm:
+ q = F.normalize(q, p=2, dim=-1)
+ k = F.normalize(k, p=2, dim=-1)
+
+ x = optimized_attention(q, k, v, self.num_heads, skip_reshape=True)
+
+ assert x.size(0) == q.size(0)
+
+ x = self.out(x)
+ x = rearrange(x, "(B h w) t C -> B C t h w", B=B, h=H, w=W)
+ return x
+
+
+class AttentionBlock(nn.Module):
+ def __init__(
+ self,
+ dim: int,
+ **attn_kwargs,
+ ) -> None:
+ super().__init__()
+ self.norm = norm_fn(dim)
+ self.attn = Attention(dim, **attn_kwargs)
+
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
+ return x + self.attn(self.norm(x))
+
+
+class CausalUpsampleBlock(nn.Module):
+ def __init__(
+ self,
+ in_channels: int,
+ out_channels: int,
+ num_res_blocks: int,
+ *,
+ temporal_expansion: int = 2,
+ spatial_expansion: int = 2,
+ **block_kwargs,
+ ):
+ super().__init__()
+
+ blocks = []
+ for _ in range(num_res_blocks):
+ blocks.append(block_fn(in_channels, **block_kwargs))
+ self.blocks = nn.Sequential(*blocks)
+
+ self.temporal_expansion = temporal_expansion
+ self.spatial_expansion = spatial_expansion
+
+ # Change channels in the final convolution layer.
+ self.proj = Conv1x1(
+ in_channels,
+ out_channels * temporal_expansion * (spatial_expansion**2),
+ )
+
+ self.d2st = DepthToSpaceTime(
+ temporal_expansion=temporal_expansion, spatial_expansion=spatial_expansion
+ )
+
+ def forward(self, x):
+ x = self.blocks(x)
+ x = self.proj(x)
+ x = self.d2st(x)
+ return x
+
+
+def block_fn(channels, *, affine: bool = True, has_attention: bool = False, **block_kwargs):
+ attn_block = AttentionBlock(channels) if has_attention else None
+ return ResBlock(channels, affine=affine, attn_block=attn_block, **block_kwargs)
+
+
+class DownsampleBlock(nn.Module):
+ def __init__(
+ self,
+ in_channels: int,
+ out_channels: int,
+ num_res_blocks,
+ *,
+ temporal_reduction=2,
+ spatial_reduction=2,
+ **block_kwargs,
+ ):
+ """
+ Downsample block for the VAE encoder.
+
+ Args:
+ in_channels: Number of input channels.
+ out_channels: Number of output channels.
+ num_res_blocks: Number of residual blocks.
+ temporal_reduction: Temporal reduction factor.
+ spatial_reduction: Spatial reduction factor.
+ """
+ super().__init__()
+ layers = []
+
+ # Change the channel count in the strided convolution.
+ # This lets the ResBlock have uniform channel count,
+ # as in ConvNeXt.
+ assert in_channels != out_channels
+ layers.append(
+ PConv3d(
+ in_channels=in_channels,
+ out_channels=out_channels,
+ kernel_size=(temporal_reduction, spatial_reduction, spatial_reduction),
+ stride=(temporal_reduction, spatial_reduction, spatial_reduction),
+ # First layer in each block always uses replicate padding
+ padding_mode="replicate",
+ bias=block_kwargs["bias"],
+ )
+ )
+
+ for _ in range(num_res_blocks):
+ layers.append(block_fn(out_channels, **block_kwargs))
+
+ self.layers = nn.Sequential(*layers)
+
+ def forward(self, x):
+ return self.layers(x)
+
+
+def add_fourier_features(inputs: torch.Tensor, start=6, stop=8, step=1):
+ num_freqs = (stop - start) // step
+ assert inputs.ndim == 5
+ C = inputs.size(1)
+
+ # Create Base 2 Fourier features.
+ freqs = torch.arange(start, stop, step, dtype=inputs.dtype, device=inputs.device)
+ assert num_freqs == len(freqs)
+ w = torch.pow(2.0, freqs) * (2 * torch.pi) # [num_freqs]
+ C = inputs.shape[1]
+ w = w.repeat(C)[None, :, None, None, None] # [1, C * num_freqs, 1, 1, 1]
+
+ # Interleaved repeat of input channels to match w.
+ h = inputs.repeat_interleave(num_freqs, dim=1) # [B, C * num_freqs, T, H, W]
+ # Scale channels by frequency.
+ h = w * h
+
+ return torch.cat(
+ [
+ inputs,
+ torch.sin(h),
+ torch.cos(h),
+ ],
+ dim=1,
+ )
+
+
+class FourierFeatures(nn.Module):
+ def __init__(self, start: int = 6, stop: int = 8, step: int = 1):
+ super().__init__()
+ self.start = start
+ self.stop = stop
+ self.step = step
+
+ def forward(self, inputs):
+ """Add Fourier features to inputs.
+
+ Args:
+ inputs: Input tensor. Shape: [B, C, T, H, W]
+
+ Returns:
+ h: Output tensor. Shape: [B, (1 + 2 * num_freqs) * C, T, H, W]
+ """
+ return add_fourier_features(inputs, self.start, self.stop, self.step)
+
+
+class Decoder(nn.Module):
+ def __init__(
+ self,
+ *,
+ out_channels: int = 3,
+ latent_dim: int,
+ base_channels: int,
+ channel_multipliers: List[int],
+ num_res_blocks: List[int],
+ temporal_expansions: Optional[List[int]] = None,
+ spatial_expansions: Optional[List[int]] = None,
+ has_attention: List[bool],
+ output_norm: bool = True,
+ nonlinearity: str = "silu",
+ output_nonlinearity: str = "silu",
+ causal: bool = True,
+ **block_kwargs,
+ ):
+ super().__init__()
+ self.input_channels = latent_dim
+ self.base_channels = base_channels
+ self.channel_multipliers = channel_multipliers
+ self.num_res_blocks = num_res_blocks
+ self.output_nonlinearity = output_nonlinearity
+ assert nonlinearity == "silu"
+ assert causal
+
+ ch = [mult * base_channels for mult in channel_multipliers]
+ self.num_up_blocks = len(ch) - 1
+ assert len(num_res_blocks) == self.num_up_blocks + 2
+
+ blocks = []
+
+ first_block = [
+ ops.Conv3d(latent_dim, ch[-1], kernel_size=(1, 1, 1))
+ ] # Input layer.
+ # First set of blocks preserve channel count.
+ for _ in range(num_res_blocks[-1]):
+ first_block.append(
+ block_fn(
+ ch[-1],
+ has_attention=has_attention[-1],
+ causal=causal,
+ **block_kwargs,
+ )
+ )
+ blocks.append(nn.Sequential(*first_block))
+
+ assert len(temporal_expansions) == len(spatial_expansions) == self.num_up_blocks
+ assert len(num_res_blocks) == len(has_attention) == self.num_up_blocks + 2
+
+ upsample_block_fn = CausalUpsampleBlock
+
+ for i in range(self.num_up_blocks):
+ block = upsample_block_fn(
+ ch[-i - 1],
+ ch[-i - 2],
+ num_res_blocks=num_res_blocks[-i - 2],
+ has_attention=has_attention[-i - 2],
+ temporal_expansion=temporal_expansions[-i - 1],
+ spatial_expansion=spatial_expansions[-i - 1],
+ causal=causal,
+ **block_kwargs,
+ )
+ blocks.append(block)
+
+ assert not output_norm
+
+ # Last block. Preserve channel count.
+ last_block = []
+ for _ in range(num_res_blocks[0]):
+ last_block.append(
+ block_fn(
+ ch[0], has_attention=has_attention[0], causal=causal, **block_kwargs
+ )
+ )
+ blocks.append(nn.Sequential(*last_block))
+
+ self.blocks = nn.ModuleList(blocks)
+ self.output_proj = Conv1x1(ch[0], out_channels)
+
+ def forward(self, x):
+ """Forward pass.
+
+ Args:
+ x: Latent tensor. Shape: [B, input_channels, t, h, w]. Scaled [-1, 1].
+
+ Returns:
+ x: Reconstructed video tensor. Shape: [B, C, T, H, W]. Scaled to [-1, 1].
+ T + 1 = (t - 1) * 4.
+ H = h * 16, W = w * 16.
+ """
+ for block in self.blocks:
+ x = block(x)
+
+ if self.output_nonlinearity == "silu":
+ x = F.silu(x, inplace=not self.training)
+ else:
+ assert (
+ not self.output_nonlinearity
+ ) # StyleGAN3 omits the to-RGB nonlinearity.
+
+ return self.output_proj(x).contiguous()
+
+class LatentDistribution:
+ def __init__(self, mean: torch.Tensor, logvar: torch.Tensor):
+ """Initialize latent distribution.
+
+ Args:
+ mean: Mean of the distribution. Shape: [B, C, T, H, W].
+ logvar: Logarithm of variance of the distribution. Shape: [B, C, T, H, W].
+ """
+ assert mean.shape == logvar.shape
+ self.mean = mean
+ self.logvar = logvar
+
+ def sample(self, temperature=1.0, generator: torch.Generator = None, noise=None):
+ if temperature == 0.0:
+ return self.mean
+
+ if noise is None:
+ noise = torch.randn(self.mean.shape, device=self.mean.device, dtype=self.mean.dtype, generator=generator)
+ else:
+ assert noise.device == self.mean.device
+ noise = noise.to(self.mean.dtype)
+
+ if temperature != 1.0:
+ raise NotImplementedError(f"Temperature {temperature} is not supported.")
+
+ # Just Gaussian sample with no scaling of variance.
+ return noise * torch.exp(self.logvar * 0.5) + self.mean
+
+ def mode(self):
+ return self.mean
+
+class Encoder(nn.Module):
+ def __init__(
+ self,
+ *,
+ in_channels: int,
+ base_channels: int,
+ channel_multipliers: List[int],
+ num_res_blocks: List[int],
+ latent_dim: int,
+ temporal_reductions: List[int],
+ spatial_reductions: List[int],
+ prune_bottlenecks: List[bool],
+ has_attentions: List[bool],
+ affine: bool = True,
+ bias: bool = True,
+ input_is_conv_1x1: bool = False,
+ padding_mode: str,
+ ):
+ super().__init__()
+ self.temporal_reductions = temporal_reductions
+ self.spatial_reductions = spatial_reductions
+ self.base_channels = base_channels
+ self.channel_multipliers = channel_multipliers
+ self.num_res_blocks = num_res_blocks
+ self.latent_dim = latent_dim
+
+ self.fourier_features = FourierFeatures()
+ ch = [mult * base_channels for mult in channel_multipliers]
+ num_down_blocks = len(ch) - 1
+ assert len(num_res_blocks) == num_down_blocks + 2
+
+ layers = (
+ [ops.Conv3d(in_channels, ch[0], kernel_size=(1, 1, 1), bias=True)]
+ if not input_is_conv_1x1
+ else [Conv1x1(in_channels, ch[0])]
+ )
+
+ assert len(prune_bottlenecks) == num_down_blocks + 2
+ assert len(has_attentions) == num_down_blocks + 2
+ block = partial(block_fn, padding_mode=padding_mode, affine=affine, bias=bias)
+
+ for _ in range(num_res_blocks[0]):
+ layers.append(block(ch[0], has_attention=has_attentions[0], prune_bottleneck=prune_bottlenecks[0]))
+ prune_bottlenecks = prune_bottlenecks[1:]
+ has_attentions = has_attentions[1:]
+
+ assert len(temporal_reductions) == len(spatial_reductions) == len(ch) - 1
+ for i in range(num_down_blocks):
+ layer = DownsampleBlock(
+ ch[i],
+ ch[i + 1],
+ num_res_blocks=num_res_blocks[i + 1],
+ temporal_reduction=temporal_reductions[i],
+ spatial_reduction=spatial_reductions[i],
+ prune_bottleneck=prune_bottlenecks[i],
+ has_attention=has_attentions[i],
+ affine=affine,
+ bias=bias,
+ padding_mode=padding_mode,
+ )
+
+ layers.append(layer)
+
+ # Additional blocks.
+ for _ in range(num_res_blocks[-1]):
+ layers.append(block(ch[-1], has_attention=has_attentions[-1], prune_bottleneck=prune_bottlenecks[-1]))
+
+ self.layers = nn.Sequential(*layers)
+
+ # Output layers.
+ self.output_norm = norm_fn(ch[-1])
+ self.output_proj = Conv1x1(ch[-1], 2 * latent_dim, bias=False)
+
+ @property
+ def temporal_downsample(self):
+ return math.prod(self.temporal_reductions)
+
+ @property
+ def spatial_downsample(self):
+ return math.prod(self.spatial_reductions)
+
+ def forward(self, x) -> LatentDistribution:
+ """Forward pass.
+
+ Args:
+ x: Input video tensor. Shape: [B, C, T, H, W]. Scaled to [-1, 1]
+
+ Returns:
+ means: Latent tensor. Shape: [B, latent_dim, t, h, w]. Scaled [-1, 1].
+ h = H // 8, w = W // 8, t - 1 = (T - 1) // 6
+ logvar: Shape: [B, latent_dim, t, h, w].
+ """
+ assert x.ndim == 5, f"Expected 5D input, got {x.shape}"
+ x = self.fourier_features(x)
+
+ x = self.layers(x)
+
+ x = self.output_norm(x)
+ x = F.silu(x, inplace=True)
+ x = self.output_proj(x)
+
+ means, logvar = torch.chunk(x, 2, dim=1)
+
+ assert means.ndim == 5
+ assert logvar.shape == means.shape
+ assert means.size(1) == self.latent_dim
+
+ return LatentDistribution(means, logvar)
+
+
+class VideoVAE(nn.Module):
+ def __init__(self):
+ super().__init__()
+ self.encoder = Encoder(
+ in_channels=15,
+ base_channels=64,
+ channel_multipliers=[1, 2, 4, 6],
+ num_res_blocks=[3, 3, 4, 6, 3],
+ latent_dim=12,
+ temporal_reductions=[1, 2, 3],
+ spatial_reductions=[2, 2, 2],
+ prune_bottlenecks=[False, False, False, False, False],
+ has_attentions=[False, True, True, True, True],
+ affine=True,
+ bias=True,
+ input_is_conv_1x1=True,
+ padding_mode="replicate"
+ )
+ self.decoder = Decoder(
+ out_channels=3,
+ base_channels=128,
+ channel_multipliers=[1, 2, 4, 6],
+ temporal_expansions=[1, 2, 3],
+ spatial_expansions=[2, 2, 2],
+ num_res_blocks=[3, 3, 4, 6, 3],
+ latent_dim=12,
+ has_attention=[False, False, False, False, False],
+ padding_mode="replicate",
+ output_norm=False,
+ nonlinearity="silu",
+ output_nonlinearity="silu",
+ causal=True,
+ )
+
+ def encode(self, x):
+ return self.encoder(x).mode()
+
+ def decode(self, x):
+ return self.decoder(x)
diff --git a/ComfyUI/comfy/ldm/hidream/__pycache__/model.cpython-312.pyc b/ComfyUI/comfy/ldm/hidream/__pycache__/model.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..23a9d36206d20005be54537b4bd62dad13eb2d5b
Binary files /dev/null and b/ComfyUI/comfy/ldm/hidream/__pycache__/model.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/hidream/model.py b/ComfyUI/comfy/ldm/hidream/model.py
new file mode 100644
index 0000000000000000000000000000000000000000..28d81c79e55b2a57d670633733654b64d5700c07
--- /dev/null
+++ b/ComfyUI/comfy/ldm/hidream/model.py
@@ -0,0 +1,829 @@
+from typing import Optional, Tuple, List
+
+import torch
+import torch.nn as nn
+import einops
+from einops import repeat
+
+from comfy.ldm.lightricks.model import TimestepEmbedding, Timesteps
+import torch.nn.functional as F
+
+from comfy.ldm.flux.math import apply_rope, rope
+from comfy.ldm.flux.layers import LastLayer
+
+from comfy.ldm.modules.attention import optimized_attention
+import comfy.model_management
+import comfy.patcher_extension
+import comfy.ldm.common_dit
+
+
+# Copied from https://github.com/black-forest-labs/flux/blob/main/src/flux/modules/layers.py
+class EmbedND(nn.Module):
+ def __init__(self, theta: int, axes_dim: List[int]):
+ super().__init__()
+ self.theta = theta
+ self.axes_dim = axes_dim
+
+ def forward(self, ids: torch.Tensor) -> torch.Tensor:
+ n_axes = ids.shape[-1]
+ emb = torch.cat(
+ [rope(ids[..., i], self.axes_dim[i], self.theta) for i in range(n_axes)],
+ dim=-3,
+ )
+ return emb.unsqueeze(2)
+
+
+class PatchEmbed(nn.Module):
+ def __init__(
+ self,
+ patch_size=2,
+ in_channels=4,
+ out_channels=1024,
+ dtype=None, device=None, operations=None
+ ):
+ super().__init__()
+ self.patch_size = patch_size
+ self.out_channels = out_channels
+ self.proj = operations.Linear(in_channels * patch_size * patch_size, out_channels, bias=True, dtype=dtype, device=device)
+
+ def forward(self, latent):
+ latent = self.proj(latent)
+ return latent
+
+
+class PooledEmbed(nn.Module):
+ def __init__(self, text_emb_dim, hidden_size, dtype=None, device=None, operations=None):
+ super().__init__()
+ self.pooled_embedder = TimestepEmbedding(in_channels=text_emb_dim, time_embed_dim=hidden_size, dtype=dtype, device=device, operations=operations)
+
+ def forward(self, pooled_embed):
+ return self.pooled_embedder(pooled_embed)
+
+
+class TimestepEmbed(nn.Module):
+ def __init__(self, hidden_size, frequency_embedding_size=256, dtype=None, device=None, operations=None):
+ super().__init__()
+ self.time_proj = Timesteps(num_channels=frequency_embedding_size, flip_sin_to_cos=True, downscale_freq_shift=0)
+ self.timestep_embedder = TimestepEmbedding(in_channels=frequency_embedding_size, time_embed_dim=hidden_size, dtype=dtype, device=device, operations=operations)
+
+ def forward(self, timesteps, wdtype):
+ t_emb = self.time_proj(timesteps).to(dtype=wdtype)
+ t_emb = self.timestep_embedder(t_emb)
+ return t_emb
+
+
+def attention(query: torch.Tensor, key: torch.Tensor, value: torch.Tensor, transformer_options={}):
+ return optimized_attention(query.view(query.shape[0], -1, query.shape[-1] * query.shape[-2]), key.view(key.shape[0], -1, key.shape[-1] * key.shape[-2]), value.view(value.shape[0], -1, value.shape[-1] * value.shape[-2]), query.shape[2], transformer_options=transformer_options)
+
+
+class HiDreamAttnProcessor_flashattn:
+ """Attention processor used typically in processing the SD3-like self-attention projections."""
+
+ def __call__(
+ self,
+ attn,
+ image_tokens: torch.FloatTensor,
+ image_tokens_masks: Optional[torch.FloatTensor] = None,
+ text_tokens: Optional[torch.FloatTensor] = None,
+ rope: torch.FloatTensor = None,
+ transformer_options={},
+ *args,
+ **kwargs,
+ ) -> torch.FloatTensor:
+ dtype = image_tokens.dtype
+ batch_size = image_tokens.shape[0]
+
+ query_i = attn.q_rms_norm(attn.to_q(image_tokens)).to(dtype=dtype)
+ key_i = attn.k_rms_norm(attn.to_k(image_tokens)).to(dtype=dtype)
+ value_i = attn.to_v(image_tokens)
+
+ inner_dim = key_i.shape[-1]
+ head_dim = inner_dim // attn.heads
+
+ query_i = query_i.view(batch_size, -1, attn.heads, head_dim)
+ key_i = key_i.view(batch_size, -1, attn.heads, head_dim)
+ value_i = value_i.view(batch_size, -1, attn.heads, head_dim)
+ if image_tokens_masks is not None:
+ key_i = key_i * image_tokens_masks.view(batch_size, -1, 1, 1)
+
+ if not attn.single:
+ query_t = attn.q_rms_norm_t(attn.to_q_t(text_tokens)).to(dtype=dtype)
+ key_t = attn.k_rms_norm_t(attn.to_k_t(text_tokens)).to(dtype=dtype)
+ value_t = attn.to_v_t(text_tokens)
+
+ query_t = query_t.view(batch_size, -1, attn.heads, head_dim)
+ key_t = key_t.view(batch_size, -1, attn.heads, head_dim)
+ value_t = value_t.view(batch_size, -1, attn.heads, head_dim)
+
+ num_image_tokens = query_i.shape[1]
+ num_text_tokens = query_t.shape[1]
+ query = torch.cat([query_i, query_t], dim=1)
+ key = torch.cat([key_i, key_t], dim=1)
+ value = torch.cat([value_i, value_t], dim=1)
+ else:
+ query = query_i
+ key = key_i
+ value = value_i
+
+ if query.shape[-1] == rope.shape[-3] * 2:
+ query, key = apply_rope(query, key, rope)
+ else:
+ query_1, query_2 = query.chunk(2, dim=-1)
+ key_1, key_2 = key.chunk(2, dim=-1)
+ query_1, key_1 = apply_rope(query_1, key_1, rope)
+ query = torch.cat([query_1, query_2], dim=-1)
+ key = torch.cat([key_1, key_2], dim=-1)
+
+ hidden_states = attention(query, key, value, transformer_options=transformer_options)
+
+ if not attn.single:
+ hidden_states_i, hidden_states_t = torch.split(hidden_states, [num_image_tokens, num_text_tokens], dim=1)
+ hidden_states_i = attn.to_out(hidden_states_i)
+ hidden_states_t = attn.to_out_t(hidden_states_t)
+ return hidden_states_i, hidden_states_t
+ else:
+ hidden_states = attn.to_out(hidden_states)
+ return hidden_states
+
+class HiDreamAttention(nn.Module):
+ def __init__(
+ self,
+ query_dim: int,
+ heads: int = 8,
+ dim_head: int = 64,
+ upcast_attention: bool = False,
+ upcast_softmax: bool = False,
+ scale_qk: bool = True,
+ eps: float = 1e-5,
+ processor = None,
+ out_dim: int = None,
+ single: bool = False,
+ dtype=None, device=None, operations=None
+ ):
+ # super(Attention, self).__init__()
+ super().__init__()
+ self.inner_dim = out_dim if out_dim is not None else dim_head * heads
+ self.query_dim = query_dim
+ self.upcast_attention = upcast_attention
+ self.upcast_softmax = upcast_softmax
+ self.out_dim = out_dim if out_dim is not None else query_dim
+
+ self.scale_qk = scale_qk
+ self.scale = dim_head**-0.5 if self.scale_qk else 1.0
+
+ self.heads = out_dim // dim_head if out_dim is not None else heads
+ self.sliceable_head_dim = heads
+ self.single = single
+
+ linear_cls = operations.Linear
+ self.linear_cls = linear_cls
+ self.to_q = linear_cls(query_dim, self.inner_dim, dtype=dtype, device=device)
+ self.to_k = linear_cls(self.inner_dim, self.inner_dim, dtype=dtype, device=device)
+ self.to_v = linear_cls(self.inner_dim, self.inner_dim, dtype=dtype, device=device)
+ self.to_out = linear_cls(self.inner_dim, self.out_dim, dtype=dtype, device=device)
+ self.q_rms_norm = operations.RMSNorm(self.inner_dim, eps, dtype=dtype, device=device)
+ self.k_rms_norm = operations.RMSNorm(self.inner_dim, eps, dtype=dtype, device=device)
+
+ if not single:
+ self.to_q_t = linear_cls(query_dim, self.inner_dim, dtype=dtype, device=device)
+ self.to_k_t = linear_cls(self.inner_dim, self.inner_dim, dtype=dtype, device=device)
+ self.to_v_t = linear_cls(self.inner_dim, self.inner_dim, dtype=dtype, device=device)
+ self.to_out_t = linear_cls(self.inner_dim, self.out_dim, dtype=dtype, device=device)
+ self.q_rms_norm_t = operations.RMSNorm(self.inner_dim, eps, dtype=dtype, device=device)
+ self.k_rms_norm_t = operations.RMSNorm(self.inner_dim, eps, dtype=dtype, device=device)
+
+ self.processor = processor
+
+ def forward(
+ self,
+ norm_image_tokens: torch.FloatTensor,
+ image_tokens_masks: torch.FloatTensor = None,
+ norm_text_tokens: torch.FloatTensor = None,
+ rope: torch.FloatTensor = None,
+ transformer_options={},
+ ) -> torch.Tensor:
+ return self.processor(
+ self,
+ image_tokens = norm_image_tokens,
+ image_tokens_masks = image_tokens_masks,
+ text_tokens = norm_text_tokens,
+ rope = rope,
+ transformer_options=transformer_options,
+ )
+
+
+class FeedForwardSwiGLU(nn.Module):
+ def __init__(
+ self,
+ dim: int,
+ hidden_dim: int,
+ multiple_of: int = 256,
+ ffn_dim_multiplier: Optional[float] = None,
+ dtype=None, device=None, operations=None
+ ):
+ super().__init__()
+ hidden_dim = int(2 * hidden_dim / 3)
+ # custom dim factor multiplier
+ if ffn_dim_multiplier is not None:
+ hidden_dim = int(ffn_dim_multiplier * hidden_dim)
+ hidden_dim = multiple_of * (
+ (hidden_dim + multiple_of - 1) // multiple_of
+ )
+
+ self.w1 = operations.Linear(dim, hidden_dim, bias=False, dtype=dtype, device=device)
+ self.w2 = operations.Linear(hidden_dim, dim, bias=False, dtype=dtype, device=device)
+ self.w3 = operations.Linear(dim, hidden_dim, bias=False, dtype=dtype, device=device)
+
+ def forward(self, x):
+ return self.w2(torch.nn.functional.silu(self.w1(x)) * self.w3(x))
+
+
+# Modified from https://github.com/deepseek-ai/DeepSeek-V3/blob/main/inference/model.py
+class MoEGate(nn.Module):
+ def __init__(self, embed_dim, num_routed_experts=4, num_activated_experts=2, aux_loss_alpha=0.01, dtype=None, device=None, operations=None):
+ super().__init__()
+ self.top_k = num_activated_experts
+ self.n_routed_experts = num_routed_experts
+
+ self.scoring_func = 'softmax'
+ self.alpha = aux_loss_alpha
+ self.seq_aux = False
+
+ # topk selection algorithm
+ self.norm_topk_prob = False
+ self.gating_dim = embed_dim
+ self.weight = nn.Parameter(torch.empty((self.n_routed_experts, self.gating_dim), dtype=dtype, device=device))
+ self.reset_parameters()
+
+ def reset_parameters(self) -> None:
+ pass
+ # import torch.nn.init as init
+ # init.kaiming_uniform_(self.weight, a=math.sqrt(5))
+
+ def forward(self, hidden_states):
+ bsz, seq_len, h = hidden_states.shape
+
+ ### compute gating score
+ hidden_states = hidden_states.view(-1, h)
+ logits = F.linear(hidden_states, comfy.model_management.cast_to(self.weight, dtype=hidden_states.dtype, device=hidden_states.device), None)
+ if self.scoring_func == 'softmax':
+ scores = logits.softmax(dim=-1)
+ else:
+ raise NotImplementedError(f'insupportable scoring function for MoE gating: {self.scoring_func}')
+
+ ### select top-k experts
+ topk_weight, topk_idx = torch.topk(scores, k=self.top_k, dim=-1, sorted=False)
+
+ ### norm gate to sum 1
+ if self.top_k > 1 and self.norm_topk_prob:
+ denominator = topk_weight.sum(dim=-1, keepdim=True) + 1e-20
+ topk_weight = topk_weight / denominator
+
+ aux_loss = None
+ return topk_idx, topk_weight, aux_loss
+
+
+# Modified from https://github.com/deepseek-ai/DeepSeek-V3/blob/main/inference/model.py
+class MOEFeedForwardSwiGLU(nn.Module):
+ def __init__(
+ self,
+ dim: int,
+ hidden_dim: int,
+ num_routed_experts: int,
+ num_activated_experts: int,
+ dtype=None, device=None, operations=None
+ ):
+ super().__init__()
+ self.shared_experts = FeedForwardSwiGLU(dim, hidden_dim // 2, dtype=dtype, device=device, operations=operations)
+ self.experts = nn.ModuleList([FeedForwardSwiGLU(dim, hidden_dim, dtype=dtype, device=device, operations=operations) for i in range(num_routed_experts)])
+ self.gate = MoEGate(
+ embed_dim = dim,
+ num_routed_experts = num_routed_experts,
+ num_activated_experts = num_activated_experts,
+ dtype=dtype, device=device, operations=operations
+ )
+ self.num_activated_experts = num_activated_experts
+
+ def forward(self, x):
+ wtype = x.dtype
+ identity = x
+ orig_shape = x.shape
+ topk_idx, topk_weight, aux_loss = self.gate(x)
+ x = x.view(-1, x.shape[-1])
+ flat_topk_idx = topk_idx.view(-1)
+ if True: # self.training: # TODO: check which branch performs faster
+ x = x.repeat_interleave(self.num_activated_experts, dim=0)
+ y = torch.empty_like(x, dtype=wtype)
+ for i, expert in enumerate(self.experts):
+ y[flat_topk_idx == i] = expert(x[flat_topk_idx == i]).to(dtype=wtype)
+ y = (y.view(*topk_weight.shape, -1) * topk_weight.unsqueeze(-1)).sum(dim=1)
+ y = y.view(*orig_shape).to(dtype=wtype)
+ #y = AddAuxiliaryLoss.apply(y, aux_loss)
+ else:
+ y = self.moe_infer(x, flat_topk_idx, topk_weight.view(-1, 1)).view(*orig_shape)
+ y = y + self.shared_experts(identity)
+ return y
+
+ @torch.no_grad()
+ def moe_infer(self, x, flat_expert_indices, flat_expert_weights):
+ expert_cache = torch.zeros_like(x)
+ idxs = flat_expert_indices.argsort()
+ tokens_per_expert = flat_expert_indices.bincount().cpu().numpy().cumsum(0)
+ token_idxs = idxs // self.num_activated_experts
+ for i, end_idx in enumerate(tokens_per_expert):
+ start_idx = 0 if i == 0 else tokens_per_expert[i-1]
+ if start_idx == end_idx:
+ continue
+ expert = self.experts[i]
+ exp_token_idx = token_idxs[start_idx:end_idx]
+ expert_tokens = x[exp_token_idx]
+ expert_out = expert(expert_tokens)
+ expert_out.mul_(flat_expert_weights[idxs[start_idx:end_idx]])
+
+ # for fp16 and other dtype
+ expert_cache = expert_cache.to(expert_out.dtype)
+ expert_cache.scatter_reduce_(0, exp_token_idx.view(-1, 1).repeat(1, x.shape[-1]), expert_out, reduce='sum')
+ return expert_cache
+
+
+class TextProjection(nn.Module):
+ def __init__(self, in_features, hidden_size, dtype=None, device=None, operations=None):
+ super().__init__()
+ self.linear = operations.Linear(in_features=in_features, out_features=hidden_size, bias=False, dtype=dtype, device=device)
+
+ def forward(self, caption):
+ hidden_states = self.linear(caption)
+ return hidden_states
+
+
+class BlockType:
+ TransformerBlock = 1
+ SingleTransformerBlock = 2
+
+
+class HiDreamImageSingleTransformerBlock(nn.Module):
+ def __init__(
+ self,
+ dim: int,
+ num_attention_heads: int,
+ attention_head_dim: int,
+ num_routed_experts: int = 4,
+ num_activated_experts: int = 2,
+ dtype=None, device=None, operations=None
+ ):
+ super().__init__()
+ self.num_attention_heads = num_attention_heads
+ self.adaLN_modulation = nn.Sequential(
+ nn.SiLU(),
+ operations.Linear(dim, 6 * dim, bias=True, dtype=dtype, device=device)
+ )
+
+ # 1. Attention
+ self.norm1_i = operations.LayerNorm(dim, eps = 1e-06, elementwise_affine = False, dtype=dtype, device=device)
+ self.attn1 = HiDreamAttention(
+ query_dim=dim,
+ heads=num_attention_heads,
+ dim_head=attention_head_dim,
+ processor = HiDreamAttnProcessor_flashattn(),
+ single = True,
+ dtype=dtype, device=device, operations=operations
+ )
+
+ # 3. Feed-forward
+ self.norm3_i = operations.LayerNorm(dim, eps = 1e-06, elementwise_affine = False, dtype=dtype, device=device)
+ if num_routed_experts > 0:
+ self.ff_i = MOEFeedForwardSwiGLU(
+ dim = dim,
+ hidden_dim = 4 * dim,
+ num_routed_experts = num_routed_experts,
+ num_activated_experts = num_activated_experts,
+ dtype=dtype, device=device, operations=operations
+ )
+ else:
+ self.ff_i = FeedForwardSwiGLU(dim = dim, hidden_dim = 4 * dim, dtype=dtype, device=device, operations=operations)
+
+ def forward(
+ self,
+ image_tokens: torch.FloatTensor,
+ image_tokens_masks: Optional[torch.FloatTensor] = None,
+ text_tokens: Optional[torch.FloatTensor] = None,
+ adaln_input: Optional[torch.FloatTensor] = None,
+ rope: torch.FloatTensor = None,
+ transformer_options={},
+ ) -> torch.FloatTensor:
+ wtype = image_tokens.dtype
+ shift_msa_i, scale_msa_i, gate_msa_i, shift_mlp_i, scale_mlp_i, gate_mlp_i = \
+ self.adaLN_modulation(adaln_input)[:,None].chunk(6, dim=-1)
+
+ # 1. MM-Attention
+ norm_image_tokens = self.norm1_i(image_tokens).to(dtype=wtype)
+ norm_image_tokens = norm_image_tokens * (1 + scale_msa_i) + shift_msa_i
+ attn_output_i = self.attn1(
+ norm_image_tokens,
+ image_tokens_masks,
+ rope = rope,
+ transformer_options=transformer_options,
+ )
+ image_tokens = gate_msa_i * attn_output_i + image_tokens
+
+ # 2. Feed-forward
+ norm_image_tokens = self.norm3_i(image_tokens).to(dtype=wtype)
+ norm_image_tokens = norm_image_tokens * (1 + scale_mlp_i) + shift_mlp_i
+ ff_output_i = gate_mlp_i * self.ff_i(norm_image_tokens.to(dtype=wtype))
+ image_tokens = ff_output_i + image_tokens
+ return image_tokens
+
+
+class HiDreamImageTransformerBlock(nn.Module):
+ def __init__(
+ self,
+ dim: int,
+ num_attention_heads: int,
+ attention_head_dim: int,
+ num_routed_experts: int = 4,
+ num_activated_experts: int = 2,
+ dtype=None, device=None, operations=None
+ ):
+ super().__init__()
+ self.num_attention_heads = num_attention_heads
+ self.adaLN_modulation = nn.Sequential(
+ nn.SiLU(),
+ operations.Linear(dim, 12 * dim, bias=True, dtype=dtype, device=device)
+ )
+ # nn.init.zeros_(self.adaLN_modulation[1].weight)
+ # nn.init.zeros_(self.adaLN_modulation[1].bias)
+
+ # 1. Attention
+ self.norm1_i = operations.LayerNorm(dim, eps = 1e-06, elementwise_affine = False, dtype=dtype, device=device)
+ self.norm1_t = operations.LayerNorm(dim, eps = 1e-06, elementwise_affine = False, dtype=dtype, device=device)
+ self.attn1 = HiDreamAttention(
+ query_dim=dim,
+ heads=num_attention_heads,
+ dim_head=attention_head_dim,
+ processor = HiDreamAttnProcessor_flashattn(),
+ single = False,
+ dtype=dtype, device=device, operations=operations
+ )
+
+ # 3. Feed-forward
+ self.norm3_i = operations.LayerNorm(dim, eps = 1e-06, elementwise_affine = False, dtype=dtype, device=device)
+ if num_routed_experts > 0:
+ self.ff_i = MOEFeedForwardSwiGLU(
+ dim = dim,
+ hidden_dim = 4 * dim,
+ num_routed_experts = num_routed_experts,
+ num_activated_experts = num_activated_experts,
+ dtype=dtype, device=device, operations=operations
+ )
+ else:
+ self.ff_i = FeedForwardSwiGLU(dim = dim, hidden_dim = 4 * dim, dtype=dtype, device=device, operations=operations)
+ self.norm3_t = operations.LayerNorm(dim, eps = 1e-06, elementwise_affine = False)
+ self.ff_t = FeedForwardSwiGLU(dim = dim, hidden_dim = 4 * dim, dtype=dtype, device=device, operations=operations)
+
+ def forward(
+ self,
+ image_tokens: torch.FloatTensor,
+ image_tokens_masks: Optional[torch.FloatTensor] = None,
+ text_tokens: Optional[torch.FloatTensor] = None,
+ adaln_input: Optional[torch.FloatTensor] = None,
+ rope: torch.FloatTensor = None,
+ transformer_options={},
+ ) -> torch.FloatTensor:
+ wtype = image_tokens.dtype
+ shift_msa_i, scale_msa_i, gate_msa_i, shift_mlp_i, scale_mlp_i, gate_mlp_i, \
+ shift_msa_t, scale_msa_t, gate_msa_t, shift_mlp_t, scale_mlp_t, gate_mlp_t = \
+ self.adaLN_modulation(adaln_input)[:,None].chunk(12, dim=-1)
+
+ # 1. MM-Attention
+ norm_image_tokens = self.norm1_i(image_tokens).to(dtype=wtype)
+ norm_image_tokens = norm_image_tokens * (1 + scale_msa_i) + shift_msa_i
+ norm_text_tokens = self.norm1_t(text_tokens).to(dtype=wtype)
+ norm_text_tokens = norm_text_tokens * (1 + scale_msa_t) + shift_msa_t
+
+ attn_output_i, attn_output_t = self.attn1(
+ norm_image_tokens,
+ image_tokens_masks,
+ norm_text_tokens,
+ rope = rope,
+ transformer_options=transformer_options,
+ )
+
+ image_tokens = gate_msa_i * attn_output_i + image_tokens
+ text_tokens = gate_msa_t * attn_output_t + text_tokens
+
+ # 2. Feed-forward
+ norm_image_tokens = self.norm3_i(image_tokens).to(dtype=wtype)
+ norm_image_tokens = norm_image_tokens * (1 + scale_mlp_i) + shift_mlp_i
+ norm_text_tokens = self.norm3_t(text_tokens).to(dtype=wtype)
+ norm_text_tokens = norm_text_tokens * (1 + scale_mlp_t) + shift_mlp_t
+
+ ff_output_i = gate_mlp_i * self.ff_i(norm_image_tokens)
+ ff_output_t = gate_mlp_t * self.ff_t(norm_text_tokens)
+ image_tokens = ff_output_i + image_tokens
+ text_tokens = ff_output_t + text_tokens
+ return image_tokens, text_tokens
+
+
+class HiDreamImageBlock(nn.Module):
+ def __init__(
+ self,
+ dim: int,
+ num_attention_heads: int,
+ attention_head_dim: int,
+ num_routed_experts: int = 4,
+ num_activated_experts: int = 2,
+ block_type: BlockType = BlockType.TransformerBlock,
+ dtype=None, device=None, operations=None
+ ):
+ super().__init__()
+ block_classes = {
+ BlockType.TransformerBlock: HiDreamImageTransformerBlock,
+ BlockType.SingleTransformerBlock: HiDreamImageSingleTransformerBlock,
+ }
+ self.block = block_classes[block_type](
+ dim,
+ num_attention_heads,
+ attention_head_dim,
+ num_routed_experts,
+ num_activated_experts,
+ dtype=dtype, device=device, operations=operations
+ )
+
+ def forward(
+ self,
+ image_tokens: torch.FloatTensor,
+ image_tokens_masks: Optional[torch.FloatTensor] = None,
+ text_tokens: Optional[torch.FloatTensor] = None,
+ adaln_input: torch.FloatTensor = None,
+ rope: torch.FloatTensor = None,
+ transformer_options={},
+ ) -> torch.FloatTensor:
+ return self.block(
+ image_tokens,
+ image_tokens_masks,
+ text_tokens,
+ adaln_input,
+ rope,
+ transformer_options=transformer_options,
+ )
+
+
+class HiDreamImageTransformer2DModel(nn.Module):
+ def __init__(
+ self,
+ patch_size: Optional[int] = None,
+ in_channels: int = 64,
+ out_channels: Optional[int] = None,
+ num_layers: int = 16,
+ num_single_layers: int = 32,
+ attention_head_dim: int = 128,
+ num_attention_heads: int = 20,
+ caption_channels: List[int] = None,
+ text_emb_dim: int = 2048,
+ num_routed_experts: int = 4,
+ num_activated_experts: int = 2,
+ axes_dims_rope: Tuple[int, int] = (32, 32),
+ max_resolution: Tuple[int, int] = (128, 128),
+ llama_layers: List[int] = None,
+ image_model=None,
+ dtype=None, device=None, operations=None
+ ):
+ self.patch_size = patch_size
+ self.num_attention_heads = num_attention_heads
+ self.attention_head_dim = attention_head_dim
+ self.num_layers = num_layers
+ self.num_single_layers = num_single_layers
+
+ self.gradient_checkpointing = False
+
+ super().__init__()
+ self.dtype = dtype
+ self.out_channels = out_channels or in_channels
+ self.inner_dim = self.num_attention_heads * self.attention_head_dim
+ self.llama_layers = llama_layers
+
+ self.t_embedder = TimestepEmbed(self.inner_dim, dtype=dtype, device=device, operations=operations)
+ self.p_embedder = PooledEmbed(text_emb_dim, self.inner_dim, dtype=dtype, device=device, operations=operations)
+ self.x_embedder = PatchEmbed(
+ patch_size = patch_size,
+ in_channels = in_channels,
+ out_channels = self.inner_dim,
+ dtype=dtype, device=device, operations=operations
+ )
+ self.pe_embedder = EmbedND(theta=10000, axes_dim=axes_dims_rope)
+
+ self.double_stream_blocks = nn.ModuleList(
+ [
+ HiDreamImageBlock(
+ dim = self.inner_dim,
+ num_attention_heads = self.num_attention_heads,
+ attention_head_dim = self.attention_head_dim,
+ num_routed_experts = num_routed_experts,
+ num_activated_experts = num_activated_experts,
+ block_type = BlockType.TransformerBlock,
+ dtype=dtype, device=device, operations=operations
+ )
+ for i in range(self.num_layers)
+ ]
+ )
+
+ self.single_stream_blocks = nn.ModuleList(
+ [
+ HiDreamImageBlock(
+ dim = self.inner_dim,
+ num_attention_heads = self.num_attention_heads,
+ attention_head_dim = self.attention_head_dim,
+ num_routed_experts = num_routed_experts,
+ num_activated_experts = num_activated_experts,
+ block_type = BlockType.SingleTransformerBlock,
+ dtype=dtype, device=device, operations=operations
+ )
+ for i in range(self.num_single_layers)
+ ]
+ )
+
+ self.final_layer = LastLayer(self.inner_dim, patch_size, self.out_channels, dtype=dtype, device=device, operations=operations)
+
+ caption_channels = [caption_channels[1], ] * (num_layers + num_single_layers) + [caption_channels[0], ]
+ caption_projection = []
+ for caption_channel in caption_channels:
+ caption_projection.append(TextProjection(in_features=caption_channel, hidden_size=self.inner_dim, dtype=dtype, device=device, operations=operations))
+ self.caption_projection = nn.ModuleList(caption_projection)
+ self.max_seq = max_resolution[0] * max_resolution[1] // (patch_size * patch_size)
+
+ def expand_timesteps(self, timesteps, batch_size, device):
+ if not torch.is_tensor(timesteps):
+ is_mps = device.type == "mps"
+ if isinstance(timesteps, float):
+ dtype = torch.float32 if is_mps else torch.float64
+ else:
+ dtype = torch.int32 if is_mps else torch.int64
+ timesteps = torch.tensor([timesteps], dtype=dtype, device=device)
+ elif len(timesteps.shape) == 0:
+ timesteps = timesteps[None].to(device)
+ # broadcast to batch dimension in a way that's compatible with ONNX/Core ML
+ timesteps = timesteps.expand(batch_size)
+ return timesteps
+
+ def unpatchify(self, x: torch.Tensor, img_sizes: List[Tuple[int, int]]) -> List[torch.Tensor]:
+ x_arr = []
+ for i, img_size in enumerate(img_sizes):
+ pH, pW = img_size
+ x_arr.append(
+ einops.rearrange(x[i, :pH*pW].reshape(1, pH, pW, -1), 'B H W (p1 p2 C) -> B C (H p1) (W p2)',
+ p1=self.patch_size, p2=self.patch_size)
+ )
+ x = torch.cat(x_arr, dim=0)
+ return x
+
+ def patchify(self, x, max_seq, img_sizes=None):
+ pz2 = self.patch_size * self.patch_size
+ if isinstance(x, torch.Tensor):
+ B = x.shape[0]
+ device = x.device
+ dtype = x.dtype
+ else:
+ B = len(x)
+ device = x[0].device
+ dtype = x[0].dtype
+ x_masks = torch.zeros((B, max_seq), dtype=dtype, device=device)
+
+ if img_sizes is not None:
+ for i, img_size in enumerate(img_sizes):
+ x_masks[i, 0:img_size[0] * img_size[1]] = 1
+ x = einops.rearrange(x, 'B C S p -> B S (p C)', p=pz2)
+ elif isinstance(x, torch.Tensor):
+ pH, pW = x.shape[-2] // self.patch_size, x.shape[-1] // self.patch_size
+ x = einops.rearrange(x, 'B C (H p1) (W p2) -> B (H W) (p1 p2 C)', p1=self.patch_size, p2=self.patch_size)
+ img_sizes = [[pH, pW]] * B
+ x_masks = None
+ else:
+ raise NotImplementedError
+ return x, x_masks, img_sizes
+
+ def forward(self,
+ x: torch.Tensor,
+ t: torch.Tensor,
+ y: Optional[torch.Tensor] = None,
+ context: Optional[torch.Tensor] = None,
+ encoder_hidden_states_llama3=None,
+ image_cond=None,
+ control = None,
+ transformer_options = {},
+ ):
+ return comfy.patcher_extension.WrapperExecutor.new_class_executor(
+ self._forward,
+ self,
+ comfy.patcher_extension.get_all_wrappers(comfy.patcher_extension.WrappersMP.DIFFUSION_MODEL, transformer_options)
+ ).execute(x, t, y, context, encoder_hidden_states_llama3, image_cond, control, transformer_options)
+
+ def _forward(
+ self,
+ x: torch.Tensor,
+ t: torch.Tensor,
+ y: Optional[torch.Tensor] = None,
+ context: Optional[torch.Tensor] = None,
+ encoder_hidden_states_llama3=None,
+ image_cond=None,
+ control = None,
+ transformer_options = {},
+ ) -> torch.Tensor:
+ bs, c, h, w = x.shape
+ if image_cond is not None:
+ x = torch.cat([x, image_cond], dim=-1)
+ hidden_states = comfy.ldm.common_dit.pad_to_patch_size(x, (self.patch_size, self.patch_size))
+ timesteps = t
+ pooled_embeds = y
+ T5_encoder_hidden_states = context
+
+ img_sizes = None
+
+ # spatial forward
+ batch_size = hidden_states.shape[0]
+ hidden_states_type = hidden_states.dtype
+
+ # 0. time
+ timesteps = self.expand_timesteps(timesteps, batch_size, hidden_states.device)
+ timesteps = self.t_embedder(timesteps, hidden_states_type)
+ p_embedder = self.p_embedder(pooled_embeds)
+ adaln_input = timesteps + p_embedder
+
+ hidden_states, image_tokens_masks, img_sizes = self.patchify(hidden_states, self.max_seq, img_sizes)
+ if image_tokens_masks is None:
+ pH, pW = img_sizes[0]
+ img_ids = torch.zeros(pH, pW, 3, device=hidden_states.device)
+ img_ids[..., 1] = img_ids[..., 1] + torch.arange(pH, device=hidden_states.device)[:, None]
+ img_ids[..., 2] = img_ids[..., 2] + torch.arange(pW, device=hidden_states.device)[None, :]
+ img_ids = repeat(img_ids, "h w c -> b (h w) c", b=batch_size)
+ hidden_states = self.x_embedder(hidden_states)
+
+ # T5_encoder_hidden_states = encoder_hidden_states[0]
+ encoder_hidden_states = encoder_hidden_states_llama3.movedim(1, 0)
+ encoder_hidden_states = [encoder_hidden_states[k] for k in self.llama_layers]
+
+ if self.caption_projection is not None:
+ new_encoder_hidden_states = []
+ for i, enc_hidden_state in enumerate(encoder_hidden_states):
+ enc_hidden_state = self.caption_projection[i](enc_hidden_state)
+ enc_hidden_state = enc_hidden_state.view(batch_size, -1, hidden_states.shape[-1])
+ new_encoder_hidden_states.append(enc_hidden_state)
+ encoder_hidden_states = new_encoder_hidden_states
+ T5_encoder_hidden_states = self.caption_projection[-1](T5_encoder_hidden_states)
+ T5_encoder_hidden_states = T5_encoder_hidden_states.view(batch_size, -1, hidden_states.shape[-1])
+ encoder_hidden_states.append(T5_encoder_hidden_states)
+
+ txt_ids = torch.zeros(
+ batch_size,
+ encoder_hidden_states[-1].shape[1] + encoder_hidden_states[-2].shape[1] + encoder_hidden_states[0].shape[1],
+ 3,
+ device=img_ids.device, dtype=img_ids.dtype
+ )
+ ids = torch.cat((img_ids, txt_ids), dim=1)
+ rope = self.pe_embedder(ids)
+
+ # 2. Blocks
+ block_id = 0
+ initial_encoder_hidden_states = torch.cat([encoder_hidden_states[-1], encoder_hidden_states[-2]], dim=1)
+ initial_encoder_hidden_states_seq_len = initial_encoder_hidden_states.shape[1]
+ for bid, block in enumerate(self.double_stream_blocks):
+ cur_llama31_encoder_hidden_states = encoder_hidden_states[block_id]
+ cur_encoder_hidden_states = torch.cat([initial_encoder_hidden_states, cur_llama31_encoder_hidden_states], dim=1)
+ hidden_states, initial_encoder_hidden_states = block(
+ image_tokens = hidden_states,
+ image_tokens_masks = image_tokens_masks,
+ text_tokens = cur_encoder_hidden_states,
+ adaln_input = adaln_input,
+ rope = rope,
+ transformer_options=transformer_options,
+ )
+ initial_encoder_hidden_states = initial_encoder_hidden_states[:, :initial_encoder_hidden_states_seq_len]
+ block_id += 1
+
+ image_tokens_seq_len = hidden_states.shape[1]
+ hidden_states = torch.cat([hidden_states, initial_encoder_hidden_states], dim=1)
+ hidden_states_seq_len = hidden_states.shape[1]
+ if image_tokens_masks is not None:
+ encoder_attention_mask_ones = torch.ones(
+ (batch_size, initial_encoder_hidden_states.shape[1] + cur_llama31_encoder_hidden_states.shape[1]),
+ device=image_tokens_masks.device, dtype=image_tokens_masks.dtype
+ )
+ image_tokens_masks = torch.cat([image_tokens_masks, encoder_attention_mask_ones], dim=1)
+
+ for bid, block in enumerate(self.single_stream_blocks):
+ cur_llama31_encoder_hidden_states = encoder_hidden_states[block_id]
+ hidden_states = torch.cat([hidden_states, cur_llama31_encoder_hidden_states], dim=1)
+ hidden_states = block(
+ image_tokens=hidden_states,
+ image_tokens_masks=image_tokens_masks,
+ text_tokens=None,
+ adaln_input=adaln_input,
+ rope=rope,
+ transformer_options=transformer_options,
+ )
+ hidden_states = hidden_states[:, :hidden_states_seq_len]
+ block_id += 1
+
+ hidden_states = hidden_states[:, :image_tokens_seq_len, ...]
+ output = self.final_layer(hidden_states, adaln_input)
+ output = self.unpatchify(output, img_sizes)
+ return -output[:, :, :h, :w]
diff --git a/ComfyUI/comfy/ldm/hidream_o1/__pycache__/attention.cpython-312.pyc b/ComfyUI/comfy/ldm/hidream_o1/__pycache__/attention.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..da2d3ffb80e4b78fba99856eda7635258e3ed734
Binary files /dev/null and b/ComfyUI/comfy/ldm/hidream_o1/__pycache__/attention.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/hidream_o1/__pycache__/conditioning.cpython-312.pyc b/ComfyUI/comfy/ldm/hidream_o1/__pycache__/conditioning.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..a92c29cf60a959cebd1057d6658854187a05af48
Binary files /dev/null and b/ComfyUI/comfy/ldm/hidream_o1/__pycache__/conditioning.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/hidream_o1/__pycache__/model.cpython-312.pyc b/ComfyUI/comfy/ldm/hidream_o1/__pycache__/model.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..409ce7b3e9ef7666fab4ca1896720cd2c715cc7c
Binary files /dev/null and b/ComfyUI/comfy/ldm/hidream_o1/__pycache__/model.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/hidream_o1/__pycache__/utils.cpython-312.pyc b/ComfyUI/comfy/ldm/hidream_o1/__pycache__/utils.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..ad557f4e2880b04a7f0bb7a83b4cb3a9e2d7c4e6
Binary files /dev/null and b/ComfyUI/comfy/ldm/hidream_o1/__pycache__/utils.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/hidream_o1/attention.py b/ComfyUI/comfy/ldm/hidream_o1/attention.py
new file mode 100644
index 0000000000000000000000000000000000000000..afb2be9b89eac5924539eccb080b79d10b98bcf5
--- /dev/null
+++ b/ComfyUI/comfy/ldm/hidream_o1/attention.py
@@ -0,0 +1,41 @@
+"""HiDream-O1 two-pass attention: tokens [0, ar_len) are causal, [ar_len, T)
+attend full K/V. Splitting Q at the boundary avoids the (B, 1, T, T) additive
+mask the general-purpose path would build (~500 MB at T~16K) and lets the
+gen half hit the user's preferred backend via optimized_attention.
+"""
+
+import torch
+
+import comfy.ops
+from comfy.ldm.modules.attention import optimized_attention
+
+
+def make_two_pass_attention(ar_len: int, transformer_options=None):
+ """Build a two-pass attention callable. AR pass uses SDPA-causal directly, gen pass routes through optimized_attention.
+ The AR pass goes through SDPA directand bypasses wrappers, it is only ~1% of T at typical edit sizes.
+ """
+
+ def two_pass_attention(q, k, v, heads, enable_gqa=False, **kwargs):
+ B, H, T, D = q.shape
+
+ if T < k.shape[2]: # KV-cache hot path: Q is shorter than K/V (cached AR prefix is in K/V only), all fresh Q positions are in the gen region, single full-attention call
+ out = optimized_attention(q, k, v, heads, mask=None, skip_reshape=True, skip_output_reshape=True, transformer_options=transformer_options, enable_gqa=enable_gqa)
+ elif ar_len >= T:
+ out = comfy.ops.scaled_dot_product_attention(q, k, v, attn_mask=None, dropout_p=0.0, is_causal=True, enable_gqa=enable_gqa)
+ elif ar_len <= 0:
+ out = optimized_attention(q, k, v, heads, mask=None, skip_reshape=True, skip_output_reshape=True, transformer_options=transformer_options, enable_gqa=enable_gqa)
+ else:
+ out_ar = comfy.ops.scaled_dot_product_attention(
+ q[:, :, :ar_len], k[:, :, :ar_len], v[:, :, :ar_len],
+ attn_mask=None, dropout_p=0.0, is_causal=True, enable_gqa=enable_gqa,
+ )
+ out_gen = optimized_attention(
+ q[:, :, ar_len:], k, v, heads,
+ mask=None, skip_reshape=True, skip_output_reshape=True,
+ transformer_options=transformer_options, enable_gqa=enable_gqa,
+ )
+ out = torch.cat([out_ar, out_gen], dim=2)
+
+ return out.transpose(1, 2).reshape(B, T, H * D)
+
+ return two_pass_attention
diff --git a/ComfyUI/comfy/ldm/hidream_o1/conditioning.py b/ComfyUI/comfy/ldm/hidream_o1/conditioning.py
new file mode 100644
index 0000000000000000000000000000000000000000..7496f00356fdb3cade1151ec4d32efc109b9f43d
--- /dev/null
+++ b/ComfyUI/comfy/ldm/hidream_o1/conditioning.py
@@ -0,0 +1,230 @@
+"""HiDream-O1 conditioning prep — ref-image dual path + extra_conds assembly.
+
+Each ref image goes through two paths: a 32x32 patchified stream concatenated
+to the noised target, and a Qwen3-VL ViT path producing tokens that scatter
+into input_ids at <|image_pad|> positions.
+"""
+
+from typing import List
+
+import torch
+
+import comfy.utils
+from comfy.text_encoders.qwen_vl import process_qwen2vl_images
+
+from .utils import (PATCH_SIZE, calculate_dimensions, cond_image_size, ref_max_size, resize_tensor)
+
+# Qwen3-VL ViT preprocessing constants (preprocessor_config.json).
+VIT_PATCH = 16
+VIT_MERGE = 2
+VIT_IMAGE_MEAN = [0.5, 0.5, 0.5]
+VIT_IMAGE_STD = [0.5, 0.5, 0.5]
+
+
+def prepare_ref_images(
+ ref_images: List[torch.Tensor],
+ target_h: int,
+ target_w: int,
+ device: torch.device,
+ dtype: torch.dtype,
+):
+ """Build the dual-path tensors for K reference images at (target_h, target_w).
+
+ Returns None for K=0, else a dict with ref_patches, ref_pixel_values,
+ ref_image_grid_thw, per_ref_vit_tokens, per_ref_patch_grids.
+ """
+ K = len(ref_images)
+ if K == 0:
+ return None
+ max_size = ref_max_size(max(target_h, target_w), K)
+ cis = cond_image_size(K)
+
+ refs_t = [img[0].clamp(0, 1).permute(2, 0, 1).unsqueeze(0).contiguous().float() for img in ref_images]
+ refs_t = [resize_tensor(t, max_size, PATCH_SIZE) for t in refs_t]
+
+ # 32-patch path.
+ ref_patches_per = []
+ per_ref_patch_grids = []
+ for t in refs_t:
+ t_norm = (t.squeeze(0) - 0.5) / 0.5 # (3, H, W) in [-1, 1]
+ h_p, w_p = t_norm.shape[-2] // PATCH_SIZE, t_norm.shape[-1] // PATCH_SIZE
+ per_ref_patch_grids.append((h_p, w_p))
+ patches = (
+ t_norm.reshape(3, h_p, PATCH_SIZE, w_p, PATCH_SIZE)
+ .permute(1, 3, 0, 2, 4)
+ .reshape(h_p * w_p, 3 * PATCH_SIZE * PATCH_SIZE)
+ )
+ ref_patches_per.append(patches)
+ ref_patches = torch.cat(ref_patches_per, dim=0).unsqueeze(0).to(device=device, dtype=dtype)
+
+ # ViT path.
+ refs_vlm_t = []
+ for t in refs_t:
+ _, _, h, w = t.shape
+ cond_w, cond_h = calculate_dimensions(cis, w / h)
+ cond_w = max(cond_w, VIT_PATCH * VIT_MERGE)
+ cond_h = max(cond_h, VIT_PATCH * VIT_MERGE)
+ refs_vlm_t.append(comfy.utils.common_upscale(t, cond_w, cond_h, "lanczos", "disabled"))
+
+ pv_list, grid_list, per_ref_vit_tokens = [], [], []
+ for t_v in refs_vlm_t:
+ pv, grid_thw = process_qwen2vl_images(
+ t_v.permute(0, 2, 3, 1),
+ min_pixels=0, max_pixels=10**12,
+ patch_size=VIT_PATCH, merge_size=VIT_MERGE,
+ image_mean=VIT_IMAGE_MEAN, image_std=VIT_IMAGE_STD,
+ )
+ grid_thw = grid_thw[0]
+ pv_list.append(pv.to(device=device, dtype=dtype))
+ grid_list.append(grid_thw.to(device=device))
+ # Post-merge token count = number of <|image_pad|> tokens this image expands to in input_ids.
+ gh, gw = int(grid_thw[1].item()), int(grid_thw[2].item())
+ per_ref_vit_tokens.append((gh // VIT_MERGE) * (gw // VIT_MERGE))
+
+ return {
+ "ref_patches": ref_patches,
+ "ref_pixel_values": torch.cat(pv_list, dim=0),
+ "ref_image_grid_thw": torch.stack(grid_list, dim=0),
+ "per_ref_vit_tokens": per_ref_vit_tokens,
+ "per_ref_patch_grids": per_ref_patch_grids,
+ }
+
+
+def build_ref_input_ids(
+ text_input_ids: torch.Tensor,
+ per_ref_vit_tokens: List[int],
+ image_token_id: int,
+ vision_start_id: int,
+ vision_end_id: int,
+):
+ """Splice [vision_start, image_pad*N, vision_end] blocks into input_ids
+ after the [im_start, user, \\n] prefix (matches original chat template).
+ """
+ ids = text_input_ids[0].tolist()
+ inserted = []
+ for n_pad in per_ref_vit_tokens:
+ inserted.extend([vision_start_id] + [image_token_id] * n_pad + [vision_end_id])
+ new_ids = ids[:3] + inserted + ids[3:] # 3 = len([im_start, user, \n])
+ return torch.tensor([new_ids], dtype=text_input_ids.dtype, device=text_input_ids.device)
+
+
+def build_extra_conds(
+ text_input_ids: torch.Tensor,
+ noise: torch.Tensor,
+ ref_images: List[torch.Tensor] = None,
+ target_patch_size: int = 32,
+):
+ """Assemble all conditioning tensors for HiDreamO1Transformer.forward:
+ input_ids (with ref-vision tokens spliced in for the edit/IP path),
+ position_ids (MRoPE), token_types, vinput_mask, plus the ref
+ dual-path tensors when refs are provided.
+ """
+ from .utils import get_rope_index_fix_point
+ from comfy.text_encoders.hidream_o1 import (
+ IMAGE_TOKEN_ID, VISION_START_ID, VISION_END_ID,
+ )
+
+ if text_input_ids.dim() == 1:
+ text_input_ids = text_input_ids.unsqueeze(0)
+ text_input_ids = text_input_ids.long().to(noise.device)
+ B = noise.shape[0]
+ if text_input_ids.shape[0] == 1 and B > 1:
+ text_input_ids = text_input_ids.expand(B, -1)
+
+ H, W = noise.shape[-2], noise.shape[-1]
+ h_p, w_p = H // target_patch_size, W // target_patch_size
+ image_len = h_p * w_p
+ image_grid_thw_tgt = torch.tensor(
+ [[1, h_p, w_p]], dtype=torch.long, device=text_input_ids.device,
+ )
+
+ out = {}
+ if ref_images:
+ ref = prepare_ref_images(ref_images, H, W, device=noise.device, dtype=noise.dtype)
+ text_input_ids = build_ref_input_ids(
+ text_input_ids, ref["per_ref_vit_tokens"],
+ IMAGE_TOKEN_ID, VISION_START_ID, VISION_END_ID,
+ )
+ new_txt_len = text_input_ids.shape[1]
+
+ # Each ref's patchified stream gets a [vision_start, image_pad*N-1]
+ # block in the position-id stream after the noised target.
+ ref_grid_lengths = [hp * wp for (hp, wp) in ref["per_ref_patch_grids"]]
+ tgt_vision = torch.full((1, image_len), IMAGE_TOKEN_ID,
+ dtype=text_input_ids.dtype, device=text_input_ids.device)
+ tgt_vision[:, 0] = VISION_START_ID
+ ref_vision_blocks = []
+ for rl in ref_grid_lengths:
+ blk = torch.full((1, rl), IMAGE_TOKEN_ID,
+ dtype=text_input_ids.dtype, device=text_input_ids.device)
+ blk[:, 0] = VISION_START_ID
+ ref_vision_blocks.append(blk)
+ ref_vision_cat = torch.cat([tgt_vision] + ref_vision_blocks, dim=1)
+ input_ids_pad = torch.cat([text_input_ids, ref_vision_cat], dim=-1)
+ total_ref_patches_len = sum(ref_grid_lengths)
+ total_len = new_txt_len + image_len + total_ref_patches_len
+
+ # K (ViT, post-merge) + 1 (target) + K (ref-patches) image grids.
+ K = len(ref_images)
+ igthw_cond = ref["ref_image_grid_thw"].clone()
+ igthw_cond[:, 1] //= 2
+ igthw_cond[:, 2] //= 2
+ image_grid_thw_ref = torch.tensor(
+ [[1, hp, wp] for (hp, wp) in ref["per_ref_patch_grids"]],
+ dtype=torch.long, device=text_input_ids.device,
+ )
+ igthw_all = torch.cat([
+ igthw_cond.to(text_input_ids.device),
+ image_grid_thw_tgt,
+ image_grid_thw_ref,
+ ], dim=0)
+ position_ids, _ = get_rope_index_fix_point(
+ spatial_merge_size=1,
+ image_token_id=IMAGE_TOKEN_ID,
+ vision_start_token_id=VISION_START_ID,
+ input_ids=input_ids_pad, image_grid_thw=igthw_all,
+ attention_mask=None,
+ skip_vision_start_token=[0] * K + [1] + [1] * K,
+ fix_point=4096,
+ )
+
+ # tms + target_image + ref_patches are all gen.
+ tms_pos = new_txt_len - 1
+ ar_len = tms_pos
+ token_types = torch.zeros(B, total_len, dtype=torch.long, device=noise.device)
+ token_types[:, tms_pos:] = 1
+ vinput_mask = torch.zeros(B, total_len, dtype=torch.bool, device=noise.device)
+ vinput_mask[:, new_txt_len:] = True
+
+ # Leading batch dim sidesteps CONDRegular.process_cond's repeat_to_batch_size truncation
+ out["ref_pixel_values"] = ref["ref_pixel_values"].unsqueeze(0)
+ out["ref_image_grid_thw"] = ref["ref_image_grid_thw"].unsqueeze(0)
+ out["ref_patches"] = ref["ref_patches"]
+ else:
+ # T2I: text + noised target only, vision_start replaces the first image token
+ txt_len = text_input_ids.shape[1]
+ total_len = txt_len + image_len
+ vision_tokens = torch.full((B, image_len), IMAGE_TOKEN_ID,
+ dtype=text_input_ids.dtype, device=text_input_ids.device)
+ vision_tokens[:, 0] = VISION_START_ID
+ input_ids_pad = torch.cat([text_input_ids, vision_tokens], dim=-1)
+ position_ids, _ = get_rope_index_fix_point(
+ spatial_merge_size=1,
+ image_token_id=IMAGE_TOKEN_ID,
+ vision_start_token_id=VISION_START_ID,
+ input_ids=input_ids_pad, image_grid_thw=image_grid_thw_tgt,
+ attention_mask=None,
+ skip_vision_start_token=[1],
+ )
+ ar_len = txt_len - 1
+ token_types = torch.zeros(B, total_len, dtype=torch.long, device=noise.device)
+ token_types[:, ar_len:] = 1
+ vinput_mask = torch.zeros(B, total_len, dtype=torch.bool, device=noise.device)
+ vinput_mask[:, txt_len:] = True
+
+ out["input_ids"] = text_input_ids
+ out["position_ids"] = position_ids[:, 0].unsqueeze(0) # Collapse position_ids batch and add a leading dim so CONDRegular's batch-resize doesn't truncate the 3-axis MRoPE dim
+ out["token_types"] = token_types
+ out["vinput_mask"] = vinput_mask
+ out["ar_len"] = ar_len
+ return out
diff --git a/ComfyUI/comfy/ldm/hidream_o1/model.py b/ComfyUI/comfy/ldm/hidream_o1/model.py
new file mode 100644
index 0000000000000000000000000000000000000000..a223e706fa455d22b1b12d933c5e88baae0e2d92
--- /dev/null
+++ b/ComfyUI/comfy/ldm/hidream_o1/model.py
@@ -0,0 +1,306 @@
+"""HiDream-O1-Image transformer.
+
+Pixel-space DiT built on Qwen3-VL: the vision tower (Qwen35VisionModel)
+encodes ref images, the Qwen3-VL-8B decoder (Llama2_ with interleaved MRoPE)
+processes a unified text+image sequence, and 32x32 patch embed/unembed
+shims map raw RGB in and out of LLM hidden space. The Qwen3-VL deepstack
+mergers go unused — their weights are dropped at load.
+"""
+
+from dataclasses import dataclass, field
+from typing import List, Optional
+
+import einops
+import torch
+import torch.nn as nn
+
+import comfy.patcher_extension
+from comfy.ldm.modules.diffusionmodules.mmdit import TimestepEmbedder
+from comfy.text_encoders.llama import Llama2_
+from comfy.text_encoders.qwen35 import Qwen35VisionModel
+
+from .attention import make_two_pass_attention
+
+
+IMAGE_TOKEN_ID = 151655 # Qwen3-VL <|image_pad|>
+TMS_TOKEN_ID = 151673 # HiDream-O1 <|tms_token|>
+PATCH_SIZE = 32
+
+
+@dataclass
+class HiDreamO1TextConfig:
+ """Qwen3-VL-8B text-decoder dims (matches public Qwen3-VL-8B-Instruct)."""
+ vocab_size: int = 151936
+ hidden_size: int = 4096
+ intermediate_size: int = 12288
+ num_hidden_layers: int = 36
+ num_attention_heads: int = 32
+ num_key_value_heads: int = 8
+ head_dim: int = 128
+ max_position_embeddings: int = 128000
+ rms_norm_eps: float = 1e-6
+ rope_theta: float = 5000000.0
+ rope_scale: Optional[float] = None
+ rope_dims: List[int] = field(default_factory=lambda: [24, 20, 20])
+ interleaved_mrope: bool = True
+ transformer_type: str = "llama"
+ rms_norm_add: bool = False
+ mlp_activation: str = "silu"
+ qkv_bias: bool = False
+ q_norm: str = "gemma3"
+ k_norm: str = "gemma3"
+ final_norm: bool = True
+ lm_head: bool = False
+ stop_tokens: List[int] = field(default_factory=lambda: [151643, 151645])
+
+
+QWEN3VL_VISION_DEFAULTS = dict(
+ hidden_size=1152,
+ num_heads=16,
+ intermediate_size=4304,
+ depth=27,
+ patch_size=16,
+ temporal_patch_size=2,
+ in_channels=3,
+ spatial_merge_size=2,
+ num_position_embeddings=2304,
+ deepstack_visual_indexes=(8, 16, 24),
+ out_hidden_size=4096, # final merger projects directly into LLM hidden
+)
+
+
+class BottleneckPatchEmbed(nn.Module):
+ # 3072 -> 1024 -> 4096 (raw 32x32 RGB patch -> bottleneck -> LLM hidden).
+ def __init__(self, patch_size=32, in_chans=3, pca_dim=1024, embed_dim=4096, bias=True, device=None, dtype=None, ops=None):
+ super().__init__()
+ self.proj1 = ops.Linear(patch_size * patch_size * in_chans, pca_dim, bias=False, device=device, dtype=dtype)
+ self.proj2 = ops.Linear(pca_dim, embed_dim, bias=bias, device=device, dtype=dtype)
+
+ def forward(self, x):
+ return self.proj2(self.proj1(x))
+
+
+class FinalLayer(nn.Module):
+ # 4096 -> 3072 (LLM hidden -> flat pixel patch).
+ def __init__(self, hidden_size, patch_size=32, out_channels=3, device=None, dtype=None, ops=None):
+ super().__init__()
+ self.linear = ops.Linear(hidden_size, patch_size * patch_size * out_channels, bias=True, device=device, dtype=dtype)
+
+ def forward(self, x):
+ return self.linear(x)
+
+
+class HiDreamO1Transformer(nn.Module):
+ """HiDream-O1 unified pixel-level transformer."""
+
+ def __init__(self, image_model=None, dtype=None, device=None, operations=None,
+ text_config_overrides=None, vision_config_overrides=None, **kwargs):
+ super().__init__()
+ self.dtype = dtype
+
+ text_cfg = HiDreamO1TextConfig(**(text_config_overrides or {}))
+ vision_cfg = dict(QWEN3VL_VISION_DEFAULTS)
+ if vision_config_overrides:
+ vision_cfg.update(vision_config_overrides)
+ vision_cfg["out_hidden_size"] = text_cfg.hidden_size
+
+ self.text_config = text_cfg
+ self.vision_config = vision_cfg
+ self.hidden_size = text_cfg.hidden_size
+ self.patch_size = PATCH_SIZE
+ self.in_channels = 3
+ self.tms_token_id = TMS_TOKEN_ID
+
+ self.visual = Qwen35VisionModel(vision_cfg, device=device, dtype=dtype, ops=operations)
+ self.language_model = Llama2_(text_cfg, device=device, dtype=dtype, ops=operations)
+ self.t_embedder1 = TimestepEmbedder(
+ text_cfg.hidden_size, device=device, dtype=dtype, operations=operations,
+ )
+ self.x_embedder = BottleneckPatchEmbed(
+ patch_size=self.patch_size, in_chans=self.in_channels,
+ pca_dim=text_cfg.hidden_size // 4, embed_dim=text_cfg.hidden_size,
+ bias=True, device=device, dtype=dtype, ops=operations,
+ )
+ self.final_layer2 = FinalLayer(
+ text_cfg.hidden_size, patch_size=self.patch_size,
+ out_channels=self.in_channels, device=device, dtype=dtype, ops=operations,
+ )
+
+ self._visual_cache = None
+ self._kv_cache_entries = []
+
+ def clear_kv_cache(self):
+ self._kv_cache_entries = []
+ self._visual_cache = None
+
+ def forward(self, x, timesteps, context=None, transformer_options={}, **kwargs):
+ return comfy.patcher_extension.WrapperExecutor.new_class_executor(
+ self._forward,
+ self,
+ comfy.patcher_extension.get_all_wrappers(comfy.patcher_extension.WrappersMP.DIFFUSION_MODEL, transformer_options)
+ ).execute(x, timesteps, context, transformer_options, **kwargs)
+
+ def _forward(self, x, timesteps, context=None, transformer_options={}, input_ids=None, attention_mask=None, position_ids=None,
+ vinput_mask=None, ar_len=None, ref_pixel_values=None, ref_image_grid_thw=None, ref_patches=None, **kwargs):
+ """Returns flow-match velocity (x - x_pred) / sigma"""
+
+ if input_ids is None or position_ids is None:
+ raise ValueError("HiDreamO1Transformer requires input_ids and position_ids in conditioning")
+
+ B, _, H, W = x.shape
+ h_p, w_p = H // self.patch_size, W // self.patch_size
+ tgt_image_len = h_p * w_p
+
+ z = einops.rearrange(
+ x, 'B C (H p1) (W p2) -> B (H W) (C p1 p2)',
+ p1=self.patch_size, p2=self.patch_size,
+ )
+ vinputs = torch.cat([z, ref_patches.to(z.dtype)], dim=1) if ref_patches is not None else z
+
+ inputs_embeds = self.language_model.embed_tokens(input_ids).to(x.dtype)
+
+ if ref_pixel_values is not None and ref_image_grid_thw is not None:
+ # ViT output is constant across sampling steps within a generation
+ # identity-key by the input tensor so refs don't recompute every step.
+ cached = self._visual_cache
+ if cached is not None and cached[0] is ref_pixel_values:
+ image_embeds = cached[1]
+ else:
+ ref_pv = ref_pixel_values.to(inputs_embeds.device)
+ ref_grid = ref_image_grid_thw.to(inputs_embeds.device).long()
+ # extra_conds wraps with a leading batch dim; refs are model-level so [0] always recovers them.
+ if ref_pv.dim() == 3:
+ ref_pv = ref_pv[0]
+ if ref_grid.dim() == 3:
+ ref_grid = ref_grid[0]
+ image_embeds = self.visual(ref_pv, ref_grid).to(inputs_embeds.dtype)
+ self._visual_cache = (ref_pixel_values, image_embeds)
+ # image_pad positions identical across batch (input_ids shared cond/uncond).
+ image_idx = (input_ids[0] == IMAGE_TOKEN_ID).nonzero(as_tuple=True)[0]
+ if image_idx.shape[0] != image_embeds.shape[0]:
+ raise ValueError(
+ f"Image-token count {image_idx.shape[0]} != ViT output count "
+ f"{image_embeds.shape[0]}; check tokenizer/processor alignment."
+ )
+ inputs_embeds[:, image_idx] = image_embeds.unsqueeze(0).expand(B, -1, -1)
+
+ sigma = timesteps.float() / 1000.0
+ t_pixeldit = 1.0 - sigma
+ t_emb = self.t_embedder1(t_pixeldit * 1000, inputs_embeds.dtype)
+ tms_mask_3d = (input_ids == self.tms_token_id).unsqueeze(-1).expand_as(inputs_embeds)
+ inputs_embeds = torch.where(tms_mask_3d, t_emb.unsqueeze(1).expand_as(inputs_embeds), inputs_embeds)
+
+ vinputs_embedded = self.x_embedder(vinputs.to(inputs_embeds.dtype))
+ inputs_embeds = torch.cat([inputs_embeds, vinputs_embedded], dim=1)
+
+ # extra_conds stores position_ids as (1, 3, T); process_cond repeats dim 0 to B. Take row 0.
+ freqs_cis = self.language_model.compute_freqs_cis(position_ids[0].to(x.device), x.device)
+ freqs_cis = tuple(t.to(x.dtype) for t in freqs_cis)
+
+ two_pass_attn = make_two_pass_attention(ar_len, transformer_options=transformer_options)
+ patches_replace = transformer_options.get("patches_replace", {})
+ blocks_replace = patches_replace.get("dit", {})
+ transformer_options["total_blocks"] = len(self.language_model.layers)
+ transformer_options["block_type"] = "double"
+
+ # Cache prefix K/V across steps. Key includes input_ids (prompt), ref_id
+ # (refs scatter into inputs_embeds), and position_ids (RoPE baked into cached K).
+ can_cache = not blocks_replace and ar_len > 0
+ cache_len = ar_len if can_cache else 0
+ ref_id = id(ref_pixel_values) if ref_pixel_values is not None else None
+ pos_ids_key = position_ids[..., :cache_len] if can_cache else position_ids
+ cache_entries = self._kv_cache_entries
+ # Drop stale entries from a previous device (model was unloaded and reloaded).
+ if cache_entries and cache_entries[0]["input_ids"].device != input_ids.device:
+ cache_entries = []
+ self._kv_cache_entries = []
+ kv_cache = None
+ if can_cache:
+ for entry in cache_entries:
+ ck = entry["input_ids"]
+ ep = entry["position_ids"]
+ if (entry["cache_len"] == cache_len
+ and ck.shape == input_ids.shape and torch.equal(ck, input_ids)
+ and entry["ref_id"] == ref_id
+ and ep.shape == pos_ids_key.shape and torch.equal(ep, pos_ids_key)):
+ kv_cache = entry
+ break
+
+ if kv_cache is not None:
+ # Hot path: project Q/K/V only for fresh positions; past_key_value prepends cached AR K/V.
+ hidden_states = inputs_embeds[:, cache_len:]
+ sliced_freqs = tuple(t[..., cache_len:, :] for t in freqs_cis)
+ for i, layer in enumerate(self.language_model.layers):
+ transformer_options["block_index"] = i
+ K_i, V_i = kv_cache["kv"][i]
+ hidden_states, _ = layer(
+ x=hidden_states, attention_mask=None, freqs_cis=sliced_freqs, optimized_attention=two_pass_attn,
+ past_key_value=(K_i, V_i, cache_len),
+ )
+ else:
+ # Cold path: run full sequence; if cacheable, snapshot K/V at AR positions.
+ snapshots = [] if can_cache else None
+ past_kv_cold = () if can_cache else None
+ hidden_states = inputs_embeds
+ for i, layer in enumerate(self.language_model.layers):
+ transformer_options["block_index"] = i
+ if ("double_block", i) in blocks_replace:
+ def block_wrap(args, _layer=layer):
+ out = {}
+ out["x"], _ = _layer(
+ x=args["x"], attention_mask=args.get("attention_mask"),
+ freqs_cis=args["freqs_cis"], optimized_attention=args["optimized_attention"],
+ past_key_value=None,
+ )
+ return out
+ out = blocks_replace[("double_block", i)](
+ {"x": hidden_states, "attention_mask": None,
+ "freqs_cis": freqs_cis, "optimized_attention": two_pass_attn,
+ "transformer_options": transformer_options},
+ {"original_block": block_wrap},
+ )
+ hidden_states = out["x"]
+ else:
+ hidden_states, present_kv = layer(
+ x=hidden_states, attention_mask=None,
+ freqs_cis=freqs_cis, optimized_attention=two_pass_attn,
+ past_key_value=past_kv_cold,
+ )
+ if snapshots is not None:
+ K, V, _ = present_kv
+ snapshots.append((K[:, :, :cache_len].contiguous(),
+ V[:, :, :cache_len].contiguous()))
+ if snapshots is not None:
+ # Cap at 2 entries (cond + uncond). Multi-cond workflows LRU-evict.
+ new_entry = {
+ "input_ids": input_ids.clone(),
+ "cache_len": cache_len,
+ "kv": snapshots,
+ "ref_id": ref_id,
+ "position_ids": pos_ids_key.clone(),
+ }
+ self._kv_cache_entries = (cache_entries + [new_entry])[-2:]
+
+ if self.language_model.norm is not None:
+ hidden_states = self.language_model.norm(hidden_states)
+
+ # Slice target-image positions before the final projection so the Linear only runs on tgt_image_len tokens.
+ # In the hot path hidden_states starts at original position cache_len, so masks/indices shift by cache_len.
+ sliced_offset = cache_len if kv_cache is not None else 0
+ if vinput_mask is not None:
+ vmask = vinput_mask.to(x.device).bool()
+ if sliced_offset > 0:
+ vmask = vmask[:, sliced_offset:]
+ target_hidden = hidden_states[vmask].view(B, -1, hidden_states.shape[-1])[:, :tgt_image_len]
+ else:
+ txt_seq_len = input_ids.shape[1]
+ start = txt_seq_len - sliced_offset
+ target_hidden = hidden_states[:, start:start + tgt_image_len]
+ x_pred_tgt = self.final_layer2(target_hidden)
+
+ # fp32 final subtraction, bf16 here noticeably degrades samples.
+ x_pred_img = einops.rearrange(
+ x_pred_tgt, 'B (H W) (C p1 p2) -> B C (H p1) (W p2)',
+ H=h_p, W=w_p, p1=self.patch_size, p2=self.patch_size,
+ )
+ return (x.float() - x_pred_img.float()) / sigma.view(B, 1, 1, 1).clamp_min(1e-3)
diff --git a/ComfyUI/comfy/ldm/hidream_o1/utils.py b/ComfyUI/comfy/ldm/hidream_o1/utils.py
new file mode 100644
index 0000000000000000000000000000000000000000..5a1249c7254956e6e8491abdf3144b73900b0726
--- /dev/null
+++ b/ComfyUI/comfy/ldm/hidream_o1/utils.py
@@ -0,0 +1,173 @@
+"""HiDream-O1 input-prep helpers: image/resolution math and unified-sequence
+RoPE position-id assembly. The fix_point offset in get_rope_index_fix_point
+lets the target image and patchified ref images share spatial RoPE positions
+despite living at different sequence indices — same 2D image plane.
+"""
+
+import math
+from typing import Optional
+
+import torch
+
+
+PATCH_SIZE = 32
+CONDITION_IMAGE_SIZE = 384 # ViT-side base size for ref images
+
+
+def resize_tensor(img_t, image_size, patch_size=16):
+ """img_t: (1, 3, H, W) float [0, 1]. Fit to image_size**2 area, patch-aligned, center-cropped."""
+
+ while min(img_t.shape[-2], img_t.shape[-1]) >= 2 * image_size: # Pre-halves with 2x2 box averaging while the image is still very large
+ img_t = torch.nn.functional.avg_pool2d(img_t, kernel_size=2, stride=2)
+
+ _, _, height, width = img_t.shape
+ m = patch_size
+ s_max = image_size * image_size
+ scale = math.sqrt(s_max / (width * height))
+
+ candidates = [
+ (round(width * scale) // m * m, round(height * scale) // m * m),
+ (round(width * scale) // m * m, math.floor(height * scale) // m * m),
+ (math.floor(width * scale) // m * m, round(height * scale) // m * m),
+ (math.floor(width * scale) // m * m, math.floor(height * scale) // m * m),
+ ]
+ candidates = sorted(candidates, key=lambda x: x[0] * x[1], reverse=True)
+ new_size = candidates[-1]
+ for c in candidates:
+ if c[0] * c[1] <= s_max:
+ new_size = c
+ break
+
+ new_w, new_h = new_size
+ s1 = width / new_w
+ s2 = height / new_h
+ if s1 < s2:
+ resize_w, resize_h = new_w, round(height / s1)
+ else:
+ resize_w, resize_h = round(width / s2), new_h
+ img_t = torch.nn.functional.interpolate(img_t, size=(resize_h, resize_w), mode="bicubic")
+ top = (resize_h - new_h) // 2
+ left = (resize_w - new_w) // 2
+ return img_t[..., top:top + new_h, left:left + new_w]
+
+
+def calculate_dimensions(max_size, ratio):
+ """(W, H) for an aspect ratio fitting in max_size**2 area, 32-aligned."""
+ width = math.sqrt(max_size * max_size * ratio)
+ height = width / ratio
+ width = int(width / 32) * 32
+ height = int(height / 32) * 32
+ return width, height
+
+
+def ref_max_size(target_max_dim, k):
+ """K-dependent ref-image max dim before patchifying."""
+ if k == 1:
+ return target_max_dim
+ if k == 2:
+ return target_max_dim * 48 // 64
+ if k <= 4:
+ return target_max_dim // 2
+ if k <= 8:
+ return target_max_dim * 24 // 64
+ return target_max_dim // 4
+
+
+def cond_image_size(k):
+ """K-dependent ViT-side image size."""
+ if k <= 4:
+ return CONDITION_IMAGE_SIZE
+ if k <= 8:
+ return CONDITION_IMAGE_SIZE * 48 // 64
+ return CONDITION_IMAGE_SIZE // 2
+
+
+def get_rope_index_fix_point(
+ spatial_merge_size: int,
+ image_token_id: int,
+ vision_start_token_id: int,
+ input_ids: Optional[torch.LongTensor] = None,
+ image_grid_thw: Optional[torch.LongTensor] = None,
+ attention_mask: Optional[torch.Tensor] = None,
+ skip_vision_start_token=None,
+ fix_point: int = 4096,
+):
+ mrope_position_deltas = []
+ if input_ids is not None and image_grid_thw is not None:
+ total_input_ids = input_ids
+ if attention_mask is None:
+ attention_mask = torch.ones_like(total_input_ids)
+ position_ids = torch.ones(
+ 3, input_ids.shape[0], input_ids.shape[1],
+ dtype=input_ids.dtype, device=input_ids.device,
+ )
+ attention_mask = attention_mask.to(total_input_ids.device)
+ for i, input_ids_b in enumerate(total_input_ids):
+ fp = fix_point
+ image_index = 0
+ input_ids_b = input_ids_b[attention_mask[i] == 1]
+ vision_start_indices = torch.argwhere(input_ids_b == vision_start_token_id).squeeze(1)
+ vision_tokens = input_ids_b[vision_start_indices + 1]
+ image_nums = (vision_tokens == image_token_id).sum()
+ input_tokens = input_ids_b.tolist()
+ llm_pos_ids_list = []
+ st = 0
+ remain_images = image_nums
+ for _ in range(image_nums):
+ if image_token_id in input_tokens and remain_images > 0:
+ ed = input_tokens.index(image_token_id, st)
+ else:
+ ed = len(input_tokens) + 1
+ t = image_grid_thw[image_index][0]
+ h = image_grid_thw[image_index][1]
+ w = image_grid_thw[image_index][2]
+ image_index += 1
+ remain_images -= 1
+ llm_grid_t = t.item()
+ llm_grid_h = h.item() // spatial_merge_size
+ llm_grid_w = w.item() // spatial_merge_size
+ text_len = ed - st
+ text_len -= skip_vision_start_token[image_index - 1]
+ text_len = max(0, text_len)
+ st_idx = llm_pos_ids_list[-1].max() + 1 if len(llm_pos_ids_list) > 0 else 0
+ llm_pos_ids_list.append(torch.arange(text_len).view(1, -1).expand(3, -1) + st_idx)
+
+ t_index = torch.arange(llm_grid_t).view(-1, 1).expand(-1, llm_grid_h * llm_grid_w).flatten()
+ h_index = torch.arange(llm_grid_h).view(1, -1, 1).expand(llm_grid_t, -1, llm_grid_w).flatten()
+ w_index = torch.arange(llm_grid_w).view(1, 1, -1).expand(llm_grid_t, llm_grid_h, -1).flatten()
+
+ if skip_vision_start_token[image_index - 1]:
+ if fp > 0:
+ fp = fp - st_idx
+ llm_pos_ids_list.append(torch.stack([t_index, h_index, w_index]) + fp + st_idx)
+ fp = 0
+ else:
+ llm_pos_ids_list.append(torch.stack([t_index, h_index, w_index]) + text_len + st_idx)
+ st = ed + llm_grid_t * llm_grid_h * llm_grid_w
+
+ if st < len(input_tokens):
+ st_idx = llm_pos_ids_list[-1].max() + 1 if len(llm_pos_ids_list) > 0 else 0
+ text_len = len(input_tokens) - st
+ llm_pos_ids_list.append(torch.arange(text_len).view(1, -1).expand(3, -1) + st_idx)
+
+ llm_positions = torch.cat(llm_pos_ids_list, dim=1).reshape(3, -1)
+ position_ids[..., i, attention_mask[i] == 1] = llm_positions.to(position_ids.device)
+ mrope_position_deltas.append(llm_positions.max() + 1 - len(total_input_ids[i]))
+ mrope_position_deltas = torch.tensor(mrope_position_deltas, device=input_ids.device).unsqueeze(1)
+ return position_ids, mrope_position_deltas
+
+ if attention_mask is not None:
+ position_ids = attention_mask.long().cumsum(-1) - 1
+ position_ids.masked_fill_(attention_mask == 0, 1)
+ position_ids = position_ids.unsqueeze(0).expand(3, -1, -1).to(attention_mask.device)
+ max_position_ids = position_ids.max(0, keepdim=False)[0].max(-1, keepdim=True)[0]
+ mrope_position_deltas = max_position_ids + 1 - attention_mask.shape[-1]
+ else:
+ position_ids = (
+ torch.arange(input_ids.shape[1], device=input_ids.device)
+ .view(1, 1, -1).expand(3, input_ids.shape[0], -1)
+ )
+ mrope_position_deltas = torch.zeros(
+ [input_ids.shape[0], 1], device=input_ids.device, dtype=input_ids.dtype,
+ )
+ return position_ids, mrope_position_deltas
diff --git a/ComfyUI/comfy/ldm/hunyuan3d/__pycache__/model.cpython-312.pyc b/ComfyUI/comfy/ldm/hunyuan3d/__pycache__/model.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..c65133dff62b9df53ea7856b87079aa7024fce9f
Binary files /dev/null and b/ComfyUI/comfy/ldm/hunyuan3d/__pycache__/model.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/hunyuan3d/__pycache__/vae.cpython-312.pyc b/ComfyUI/comfy/ldm/hunyuan3d/__pycache__/vae.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..10f3ec9b88c5a385215514834091805eaef80cff
Binary files /dev/null and b/ComfyUI/comfy/ldm/hunyuan3d/__pycache__/vae.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/hunyuan3d/model.py b/ComfyUI/comfy/ldm/hunyuan3d/model.py
new file mode 100644
index 0000000000000000000000000000000000000000..4991b164531e1b095f748f2aa5cdb06a59542fc2
--- /dev/null
+++ b/ComfyUI/comfy/ldm/hunyuan3d/model.py
@@ -0,0 +1,148 @@
+import torch
+from torch import nn
+from comfy.ldm.flux.layers import (
+ DoubleStreamBlock,
+ LastLayer,
+ MLPEmbedder,
+ SingleStreamBlock,
+ timestep_embedding,
+)
+import comfy.patcher_extension
+
+
+class Hunyuan3Dv2(nn.Module):
+ def __init__(
+ self,
+ in_channels=64,
+ context_in_dim=1536,
+ hidden_size=1024,
+ mlp_ratio=4.0,
+ num_heads=16,
+ depth=16,
+ depth_single_blocks=32,
+ qkv_bias=True,
+ guidance_embed=False,
+ image_model=None,
+ dtype=None,
+ device=None,
+ operations=None
+ ):
+ super().__init__()
+ self.dtype = dtype
+
+ if hidden_size % num_heads != 0:
+ raise ValueError(
+ f"Hidden size {hidden_size} must be divisible by num_heads {num_heads}"
+ )
+
+ self.max_period = 1000 # While reimplementing the model I noticed that they messed up. This 1000 value was meant to be the time_factor but they set the max_period instead
+ self.latent_in = operations.Linear(in_channels, hidden_size, bias=True, dtype=dtype, device=device)
+ self.time_in = MLPEmbedder(in_dim=256, hidden_dim=hidden_size, dtype=dtype, device=device, operations=operations)
+ self.guidance_in = (
+ MLPEmbedder(in_dim=256, hidden_dim=hidden_size, dtype=dtype, device=device, operations=operations) if guidance_embed else None
+ )
+ self.cond_in = operations.Linear(context_in_dim, hidden_size, dtype=dtype, device=device)
+ self.double_blocks = nn.ModuleList(
+ [
+ DoubleStreamBlock(
+ hidden_size,
+ num_heads,
+ mlp_ratio=mlp_ratio,
+ qkv_bias=qkv_bias,
+ dtype=dtype, device=device, operations=operations
+ )
+ for _ in range(depth)
+ ]
+ )
+ self.single_blocks = nn.ModuleList(
+ [
+ SingleStreamBlock(
+ hidden_size,
+ num_heads,
+ mlp_ratio=mlp_ratio,
+ dtype=dtype, device=device, operations=operations
+ )
+ for _ in range(depth_single_blocks)
+ ]
+ )
+ self.final_layer = LastLayer(hidden_size, 1, in_channels, dtype=dtype, device=device, operations=operations)
+
+ def forward(self, x, timestep, context, guidance=None, transformer_options={}, **kwargs):
+ return comfy.patcher_extension.WrapperExecutor.new_class_executor(
+ self._forward,
+ self,
+ comfy.patcher_extension.get_all_wrappers(comfy.patcher_extension.WrappersMP.DIFFUSION_MODEL, transformer_options)
+ ).execute(x, timestep, context, guidance, transformer_options, **kwargs)
+
+ def _forward(self, x, timestep, context, guidance=None, transformer_options={}, **kwargs):
+ x = x.movedim(-1, -2)
+ timestep = 1.0 - timestep
+ txt = context
+ img = self.latent_in(x)
+
+ vec = self.time_in(timestep_embedding(timestep, 256, self.max_period).to(dtype=img.dtype))
+ if self.guidance_in is not None:
+ if guidance is not None:
+ vec = vec + self.guidance_in(timestep_embedding(guidance, 256, self.max_period).to(img.dtype))
+
+ txt = self.cond_in(txt)
+ pe = None
+ attn_mask = None
+
+ patches_replace = transformer_options.get("patches_replace", {})
+ blocks_replace = patches_replace.get("dit", {})
+ for i, block in enumerate(self.double_blocks):
+ if ("double_block", i) in blocks_replace:
+ def block_wrap(args):
+ out = {}
+ out["img"], out["txt"] = block(img=args["img"],
+ txt=args["txt"],
+ vec=args["vec"],
+ pe=args["pe"],
+ attn_mask=args.get("attn_mask"),
+ transformer_options=args["transformer_options"])
+ return out
+
+ out = blocks_replace[("double_block", i)]({"img": img,
+ "txt": txt,
+ "vec": vec,
+ "pe": pe,
+ "attn_mask": attn_mask,
+ "transformer_options": transformer_options},
+ {"original_block": block_wrap})
+ txt = out["txt"]
+ img = out["img"]
+ else:
+ img, txt = block(img=img,
+ txt=txt,
+ vec=vec,
+ pe=pe,
+ attn_mask=attn_mask,
+ transformer_options=transformer_options)
+
+ img = torch.cat((txt, img), 1)
+
+ for i, block in enumerate(self.single_blocks):
+ if ("single_block", i) in blocks_replace:
+ def block_wrap(args):
+ out = {}
+ out["img"] = block(args["img"],
+ vec=args["vec"],
+ pe=args["pe"],
+ attn_mask=args.get("attn_mask"),
+ transformer_options=args["transformer_options"])
+ return out
+
+ out = blocks_replace[("single_block", i)]({"img": img,
+ "vec": vec,
+ "pe": pe,
+ "attn_mask": attn_mask,
+ "transformer_options": transformer_options},
+ {"original_block": block_wrap})
+ img = out["img"]
+ else:
+ img = block(img, vec=vec, pe=pe, attn_mask=attn_mask, transformer_options=transformer_options)
+
+ img = img[:, txt.shape[1]:, ...]
+ img = self.final_layer(img, vec)
+ return img.movedim(-2, -1) * (-1.0)
diff --git a/ComfyUI/comfy/ldm/hunyuan3d/vae.py b/ComfyUI/comfy/ldm/hunyuan3d/vae.py
new file mode 100644
index 0000000000000000000000000000000000000000..76094482700f8b2fbd8379323640b4ed7fe0a01a
--- /dev/null
+++ b/ComfyUI/comfy/ldm/hunyuan3d/vae.py
@@ -0,0 +1,988 @@
+# Original: https://github.com/Tencent/Hunyuan3D-2/blob/main/hy3dgen/shapegen/models/autoencoders/model.py
+# Since the header on their VAE source file was a bit confusing we asked for permission to use this code from tencent under the GPL license used in ComfyUI.
+
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+import numpy as np
+import math
+from tqdm import tqdm
+
+from typing import Optional
+
+import logging
+
+import comfy.ops
+ops = comfy.ops.disable_weight_init
+
+def fps(src: torch.Tensor, batch: torch.Tensor, sampling_ratio: float, start_random: bool = True):
+
+ # manually create the pointer vector
+ assert src.size(0) == batch.numel()
+
+ batch_size = int(batch.max()) + 1
+ deg = src.new_zeros(batch_size, dtype = torch.long)
+
+ deg.scatter_add_(0, batch, torch.ones_like(batch))
+
+ ptr_vec = deg.new_zeros(batch_size + 1)
+ torch.cumsum(deg, 0, out=ptr_vec[1:])
+
+ #return fps_sampling(src, ptr_vec, ratio)
+ sampled_indicies = []
+
+ for b in range(batch_size):
+ # start and the end of each batch
+ start, end = ptr_vec[b].item(), ptr_vec[b + 1].item()
+ # points from the point cloud
+ points = src[start:end]
+
+ num_points = points.size(0)
+ num_samples = max(1, math.ceil(num_points * sampling_ratio))
+
+ selected = torch.zeros(num_samples, device = src.device, dtype = torch.long)
+ distances = torch.full((num_points,), float("inf"), device = src.device)
+
+ # select a random start point
+ if start_random:
+ farthest = torch.randint(0, num_points, (1,), device = src.device)
+ else:
+ farthest = torch.tensor([0], device = src.device, dtype = torch.long)
+
+ for i in range(num_samples):
+ selected[i] = farthest
+ centroid = points[farthest].squeeze(0)
+ dist = torch.norm(points - centroid, dim = 1) # compute euclidean distance
+ distances = torch.minimum(distances, dist)
+ farthest = torch.argmax(distances)
+
+ sampled_indicies.append(torch.arange(start, end)[selected])
+
+ return torch.cat(sampled_indicies, dim = 0)
+class PointCrossAttention(nn.Module):
+ def __init__(self,
+ num_latents: int,
+ downsample_ratio: float,
+ pc_size: int,
+ pc_sharpedge_size: int,
+ point_feats: int,
+ width: int,
+ heads: int,
+ layers: int,
+ fourier_embedder,
+ normal_pe: bool = False,
+ qkv_bias: bool = False,
+ use_ln_post: bool = True,
+ qk_norm: bool = True):
+
+ super().__init__()
+
+ self.fourier_embedder = fourier_embedder
+
+ self.pc_size = pc_size
+ self.normal_pe = normal_pe
+ self.downsample_ratio = downsample_ratio
+ self.pc_sharpedge_size = pc_sharpedge_size
+ self.num_latents = num_latents
+ self.point_feats = point_feats
+
+ self.input_proj = nn.Linear(self.fourier_embedder.out_dim + point_feats, width)
+
+ self.cross_attn = ResidualCrossAttentionBlock(
+ width = width,
+ heads = heads,
+ qkv_bias = qkv_bias,
+ qk_norm = qk_norm
+ )
+
+ self.self_attn = None
+ if layers > 0:
+ self.self_attn = Transformer(
+ width = width,
+ heads = heads,
+ qkv_bias = qkv_bias,
+ qk_norm = qk_norm,
+ layers = layers
+ )
+
+ if use_ln_post:
+ self.ln_post = nn.LayerNorm(width)
+ else:
+ self.ln_post = None
+
+ def sample_points_and_latents(self, point_cloud: torch.Tensor, features: torch.Tensor):
+
+ """
+ Subsample points randomly from the point cloud (input_pc)
+ Further sample the subsampled points to get query_pc
+ take the fourier embeddings for both input and query pc
+
+ Mental Note: FPS-sampled points (query_pc) act as latent tokens that attend to and learn from the broader context in input_pc.
+ Goal: get a smaller represenation (query_pc) to represent the entire scence structure by learning from a broader subset (input_pc).
+ More computationally efficient.
+
+ Features are additional information for each point in the cloud
+ """
+
+ B, _, D = point_cloud.shape
+
+ num_latents = int(self.num_latents)
+
+ num_random_query = self.pc_size / (self.pc_size + self.pc_sharpedge_size) * num_latents
+ num_sharpedge_query = num_latents - num_random_query
+
+ # Split random and sharpedge surface points
+ random_pc, sharpedge_pc = torch.split(point_cloud, [self.pc_size, self.pc_sharpedge_size], dim=1)
+
+ # assert statements
+ assert random_pc.shape[1] <= self.pc_size, "Random surface points size must be less than or equal to pc_size"
+ assert sharpedge_pc.shape[1] <= self.pc_sharpedge_size, "Sharpedge surface points size must be less than or equal to pc_sharpedge_size"
+
+ input_random_pc_size = int(num_random_query * self.downsample_ratio)
+ random_query_pc, random_input_pc, random_idx_pc, random_idx_query = \
+ self.subsample(pc = random_pc, num_query = num_random_query, input_pc_size = input_random_pc_size)
+
+ input_sharpedge_pc_size = int(num_sharpedge_query * self.downsample_ratio)
+
+ if input_sharpedge_pc_size == 0:
+ sharpedge_input_pc = torch.zeros(B, 0, D, dtype = random_input_pc.dtype).to(point_cloud.device)
+ sharpedge_query_pc = torch.zeros(B, 0, D, dtype= random_query_pc.dtype).to(point_cloud.device)
+
+ else:
+ sharpedge_query_pc, sharpedge_input_pc, sharpedge_idx_pc, sharpedge_idx_query = \
+ self.subsample(pc = sharpedge_pc, num_query = num_sharpedge_query, input_pc_size = input_sharpedge_pc_size)
+
+ # concat the random and sharpedges
+ query_pc = torch.cat([random_query_pc, sharpedge_query_pc], dim = 1)
+ input_pc = torch.cat([random_input_pc, sharpedge_input_pc], dim = 1)
+
+ query = self.fourier_embedder(query_pc)
+ data = self.fourier_embedder(input_pc)
+
+ if self.point_feats > 0:
+ random_surface_features, sharpedge_surface_features = torch.split(features, [self.pc_size, self.pc_sharpedge_size], dim = 1)
+
+ input_random_surface_features, query_random_features = \
+ self.handle_features(features = random_surface_features, idx_pc = random_idx_pc, batch_size = B,
+ input_pc_size = input_random_pc_size, idx_query = random_idx_query)
+
+ if input_sharpedge_pc_size == 0:
+ input_sharpedge_surface_features = torch.zeros(B, 0, self.point_feats,
+ dtype = input_random_surface_features.dtype, device = point_cloud.device)
+
+ query_sharpedge_features = torch.zeros(B, 0, self.point_feats,
+ dtype = query_random_features.dtype, device = point_cloud.device)
+ else:
+
+ input_sharpedge_surface_features, query_sharpedge_features = \
+ self.handle_features(idx_pc = sharpedge_idx_pc, features = sharpedge_surface_features,
+ batch_size = B, idx_query = sharpedge_idx_query, input_pc_size = input_sharpedge_pc_size)
+
+ query_features = torch.cat([query_random_features, query_sharpedge_features], dim = 1)
+ input_features = torch.cat([input_random_surface_features, input_sharpedge_surface_features], dim = 1)
+
+ if self.normal_pe:
+ # apply the fourier embeddings on the first 3 dims (xyz)
+ input_features_pe = self.fourier_embedder(input_features[..., :3])
+ query_features_pe = self.fourier_embedder(query_features[..., :3])
+ # replace the first 3 dims with the new PE ones
+ input_features = torch.cat([input_features_pe, input_features[..., :3]], dim = -1)
+ query_features = torch.cat([query_features_pe, query_features[..., :3]], dim = -1)
+
+ # concat at the channels dim
+ query = torch.cat([query, query_features], dim = -1)
+ data = torch.cat([data, input_features], dim = -1)
+
+ # don't return pc_info to avoid unnecessary memory usuage
+ return query.view(B, -1, query.shape[-1]), data.view(B, -1, data.shape[-1])
+
+ def forward(self, point_cloud: torch.Tensor, features: torch.Tensor):
+
+ query, data = self.sample_points_and_latents(point_cloud = point_cloud, features = features)
+
+ # apply projections
+ query = self.input_proj(query)
+ data = self.input_proj(data)
+
+ # apply cross attention between query and data
+ latents = self.cross_attn(query, data)
+
+ if self.self_attn is not None:
+ latents = self.self_attn(latents)
+
+ if self.ln_post is not None:
+ latents = self.ln_post(latents)
+
+ return latents
+
+
+ def subsample(self, pc, num_query, input_pc_size: int):
+
+ """
+ num_query: number of points to keep after FPS
+ input_pc_size: number of points to select before FPS
+ """
+
+ B, _, D = pc.shape
+ query_ratio = num_query / input_pc_size
+
+ # random subsampling of points inside the point cloud
+ idx_pc = torch.randperm(pc.shape[1], device = pc.device)[:input_pc_size]
+ input_pc = pc[:, idx_pc, :]
+
+ # flatten to allow applying fps across the whole batch
+ flattent_input_pc = input_pc.view(B * input_pc_size, D)
+
+ # construct a batch_down tensor to tell fps
+ # which points belong to which batch
+ N_down = int(flattent_input_pc.shape[0] / B)
+ batch_down = torch.arange(B).to(pc.device)
+ batch_down = torch.repeat_interleave(batch_down, N_down)
+
+ idx_query = fps(flattent_input_pc, batch_down, sampling_ratio = query_ratio)
+ query_pc = flattent_input_pc[idx_query].view(B, -1, D)
+
+ return query_pc, input_pc, idx_pc, idx_query
+
+ def handle_features(self, features, idx_pc, input_pc_size, batch_size: int, idx_query):
+
+ B = batch_size
+
+ input_surface_features = features[:, idx_pc, :]
+ flattent_input_features = input_surface_features.view(B * input_pc_size, -1)
+ query_features = flattent_input_features[idx_query].view(B, -1,
+ flattent_input_features.shape[-1])
+
+ return input_surface_features, query_features
+
+def normalize_mesh(mesh, scale = 0.9999):
+ """Normalize mesh to fit in [-scale, scale]. Translate mesh so its center is [0,0,0]"""
+
+ bbox = mesh.bounds
+ center = (bbox[1] + bbox[0]) / 2
+
+ max_extent = (bbox[1] - bbox[0]).max()
+ mesh.apply_translation(-center)
+ mesh.apply_scale((2 * scale) / max_extent)
+
+ return mesh
+
+def sample_pointcloud(mesh, num = 200000):
+ """ Uniformly sample points from the surface of the mesh """
+
+ points, face_idx = mesh.sample(num, return_index = True)
+ normals = mesh.face_normals[face_idx]
+ return torch.from_numpy(points.astype(np.float32)), torch.from_numpy(normals.astype(np.float32))
+
+def detect_sharp_edges(mesh, threshold=0.985):
+ """Return edge indices (a, b) that lie on sharp boundaries of the mesh."""
+
+ V, F = mesh.vertices, mesh.faces
+ VN, FN = mesh.vertex_normals, mesh.face_normals
+
+ sharp_mask = np.ones(V.shape[0])
+ for i in range(3):
+ indices = F[:, i]
+ alignment = np.einsum('ij,ij->i', VN[indices], FN)
+ dot_stack = np.stack((sharp_mask[indices], alignment), axis=-1)
+ sharp_mask[indices] = np.min(dot_stack, axis=-1)
+
+ edge_a = np.concatenate([F[:, 0], F[:, 1], F[:, 2]])
+ edge_b = np.concatenate([F[:, 1], F[:, 2], F[:, 0]])
+ sharp_edges = (sharp_mask[edge_a] < threshold) & (sharp_mask[edge_b] < threshold)
+
+ return edge_a[sharp_edges], edge_b[sharp_edges]
+
+
+def sharp_sample_pointcloud(mesh, num = 16384):
+ """ Sample points preferentially from sharp edges in the mesh. """
+
+ edge_a, edge_b = detect_sharp_edges(mesh)
+ V, VN = mesh.vertices, mesh.vertex_normals
+
+ va, vb = V[edge_a], V[edge_b]
+ na, nb = VN[edge_a], VN[edge_b]
+
+ edge_lengths = np.linalg.norm(vb - va, axis=-1)
+ weights = edge_lengths / edge_lengths.sum()
+
+ indices = np.searchsorted(np.cumsum(weights), np.random.rand(num))
+ t = np.random.rand(num, 1)
+
+ samples = t * va[indices] + (1 - t) * vb[indices]
+ normals = t * na[indices] + (1 - t) * nb[indices]
+
+ return samples.astype(np.float32), normals.astype(np.float32)
+
+def load_surface_sharpedge(mesh, num_points=4096, num_sharp_points=4096, sharpedge_flag = True, device = "cuda"):
+ """Load a surface with optional sharp-edge annotations from a trimesh mesh."""
+
+ import trimesh
+
+ try:
+ mesh_full = trimesh.util.concatenate(mesh.dump())
+ except Exception:
+ mesh_full = trimesh.util.concatenate(mesh)
+
+ mesh_full = normalize_mesh(mesh_full)
+
+ faces = mesh_full.faces
+ vertices = mesh_full.vertices
+ origin_face_count = faces.shape[0]
+
+ mesh_surface = trimesh.Trimesh(vertices=vertices, faces=faces[:origin_face_count])
+ mesh_fill = trimesh.Trimesh(vertices=vertices, faces=faces[origin_face_count:])
+
+ area_surface = mesh_surface.area
+ area_fill = mesh_fill.area
+ total_area = area_surface + area_fill
+
+ sample_num = 499712 // 2
+ fill_ratio = area_fill / total_area if total_area > 0 else 0
+
+ num_fill = int(sample_num * fill_ratio)
+ num_surface = sample_num - num_fill
+
+ surf_pts, surf_normals = sample_pointcloud(mesh_surface, num_surface)
+ fill_pts, fill_normals = (torch.zeros(0, 3), torch.zeros(0, 3)) if num_fill == 0 else sample_pointcloud(mesh_fill, num_fill)
+
+ sharp_pts, sharp_normals = sharp_sample_pointcloud(mesh_surface, sample_num)
+
+ def assemble_tensor(points, normals, label=None):
+
+ data = torch.cat([points, normals], dim=1).half().to(device)
+
+ if label is not None:
+ label_tensor = torch.full((data.shape[0], 1), float(label), dtype=torch.float16).to(device)
+ data = torch.cat([data, label_tensor], dim=1)
+
+ return data
+
+ surface = assemble_tensor(torch.cat([surf_pts.to(device), fill_pts.to(device)], dim=0),
+ torch.cat([surf_normals.to(device), fill_normals.to(device)], dim=0),
+ label = 0 if sharpedge_flag else None)
+
+ sharp_surface = assemble_tensor(torch.from_numpy(sharp_pts), torch.from_numpy(sharp_normals),
+ label = 1 if sharpedge_flag else None)
+
+ rng = np.random.default_rng()
+
+ surface = surface[rng.choice(surface.shape[0], num_points, replace = False)]
+ sharp_surface = sharp_surface[rng.choice(sharp_surface.shape[0], num_sharp_points, replace = False)]
+
+ full = torch.cat([surface, sharp_surface], dim = 0).unsqueeze(0)
+
+ return full
+
+class SharpEdgeSurfaceLoader:
+ """ Load mesh surface and sharp edge samples. """
+
+ def __init__(self, num_uniform_points = 8192, num_sharp_points = 8192):
+
+ self.num_uniform_points = num_uniform_points
+ self.num_sharp_points = num_sharp_points
+ self.total_points = num_uniform_points + num_sharp_points
+
+ def __call__(self, mesh_input, device = "cuda"):
+ mesh = self._load_mesh(mesh_input)
+ return load_surface_sharpedge(mesh, self.num_uniform_points, self.num_sharp_points, device = device)
+
+ @staticmethod
+ def _load_mesh(mesh_input):
+ import trimesh
+
+ if isinstance(mesh_input, str):
+ mesh = trimesh.load(mesh_input, force="mesh", merge_primitives = True)
+ else:
+ mesh = mesh_input
+
+ if isinstance(mesh, trimesh.Scene):
+ combined = None
+ for obj in mesh.geometry.values():
+ combined = obj if combined is None else combined + obj
+ return combined
+
+ return mesh
+
+class DiagonalGaussianDistribution:
+ def __init__(self, params: torch.Tensor, feature_dim: int = -1):
+
+ # divide quant channels (8) into mean and log variance
+ self.mean, self.logvar = torch.chunk(params, 2, dim = feature_dim)
+
+ self.logvar = torch.clamp(self.logvar, -30.0, 20.0)
+ self.std = torch.exp(0.5 * self.logvar)
+
+ def sample(self):
+
+ eps = torch.randn_like(self.std)
+ z = self.mean + eps * self.std
+
+ return z
+
+################################################
+# Volume Decoder
+################################################
+
+class VanillaVolumeDecoder():
+ @torch.no_grad()
+ def __call__(self, latents: torch.Tensor, geo_decoder: callable, octree_resolution: int, bounds = 1.01,
+ num_chunks: int = 10_000, enable_pbar: bool = True, **kwargs):
+
+ if isinstance(bounds, float):
+ bounds = [-bounds, -bounds, -bounds, bounds, bounds, bounds]
+
+ bbox_min, bbox_max = torch.tensor(bounds[:3]), torch.tensor(bounds[3:])
+
+ x = torch.linspace(bbox_min[0], bbox_max[0], int(octree_resolution) + 1, dtype = torch.float32)
+ y = torch.linspace(bbox_min[1], bbox_max[1], int(octree_resolution) + 1, dtype = torch.float32)
+ z = torch.linspace(bbox_min[2], bbox_max[2], int(octree_resolution) + 1, dtype = torch.float32)
+
+ [xs, ys, zs] = torch.meshgrid(x, y, z, indexing = "ij")
+ xyz = torch.stack((xs, ys, zs), axis=-1).to(latents.device, dtype = latents.dtype).contiguous().reshape(-1, 3)
+ grid_size = [int(octree_resolution) + 1, int(octree_resolution) + 1, int(octree_resolution) + 1]
+
+ batch_logits = []
+ for start in tqdm(range(0, xyz.shape[0], num_chunks), desc="Volume Decoding",
+ disable=not enable_pbar):
+
+ chunk_queries = xyz[start: start + num_chunks, :]
+ chunk_queries = chunk_queries.unsqueeze(0).repeat(latents.shape[0], 1, 1)
+ logits = geo_decoder(queries = chunk_queries, latents = latents)
+ batch_logits.append(logits)
+
+ grid_logits = torch.cat(batch_logits, dim = 1)
+ grid_logits = grid_logits.view((latents.shape[0], *grid_size)).float()
+
+ return grid_logits
+
+class FourierEmbedder(nn.Module):
+ """The sin/cosine positional embedding. Given an input tensor `x` of shape [n_batch, ..., c_dim], it converts
+ each feature dimension of `x[..., i]` into:
+ [
+ sin(x[..., i]),
+ sin(f_1*x[..., i]),
+ sin(f_2*x[..., i]),
+ ...
+ sin(f_N * x[..., i]),
+ cos(x[..., i]),
+ cos(f_1*x[..., i]),
+ cos(f_2*x[..., i]),
+ ...
+ cos(f_N * x[..., i]),
+ x[..., i] # only present if include_input is True.
+ ], here f_i is the frequency.
+
+ Denote the space is [0 / num_freqs, 1 / num_freqs, 2 / num_freqs, 3 / num_freqs, ..., (num_freqs - 1) / num_freqs].
+ If logspace is True, then the frequency f_i is [2^(0 / num_freqs), ..., 2^(i / num_freqs), ...];
+ Otherwise, the frequencies are linearly spaced between [1.0, 2^(num_freqs - 1)].
+
+ Args:
+ num_freqs (int): the number of frequencies, default is 6;
+ logspace (bool): If logspace is True, then the frequency f_i is [..., 2^(i / num_freqs), ...],
+ otherwise, the frequencies are linearly spaced between [1.0, 2^(num_freqs - 1)];
+ input_dim (int): the input dimension, default is 3;
+ include_input (bool): include the input tensor or not, default is True.
+
+ Attributes:
+ frequencies (torch.Tensor): If logspace is True, then the frequency f_i is [..., 2^(i / num_freqs), ...],
+ otherwise, the frequencies are linearly spaced between [1.0, 2^(num_freqs - 1);
+
+ out_dim (int): the embedding size, if include_input is True, it is input_dim * (num_freqs * 2 + 1),
+ otherwise, it is input_dim * num_freqs * 2.
+
+ """
+
+ def __init__(self,
+ num_freqs: int = 6,
+ logspace: bool = True,
+ input_dim: int = 3,
+ include_input: bool = True,
+ include_pi: bool = True) -> None:
+
+ """The initialization"""
+
+ super().__init__()
+
+ if logspace:
+ frequencies = 2.0 ** torch.arange(
+ num_freqs,
+ dtype=torch.float32
+ )
+ else:
+ frequencies = torch.linspace(
+ 1.0,
+ 2.0 ** (num_freqs - 1),
+ num_freqs,
+ dtype=torch.float32
+ )
+
+ if include_pi:
+ frequencies *= torch.pi
+
+ self.register_buffer("frequencies", frequencies, persistent=False)
+ self.include_input = include_input
+ self.num_freqs = num_freqs
+
+ self.out_dim = self.get_dims(input_dim)
+
+ def get_dims(self, input_dim):
+ temp = 1 if self.include_input or self.num_freqs == 0 else 0
+ out_dim = input_dim * (self.num_freqs * 2 + temp)
+
+ return out_dim
+
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
+ """ Forward process.
+
+ Args:
+ x: tensor of shape [..., dim]
+
+ Returns:
+ embedding: an embedding of `x` of shape [..., dim * (num_freqs * 2 + temp)]
+ where temp is 1 if include_input is True and 0 otherwise.
+ """
+
+ if self.num_freqs > 0:
+ embed = (x[..., None].contiguous() * self.frequencies.to(device=x.device, dtype=x.dtype)).view(*x.shape[:-1], -1)
+ if self.include_input:
+ return torch.cat((x, embed.sin(), embed.cos()), dim=-1)
+ else:
+ return torch.cat((embed.sin(), embed.cos()), dim=-1)
+ else:
+ return x
+
+class CrossAttentionProcessor:
+ def __call__(self, attn, q, k, v):
+ out = comfy.ops.scaled_dot_product_attention(q, k, v)
+ return out
+
+class DropPath(nn.Module):
+ """Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks).
+ """
+
+ def __init__(self, drop_prob: float = 0., scale_by_keep: bool = True):
+ super(DropPath, self).__init__()
+ self.drop_prob = drop_prob
+ self.scale_by_keep = scale_by_keep
+
+ def forward(self, x):
+ """Drop paths (Stochastic Depth) per sample (when applied in main path of residual blocks).
+
+ This is the same as the DropConnect impl I created for EfficientNet, etc networks, however,
+ the original name is misleading as 'Drop Connect' is a different form of dropout in a separate paper...
+ See discussion: https://github.com/tensorflow/tpu/issues/494#issuecomment-532968956 ... I've opted for
+ changing the layer and argument names to 'drop path' rather than mix DropConnect as a layer name and use
+ 'survival rate' as the argument.
+
+ """
+ if self.drop_prob == 0. or not self.training:
+ return x
+ keep_prob = 1 - self.drop_prob
+ shape = (x.shape[0],) + (1,) * (x.ndim - 1) # work with diff dim tensors, not just 2D ConvNets
+ random_tensor = x.new_empty(shape).bernoulli_(keep_prob)
+ if keep_prob > 0.0 and self.scale_by_keep:
+ random_tensor.div_(keep_prob)
+ return x * random_tensor
+
+ def extra_repr(self):
+ return f'drop_prob={round(self.drop_prob, 3):0.3f}'
+
+
+class MLP(nn.Module):
+ def __init__(
+ self, *,
+ width: int,
+ expand_ratio: int = 4,
+ output_width: int = None,
+ drop_path_rate: float = 0.0
+ ):
+ super().__init__()
+ self.width = width
+ self.c_fc = ops.Linear(width, width * expand_ratio)
+ self.c_proj = ops.Linear(width * expand_ratio, output_width if output_width is not None else width)
+ self.gelu = nn.GELU()
+ self.drop_path = DropPath(drop_path_rate) if drop_path_rate > 0. else nn.Identity()
+
+ def forward(self, x):
+ return self.drop_path(self.c_proj(self.gelu(self.c_fc(x))))
+
+class QKVMultiheadCrossAttention(nn.Module):
+ def __init__(
+ self,
+ heads: int,
+ n_data = None,
+ width=None,
+ qk_norm=False,
+ norm_layer=ops.LayerNorm
+ ):
+ super().__init__()
+ self.heads = heads
+ self.n_data = n_data
+ self.q_norm = norm_layer(width // heads, elementwise_affine=True, eps=1e-6) if qk_norm else nn.Identity()
+ self.k_norm = norm_layer(width // heads, elementwise_affine=True, eps=1e-6) if qk_norm else nn.Identity()
+
+ def forward(self, q, kv):
+
+ _, n_ctx, _ = q.shape
+ bs, n_data, width = kv.shape
+
+ attn_ch = width // self.heads // 2
+ q = q.view(bs, n_ctx, self.heads, -1)
+
+ kv = kv.view(bs, n_data, self.heads, -1)
+ k, v = torch.split(kv, attn_ch, dim=-1)
+
+ q = self.q_norm(q)
+ k = self.k_norm(k)
+
+ q, k, v = [t.permute(0, 2, 1, 3) for t in (q, k, v)]
+ out = F.scaled_dot_product_attention(q, k, v)
+
+ out = out.transpose(1, 2).reshape(bs, n_ctx, -1)
+
+ return out
+
+class MultiheadCrossAttention(nn.Module):
+ def __init__(
+ self,
+ *,
+ width: int,
+ heads: int,
+ qkv_bias: bool = True,
+ data_width: Optional[int] = None,
+ norm_layer=ops.LayerNorm,
+ qk_norm: bool = False,
+ kv_cache: bool = False,
+ ):
+ super().__init__()
+ self.width = width
+ self.heads = heads
+ self.data_width = width if data_width is None else data_width
+ self.c_q = ops.Linear(width, width, bias=qkv_bias)
+ self.c_kv = ops.Linear(self.data_width, width * 2, bias=qkv_bias)
+ self.c_proj = ops.Linear(width, width)
+ self.attention = QKVMultiheadCrossAttention(
+ heads=heads,
+ width=width,
+ norm_layer=norm_layer,
+ qk_norm=qk_norm
+ )
+ self.kv_cache = kv_cache
+ self.data = None
+
+ def forward(self, x, data):
+ x = self.c_q(x)
+ if self.kv_cache:
+ if self.data is None:
+ self.data = self.c_kv(data)
+ logging.info('Save kv cache,this should be called only once for one mesh')
+ data = self.data
+ else:
+ data = self.c_kv(data)
+ x = self.attention(x, data)
+ x = self.c_proj(x)
+ return x
+
+class ResidualCrossAttentionBlock(nn.Module):
+ def __init__(
+ self,
+ *,
+ width: int,
+ heads: int,
+ mlp_expand_ratio: int = 4,
+ data_width: Optional[int] = None,
+ qkv_bias: bool = True,
+ norm_layer=ops.LayerNorm,
+ qk_norm: bool = False
+ ):
+ super().__init__()
+
+ if data_width is None:
+ data_width = width
+
+ self.attn = MultiheadCrossAttention(
+ width=width,
+ heads=heads,
+ data_width=data_width,
+ qkv_bias=qkv_bias,
+ norm_layer=norm_layer,
+ qk_norm=qk_norm
+ )
+ self.ln_1 = norm_layer(width, elementwise_affine=True, eps=1e-6)
+ self.ln_2 = norm_layer(data_width, elementwise_affine=True, eps=1e-6)
+ self.ln_3 = norm_layer(width, elementwise_affine=True, eps=1e-6)
+ self.mlp = MLP(width=width, expand_ratio=mlp_expand_ratio)
+
+ def forward(self, x: torch.Tensor, data: torch.Tensor):
+ x = x + self.attn(self.ln_1(x), self.ln_2(data))
+ x = x + self.mlp(self.ln_3(x))
+ return x
+
+
+class QKVMultiheadAttention(nn.Module):
+ def __init__(
+ self,
+ *,
+ heads: int,
+ width=None,
+ qk_norm=False,
+ norm_layer=ops.LayerNorm
+ ):
+ super().__init__()
+ self.heads = heads
+ self.q_norm = norm_layer(width // heads, elementwise_affine=True, eps=1e-6) if qk_norm else nn.Identity()
+ self.k_norm = norm_layer(width // heads, elementwise_affine=True, eps=1e-6) if qk_norm else nn.Identity()
+
+ def forward(self, qkv):
+ bs, n_ctx, width = qkv.shape
+ attn_ch = width // self.heads // 3
+ qkv = qkv.view(bs, n_ctx, self.heads, -1)
+ q, k, v = torch.split(qkv, attn_ch, dim=-1)
+
+ q = self.q_norm(q)
+ k = self.k_norm(k)
+
+ q, k, v = [t.permute(0, 2, 1, 3) for t in (q, k, v)]
+ out = F.scaled_dot_product_attention(q, k, v).transpose(1, 2).reshape(bs, n_ctx, -1)
+ return out
+
+
+class MultiheadAttention(nn.Module):
+ def __init__(
+ self,
+ *,
+ width: int,
+ heads: int,
+ qkv_bias: bool,
+ norm_layer=ops.LayerNorm,
+ qk_norm: bool = False,
+ drop_path_rate: float = 0.0
+ ):
+ super().__init__()
+
+ self.c_qkv = ops.Linear(width, width * 3, bias=qkv_bias)
+ self.c_proj = ops.Linear(width, width)
+ self.attention = QKVMultiheadAttention(
+ heads=heads,
+ width=width,
+ norm_layer=norm_layer,
+ qk_norm=qk_norm
+ )
+ self.drop_path = DropPath(drop_path_rate) if drop_path_rate > 0. else nn.Identity()
+
+ def forward(self, x):
+ x = self.c_qkv(x)
+ x = self.attention(x)
+ x = self.drop_path(self.c_proj(x))
+ return x
+
+
+class ResidualAttentionBlock(nn.Module):
+ def __init__(
+ self,
+ *,
+ width: int,
+ heads: int,
+ qkv_bias: bool = True,
+ norm_layer=ops.LayerNorm,
+ qk_norm: bool = False,
+ drop_path_rate: float = 0.0,
+ ):
+ super().__init__()
+ self.attn = MultiheadAttention(
+ width=width,
+ heads=heads,
+ qkv_bias=qkv_bias,
+ norm_layer=norm_layer,
+ qk_norm=qk_norm,
+ drop_path_rate=drop_path_rate
+ )
+ self.ln_1 = norm_layer(width, elementwise_affine=True, eps=1e-6)
+ self.mlp = MLP(width=width, drop_path_rate=drop_path_rate)
+ self.ln_2 = norm_layer(width, elementwise_affine=True, eps=1e-6)
+
+ def forward(self, x: torch.Tensor):
+ x = x + self.attn(self.ln_1(x))
+ x = x + self.mlp(self.ln_2(x))
+ return x
+
+
+class Transformer(nn.Module):
+ def __init__(
+ self,
+ *,
+ width: int,
+ layers: int,
+ heads: int,
+ qkv_bias: bool = True,
+ norm_layer=ops.LayerNorm,
+ qk_norm: bool = False,
+ drop_path_rate: float = 0.0
+ ):
+ super().__init__()
+ self.width = width
+ self.layers = layers
+ self.resblocks = nn.ModuleList(
+ [
+ ResidualAttentionBlock(
+ width=width,
+ heads=heads,
+ qkv_bias=qkv_bias,
+ norm_layer=norm_layer,
+ qk_norm=qk_norm,
+ drop_path_rate=drop_path_rate
+ )
+ for _ in range(layers)
+ ]
+ )
+
+ def forward(self, x: torch.Tensor):
+ for block in self.resblocks:
+ x = block(x)
+ return x
+
+
+class CrossAttentionDecoder(nn.Module):
+
+ def __init__(
+ self,
+ *,
+ out_channels: int,
+ fourier_embedder: FourierEmbedder,
+ width: int,
+ heads: int,
+ mlp_expand_ratio: int = 4,
+ downsample_ratio: int = 1,
+ enable_ln_post: bool = True,
+ qkv_bias: bool = True,
+ qk_norm: bool = False,
+ label_type: str = "binary"
+ ):
+ super().__init__()
+
+ self.enable_ln_post = enable_ln_post
+ self.fourier_embedder = fourier_embedder
+ self.downsample_ratio = downsample_ratio
+ self.query_proj = ops.Linear(self.fourier_embedder.out_dim, width)
+ if self.downsample_ratio != 1:
+ self.latents_proj = ops.Linear(width * downsample_ratio, width)
+ if not self.enable_ln_post:
+ qk_norm = False
+ self.cross_attn_decoder = ResidualCrossAttentionBlock(
+ width=width,
+ mlp_expand_ratio=mlp_expand_ratio,
+ heads=heads,
+ qkv_bias=qkv_bias,
+ qk_norm=qk_norm
+ )
+
+ if self.enable_ln_post:
+ self.ln_post = ops.LayerNorm(width)
+ self.output_proj = ops.Linear(width, out_channels)
+ self.label_type = label_type
+ self.count = 0
+
+ def forward(self, queries=None, query_embeddings=None, latents=None):
+ if query_embeddings is None:
+ query_embeddings = self.query_proj(self.fourier_embedder(queries).to(latents.dtype))
+ self.count += query_embeddings.shape[1]
+ if self.downsample_ratio != 1:
+ latents = self.latents_proj(latents)
+ x = self.cross_attn_decoder(query_embeddings, latents)
+ if self.enable_ln_post:
+ x = self.ln_post(x)
+ occ = self.output_proj(x)
+ return occ
+
+
+class ShapeVAE(nn.Module):
+ def __init__(
+ self,
+ *,
+ num_latents: int = 4096,
+ embed_dim: int = 64,
+ width: int = 1024,
+ heads: int = 16,
+ num_decoder_layers: int = 16,
+ num_encoder_layers: int = 8,
+ pc_size: int = 81920,
+ pc_sharpedge_size: int = 0,
+ point_feats: int = 4,
+ downsample_ratio: int = 20,
+ geo_decoder_downsample_ratio: int = 1,
+ geo_decoder_mlp_expand_ratio: int = 4,
+ geo_decoder_ln_post: bool = True,
+ num_freqs: int = 8,
+ qkv_bias: bool = False,
+ qk_norm: bool = True,
+ drop_path_rate: float = 0.0,
+ include_pi: bool = False,
+ scale_factor: float = 1.0039506158752403,
+ label_type: str = "binary",
+ ):
+ super().__init__()
+ self.geo_decoder_ln_post = geo_decoder_ln_post
+
+ self.fourier_embedder = FourierEmbedder(num_freqs=num_freqs, include_pi=include_pi)
+
+ self.encoder = PointCrossAttention(layers = num_encoder_layers,
+ num_latents = num_latents,
+ downsample_ratio = downsample_ratio,
+ heads = heads,
+ pc_size = pc_size,
+ width = width,
+ point_feats = point_feats,
+ fourier_embedder = self.fourier_embedder,
+ pc_sharpedge_size = pc_sharpedge_size)
+
+ self.post_kl = ops.Linear(embed_dim, width)
+
+ self.transformer = Transformer(
+ width=width,
+ layers=num_decoder_layers,
+ heads=heads,
+ qkv_bias=qkv_bias,
+ qk_norm=qk_norm,
+ drop_path_rate=drop_path_rate
+ )
+
+ self.geo_decoder = CrossAttentionDecoder(
+ fourier_embedder=self.fourier_embedder,
+ out_channels=1,
+ mlp_expand_ratio=geo_decoder_mlp_expand_ratio,
+ downsample_ratio=geo_decoder_downsample_ratio,
+ enable_ln_post=self.geo_decoder_ln_post,
+ width=width // geo_decoder_downsample_ratio,
+ heads=heads // geo_decoder_downsample_ratio,
+ qkv_bias=qkv_bias,
+ qk_norm=qk_norm,
+ label_type=label_type,
+ )
+
+ self.volume_decoder = VanillaVolumeDecoder()
+ self.scale_factor = scale_factor
+
+ def decode(self, latents, **kwargs):
+ latents = self.post_kl(latents.movedim(-2, -1))
+ latents = self.transformer(latents)
+
+ bounds = kwargs.get("bounds", 1.01)
+ num_chunks = kwargs.get("num_chunks", 8000)
+ octree_resolution = kwargs.get("octree_resolution", 256)
+ enable_pbar = kwargs.get("enable_pbar", True)
+
+ grid_logits = self.volume_decoder(latents, self.geo_decoder, bounds=bounds, num_chunks=num_chunks, octree_resolution=octree_resolution, enable_pbar=enable_pbar)
+ return grid_logits.movedim(-2, -1)
+
+ def encode(self, surface):
+
+ pc, feats = surface[:, :, :3], surface[:, :, 3:]
+ latents = self.encoder(pc, feats)
+
+ moments = self.pre_kl(latents)
+ posterior = DiagonalGaussianDistribution(moments, feature_dim = -1)
+
+ latents = posterior.sample()
+
+ return latents
diff --git a/ComfyUI/comfy/ldm/hunyuan3dv2_1/__pycache__/hunyuandit.cpython-312.pyc b/ComfyUI/comfy/ldm/hunyuan3dv2_1/__pycache__/hunyuandit.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..2f10d11b09477dcea8c62014abd0d37894dd8b34
Binary files /dev/null and b/ComfyUI/comfy/ldm/hunyuan3dv2_1/__pycache__/hunyuandit.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/hunyuan3dv2_1/hunyuandit.py b/ComfyUI/comfy/ldm/hunyuan3dv2_1/hunyuandit.py
new file mode 100644
index 0000000000000000000000000000000000000000..4e4819fe3dc427208ad3e325cbd1409a7dec7e1f
--- /dev/null
+++ b/ComfyUI/comfy/ldm/hunyuan3dv2_1/hunyuandit.py
@@ -0,0 +1,668 @@
+import math
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+from comfy.ldm.modules.attention import optimized_attention
+import comfy.model_management
+
+class GELU(nn.Module):
+
+ def __init__(self, dim_in: int, dim_out: int, operations, device, dtype):
+ super().__init__()
+ self.proj = operations.Linear(dim_in, dim_out, device = device, dtype = dtype)
+
+ def gelu(self, gate: torch.Tensor) -> torch.Tensor:
+
+ if gate.device.type == "mps":
+ return F.gelu(gate.to(dtype = torch.float32)).to(dtype = gate.dtype)
+
+ return F.gelu(gate)
+
+ def forward(self, hidden_states):
+
+ hidden_states = self.proj(hidden_states)
+ hidden_states = self.gelu(hidden_states)
+
+ return hidden_states
+
+class FeedForward(nn.Module):
+
+ def __init__(self, dim: int, dim_out = None, mult: int = 4,
+ dropout: float = 0.0, inner_dim = None, operations = None, device = None, dtype = None):
+
+ super().__init__()
+ if inner_dim is None:
+ inner_dim = int(dim * mult)
+
+ dim_out = dim_out if dim_out is not None else dim
+
+ act_fn = GELU(dim, inner_dim, operations = operations, device = device, dtype = dtype)
+
+ self.net = nn.ModuleList([])
+ self.net.append(act_fn)
+
+ self.net.append(nn.Dropout(dropout))
+ self.net.append(operations.Linear(inner_dim, dim_out, device = device, dtype = dtype))
+
+ def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
+ for module in self.net:
+ hidden_states = module(hidden_states)
+ return hidden_states
+
+class AddAuxLoss(torch.autograd.Function):
+
+ @staticmethod
+ def forward(ctx, x, loss):
+ # do nothing in forward (no computation)
+ ctx.requires_aux_loss = loss.requires_grad
+ ctx.dtype = loss.dtype
+
+ return x
+
+ @staticmethod
+ def backward(ctx, grad_output):
+ # add the aux loss gradients
+ grad_loss = None
+ # put the aux grad the same as the main grad loss
+ # aux grad contributes equally
+ if ctx.requires_aux_loss:
+ grad_loss = torch.ones(1, dtype = ctx.dtype, device = grad_output.device)
+
+ return grad_output, grad_loss
+
+class MoEGate(nn.Module):
+
+ def __init__(self, embed_dim, num_experts=16, num_experts_per_tok=2, aux_loss_alpha=0.01, device = None, dtype = None):
+
+ super().__init__()
+ self.top_k = num_experts_per_tok
+ self.n_routed_experts = num_experts
+
+ self.alpha = aux_loss_alpha
+
+ self.gating_dim = embed_dim
+ self.weight = nn.Parameter(torch.empty((self.n_routed_experts, self.gating_dim), device = device, dtype = dtype))
+
+ def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
+
+ # flatten hidden states
+ hidden_states = hidden_states.view(-1, hidden_states.size(-1))
+
+ # get logits and pass it to softmax
+ logits = F.linear(hidden_states, comfy.model_management.cast_to(self.weight, dtype=hidden_states.dtype, device=hidden_states.device), bias = None)
+ scores = logits.softmax(dim = -1)
+
+ topk_weight, topk_idx = torch.topk(scores, k = self.top_k, dim = -1, sorted = False)
+
+ if self.training and self.alpha > 0.0:
+ scores_for_aux = scores
+
+ # used bincount instead of one hot encoding
+ counts = torch.bincount(topk_idx.view(-1), minlength = self.n_routed_experts).float()
+ ce = counts / topk_idx.numel() # normalized expert usage
+
+ # mean expert score
+ Pi = scores_for_aux.mean(0)
+
+ # expert balance loss
+ aux_loss = (Pi * ce * self.n_routed_experts).sum() * self.alpha
+ else:
+ aux_loss = None
+
+ return topk_idx, topk_weight, aux_loss
+
+class MoEBlock(nn.Module):
+ def __init__(self, dim, num_experts: int = 6, moe_top_k: int = 2, dropout: float = 0.0,
+ ff_inner_dim: int = None, operations = None, device = None, dtype = None):
+ super().__init__()
+
+ self.moe_top_k = moe_top_k
+ self.num_experts = num_experts
+
+ self.experts = nn.ModuleList([
+ FeedForward(dim, dropout = dropout, inner_dim = ff_inner_dim, operations = operations, device = device, dtype = dtype)
+ for _ in range(num_experts)
+ ])
+
+ self.gate = MoEGate(dim, num_experts = num_experts, num_experts_per_tok = moe_top_k, device = device, dtype = dtype)
+ self.shared_experts = FeedForward(dim, dropout = dropout, inner_dim = ff_inner_dim, operations = operations, device = device, dtype = dtype)
+
+ def forward(self, hidden_states) -> torch.Tensor:
+
+ identity = hidden_states
+ orig_shape = hidden_states.shape
+ topk_idx, topk_weight, aux_loss = self.gate(hidden_states)
+
+ hidden_states = hidden_states.view(-1, hidden_states.shape[-1])
+ flat_topk_idx = topk_idx.view(-1)
+
+ if self.training:
+
+ hidden_states = hidden_states.repeat_interleave(self.moe_top_k, dim = 0)
+ y = torch.empty_like(hidden_states, dtype = hidden_states.dtype)
+
+ for i, expert in enumerate(self.experts):
+ tmp = expert(hidden_states[flat_topk_idx == i])
+ y[flat_topk_idx == i] = tmp.to(hidden_states.dtype)
+
+ y = (y.view(*topk_weight.shape, -1) * topk_weight.unsqueeze(-1)).sum(dim = 1)
+ y = y.view(*orig_shape)
+
+ y = AddAuxLoss.apply(y, aux_loss)
+ else:
+ y = self.moe_infer(hidden_states, flat_expert_indices = flat_topk_idx,flat_expert_weights = topk_weight.view(-1, 1)).view(*orig_shape)
+
+ y = y + self.shared_experts(identity)
+
+ return y
+
+ @torch.no_grad()
+ def moe_infer(self, x, flat_expert_indices, flat_expert_weights):
+
+ expert_cache = torch.zeros_like(x)
+ idxs = flat_expert_indices.argsort()
+
+ # no need for .numpy().cpu() here
+ tokens_per_expert = flat_expert_indices.bincount().cumsum(0)
+ token_idxs = idxs // self.moe_top_k
+
+ for i, end_idx in enumerate(tokens_per_expert):
+
+ start_idx = 0 if i == 0 else tokens_per_expert[i-1]
+
+ if start_idx == end_idx:
+ continue
+
+ expert = self.experts[i]
+ exp_token_idx = token_idxs[start_idx:end_idx]
+
+ expert_tokens = x[exp_token_idx]
+ expert_out = expert(expert_tokens)
+
+ expert_out.mul_(flat_expert_weights[idxs[start_idx:end_idx]])
+
+ # use index_add_ with a 1-D index tensor directly avoids building a large [N, D] index map and extra memcopy required by scatter_reduce_
+ # + avoid dtype conversion
+ expert_cache.index_add_(0, exp_token_idx, expert_out)
+
+ return expert_cache
+
+class Timesteps(nn.Module):
+ def __init__(self, num_channels: int, downscale_freq_shift: float = 0.0,
+ scale: float = 1.0, max_period: int = 10000):
+ super().__init__()
+
+ self.num_channels = num_channels
+ half_dim = num_channels // 2
+
+ # precompute the “inv_freq” vector once
+ exponent = -math.log(max_period) * torch.arange(
+ half_dim, dtype=torch.float32
+ ) / (half_dim - downscale_freq_shift)
+
+ inv_freq = torch.exp(exponent)
+
+ # pad
+ if num_channels % 2 == 1:
+ # we’ll pad a zero at the end of the cos-half
+ inv_freq = torch.cat([inv_freq, inv_freq.new_zeros(1)])
+
+ # register to buffer so it moves with the device
+ self.register_buffer("inv_freq", inv_freq, persistent = False)
+ self.scale = scale
+
+ def forward(self, timesteps: torch.Tensor):
+
+ x = timesteps.float().unsqueeze(1) * self.inv_freq.to(timesteps.device).unsqueeze(0)
+
+
+ # fused CUDA kernels for sin and cos
+ sin_emb = x.sin()
+ cos_emb = x.cos()
+
+ emb = torch.cat([sin_emb, cos_emb], dim = 1)
+
+ # scale factor
+ if self.scale != 1.0:
+ emb = emb * self.scale
+
+ # If we padded inv_freq for odd, emb is already wide enough; otherwise:
+ if emb.shape[1] > self.num_channels:
+ emb = emb[:, :self.num_channels]
+
+ return emb
+
+class TimestepEmbedder(nn.Module):
+ def __init__(self, hidden_size, frequency_embedding_size = 256, cond_proj_dim = None, operations = None, device = None, dtype = None):
+ super().__init__()
+
+ self.mlp = nn.Sequential(
+ operations.Linear(hidden_size, frequency_embedding_size, bias=True, device = device, dtype = dtype),
+ nn.GELU(),
+ operations.Linear(frequency_embedding_size, hidden_size, bias=True, device = device, dtype = dtype),
+ )
+ self.frequency_embedding_size = frequency_embedding_size
+
+ if cond_proj_dim is not None:
+ self.cond_proj = operations.Linear(cond_proj_dim, frequency_embedding_size, bias=False, device = device, dtype = dtype)
+
+ self.time_embed = Timesteps(hidden_size)
+
+ def forward(self, timesteps, condition):
+
+ timestep_embed = self.time_embed(timesteps).type(self.mlp[0].weight.dtype)
+
+ if condition is not None:
+ cond_embed = self.cond_proj(condition)
+ timestep_embed = timestep_embed + cond_embed
+
+ time_conditioned = self.mlp(timestep_embed)
+
+ # for broadcasting with image tokens
+ return time_conditioned.unsqueeze(1)
+
+class MLP(nn.Module):
+ def __init__(self, *, width: int, operations = None, device = None, dtype = None):
+ super().__init__()
+ self.width = width
+ self.fc1 = operations.Linear(width, width * 4, device = device, dtype = dtype)
+ self.fc2 = operations.Linear(width * 4, width, device = device, dtype = dtype)
+ self.gelu = nn.GELU()
+
+ def forward(self, x):
+ return self.fc2(self.gelu(self.fc1(x)))
+
+class CrossAttention(nn.Module):
+ def __init__(
+ self,
+ qdim,
+ kdim,
+ num_heads,
+ qkv_bias=True,
+ qk_norm=False,
+ norm_layer=nn.LayerNorm,
+ use_fp16: bool = False,
+ operations = None,
+ dtype = None,
+ device = None,
+ **kwargs,
+ ):
+ super().__init__()
+ self.qdim = qdim
+ self.kdim = kdim
+
+ self.num_heads = num_heads
+ self.head_dim = self.qdim // num_heads
+
+ self.scale = self.head_dim ** -0.5
+
+ self.to_q = operations.Linear(qdim, qdim, bias=qkv_bias, device = device, dtype = dtype)
+ self.to_k = operations.Linear(kdim, qdim, bias=qkv_bias, device = device, dtype = dtype)
+ self.to_v = operations.Linear(kdim, qdim, bias=qkv_bias, device = device, dtype = dtype)
+
+ if use_fp16:
+ eps = 1.0 / 65504
+ else:
+ eps = 1e-6
+
+ if norm_layer == nn.LayerNorm:
+ norm_layer = operations.LayerNorm
+ else:
+ norm_layer = operations.RMSNorm
+
+ self.q_norm = norm_layer(self.head_dim, elementwise_affine=True, eps = eps, device = device, dtype = dtype) if qk_norm else nn.Identity()
+ self.k_norm = norm_layer(self.head_dim, elementwise_affine=True, eps = eps, device = device, dtype = dtype) if qk_norm else nn.Identity()
+ self.out_proj = operations.Linear(qdim, qdim, bias=True, device = device, dtype = dtype)
+
+ def forward(self, x, y):
+
+ b, s1, _ = x.shape
+ _, s2, _ = y.shape
+
+ y = y.to(next(self.to_k.parameters()).dtype)
+
+ q = self.to_q(x)
+ k = self.to_k(y)
+ v = self.to_v(y)
+
+ kv = torch.cat((k, v), dim=-1)
+ split_size = kv.shape[-1] // self.num_heads // 2
+
+ kv = kv.view(b, -1, self.num_heads, split_size * 2)
+ k, v = torch.split(kv, split_size, dim=-1)
+
+ q = q.view(b, s1, self.num_heads, self.head_dim)
+ k = k.view(b, s2, self.num_heads, self.head_dim)
+ v = v.reshape(b, s2, self.num_heads * self.head_dim)
+
+ q = self.q_norm(q)
+ k = self.k_norm(k)
+
+ x = optimized_attention(
+ q.reshape(b, s1, self.num_heads * self.head_dim),
+ k.reshape(b, s2, self.num_heads * self.head_dim),
+ v,
+ heads=self.num_heads,
+ low_precision_attention=False,
+ )
+
+ out = self.out_proj(x)
+
+ return out
+
+class Attention(nn.Module):
+
+ def __init__(
+ self,
+ dim,
+ num_heads,
+ qkv_bias = True,
+ qk_norm = False,
+ norm_layer = nn.LayerNorm,
+ use_fp16: bool = False,
+ operations = None,
+ device = None,
+ dtype = None
+ ):
+ super().__init__()
+ self.dim = dim
+ self.num_heads = num_heads
+ self.head_dim = self.dim // num_heads
+ self.scale = self.head_dim ** -0.5
+
+ self.to_q = operations.Linear(dim, dim, bias = qkv_bias, device = device, dtype = dtype)
+ self.to_k = operations.Linear(dim, dim, bias = qkv_bias, device = device, dtype = dtype)
+ self.to_v = operations.Linear(dim, dim, bias = qkv_bias, device = device, dtype = dtype)
+
+ if use_fp16:
+ eps = 1.0 / 65504
+ else:
+ eps = 1e-6
+
+ if norm_layer == nn.LayerNorm:
+ norm_layer = operations.LayerNorm
+ else:
+ norm_layer = operations.RMSNorm
+
+ self.q_norm = norm_layer(self.head_dim, elementwise_affine=True, eps = eps, device = device, dtype = dtype) if qk_norm else nn.Identity()
+ self.k_norm = norm_layer(self.head_dim, elementwise_affine=True, eps = eps, device = device, dtype = dtype) if qk_norm else nn.Identity()
+ self.out_proj = operations.Linear(dim, dim, device = device, dtype = dtype)
+
+ def forward(self, x):
+ B, N, _ = x.shape
+
+ query = self.to_q(x)
+ key = self.to_k(x)
+ value = self.to_v(x)
+
+ qkv_combined = torch.cat((query, key, value), dim=-1)
+ split_size = qkv_combined.shape[-1] // self.num_heads // 3
+
+ qkv = qkv_combined.view(B, -1, self.num_heads, split_size * 3)
+ query, key, value = torch.split(qkv, split_size, dim=-1)
+
+ query = query.reshape(B, N, self.num_heads, self.head_dim)
+ key = key.reshape(B, N, self.num_heads, self.head_dim)
+ value = value.reshape(B, N, self.num_heads * self.head_dim)
+
+ query = self.q_norm(query)
+ key = self.k_norm(key)
+
+ x = optimized_attention(
+ query.reshape(B, N, self.num_heads * self.head_dim),
+ key.reshape(B, N, self.num_heads * self.head_dim),
+ value,
+ heads=self.num_heads,
+ low_precision_attention=False,
+ )
+
+ x = self.out_proj(x)
+ return x
+
+class HunYuanDiTBlock(nn.Module):
+ def __init__(
+ self,
+ hidden_size,
+ c_emb_size,
+ num_heads,
+ text_states_dim=1024,
+ qk_norm=False,
+ norm_layer=nn.LayerNorm,
+ qk_norm_layer=True,
+ qkv_bias=True,
+ skip_connection=True,
+ timested_modulate=False,
+ use_moe: bool = False,
+ num_experts: int = 8,
+ moe_top_k: int = 2,
+ use_fp16: bool = False,
+ operations = None,
+ device = None, dtype = None
+ ):
+ super().__init__()
+
+ # eps can't be 1e-6 in fp16 mode because of numerical stability issues
+ if use_fp16:
+ eps = 1.0 / 65504
+ else:
+ eps = 1e-6
+
+ self.norm1 = norm_layer(hidden_size, elementwise_affine = True, eps = eps, device = device, dtype = dtype)
+
+ self.attn1 = Attention(hidden_size, num_heads=num_heads, qkv_bias=qkv_bias, qk_norm=qk_norm,
+ norm_layer=qk_norm_layer, use_fp16 = use_fp16, device = device, dtype = dtype, operations = operations)
+
+ self.norm2 = norm_layer(hidden_size, elementwise_affine = True, eps = eps, device = device, dtype = dtype)
+
+ self.timested_modulate = timested_modulate
+ if self.timested_modulate:
+ self.default_modulation = nn.Sequential(
+ nn.SiLU(),
+ operations.Linear(c_emb_size, hidden_size, bias=True, device = device, dtype = dtype)
+ )
+
+ self.attn2 = CrossAttention(hidden_size, text_states_dim, num_heads=num_heads, qkv_bias=qkv_bias,
+ qk_norm=qk_norm, norm_layer=qk_norm_layer, use_fp16 = use_fp16,
+ device = device, dtype = dtype, operations = operations)
+
+ self.norm3 = norm_layer(hidden_size, elementwise_affine = True, eps = eps, device = device, dtype = dtype)
+
+ if skip_connection:
+ self.skip_norm = norm_layer(hidden_size, elementwise_affine = True, eps = eps, device = device, dtype = dtype)
+ self.skip_linear = operations.Linear(2 * hidden_size, hidden_size, device = device, dtype = dtype)
+ else:
+ self.skip_linear = None
+
+ self.use_moe = use_moe
+
+ if self.use_moe:
+ self.moe = MoEBlock(
+ hidden_size,
+ num_experts = num_experts,
+ moe_top_k = moe_top_k,
+ dropout = 0.0,
+ ff_inner_dim = int(hidden_size * 4.0),
+ device = device, dtype = dtype,
+ operations = operations
+ )
+ else:
+ self.mlp = MLP(width=hidden_size, operations=operations, device = device, dtype = dtype)
+
+ def forward(self, hidden_states, conditioning=None, text_states=None, skip_tensor=None):
+
+ if self.skip_linear is not None:
+ combined = torch.cat([skip_tensor, hidden_states], dim=-1)
+ hidden_states = self.skip_linear(combined)
+ hidden_states = self.skip_norm(hidden_states)
+
+ # self attention
+ if self.timested_modulate:
+ modulation_shift = self.default_modulation(conditioning).unsqueeze(dim=1)
+ hidden_states = hidden_states + modulation_shift
+
+ self_attn_out = self.attn1(self.norm1(hidden_states))
+ hidden_states = hidden_states + self_attn_out
+
+ # cross attention
+ hidden_states = hidden_states + self.attn2(self.norm2(hidden_states), text_states)
+
+ # MLP Layer
+ mlp_input = self.norm3(hidden_states)
+
+ if self.use_moe:
+ hidden_states = hidden_states + self.moe(mlp_input)
+ else:
+ hidden_states = hidden_states + self.mlp(mlp_input)
+
+ return hidden_states
+
+class FinalLayer(nn.Module):
+
+ def __init__(self, final_hidden_size, out_channels, operations, use_fp16: bool = False, device = None, dtype = None):
+ super().__init__()
+
+ if use_fp16:
+ eps = 1.0 / 65504
+ else:
+ eps = 1e-6
+
+ self.norm_final = operations.LayerNorm(final_hidden_size, elementwise_affine = True, eps = eps, device = device, dtype = dtype)
+ self.linear = operations.Linear(final_hidden_size, out_channels, bias = True, device = device, dtype = dtype)
+
+ def forward(self, x):
+ x = self.norm_final(x)
+ x = x[:, 1:]
+ x = self.linear(x)
+ return x
+
+class HunYuanDiTPlain(nn.Module):
+
+ # init with the defaults values from https://huggingface.co/tencent/Hunyuan3D-2.1/blob/main/hunyuan3d-dit-v2-1/config.yaml
+ def __init__(
+ self,
+ in_channels: int = 64,
+ hidden_size: int = 2048,
+ context_dim: int = 1024,
+ depth: int = 21,
+ num_heads: int = 16,
+ qk_norm: bool = True,
+ qkv_bias: bool = False,
+ num_moe_layers: int = 6,
+ guidance_cond_proj_dim = 2048,
+ norm_type = 'layer',
+ num_experts: int = 8,
+ moe_top_k: int = 2,
+ use_fp16: bool = False,
+ dtype = None,
+ device = None,
+ operations = None,
+ **kwargs
+ ):
+
+ self.dtype = dtype
+
+ super().__init__()
+
+ self.depth = depth
+
+ self.in_channels = in_channels
+ self.out_channels = in_channels
+
+ self.num_heads = num_heads
+ self.hidden_size = hidden_size
+
+ norm = operations.LayerNorm if norm_type == 'layer' else operations.RMSNorm
+ qk_norm = operations.RMSNorm
+
+ self.context_dim = context_dim
+ self.guidance_cond_proj_dim = guidance_cond_proj_dim
+
+ self.x_embedder = operations.Linear(in_channels, hidden_size, bias = True, device = device, dtype = dtype)
+ self.t_embedder = TimestepEmbedder(hidden_size, hidden_size * 4, cond_proj_dim = guidance_cond_proj_dim, device = device, dtype = dtype, operations = operations)
+
+
+ # HUnYuanDiT Blocks
+ self.blocks = nn.ModuleList([
+ HunYuanDiTBlock(hidden_size=hidden_size,
+ c_emb_size=hidden_size,
+ num_heads=num_heads,
+ text_states_dim=context_dim,
+ qk_norm=qk_norm,
+ norm_layer = norm,
+ qk_norm_layer = qk_norm,
+ skip_connection=layer > depth // 2,
+ qkv_bias=qkv_bias,
+ use_moe=True if depth - layer <= num_moe_layers else False,
+ num_experts=num_experts,
+ moe_top_k=moe_top_k,
+ use_fp16 = use_fp16,
+ device = device, dtype = dtype, operations = operations)
+ for layer in range(depth)
+ ])
+
+ self.depth = depth
+
+ self.final_layer = FinalLayer(hidden_size, self.out_channels, use_fp16 = use_fp16, operations = operations, device = device, dtype = dtype)
+
+ def forward(self, x, t, context, transformer_options = {}, **kwargs):
+
+ x = x.movedim(-1, -2)
+
+ swap_cfg_halves = context.shape[0] >= 2
+
+ if swap_cfg_halves:
+ first_half, second_half = context.chunk(2, dim = 0)
+ context = torch.cat([second_half, first_half], dim = 0)
+
+ main_condition = context
+
+ t = 1.0 - t
+
+ time_embedded = self.t_embedder(t, condition = kwargs.get('guidance_cond'))
+
+ x = x.to(dtype = next(self.x_embedder.parameters()).dtype)
+ x_embedded = self.x_embedder(x)
+
+ combined = torch.cat([time_embedded, x_embedded], dim=1)
+
+ def block_wrap(args):
+ return block(
+ args["x"],
+ args["t"],
+ args["cond"],
+ skip_tensor=args.get("skip"),)
+
+ skip_stack = []
+ patches_replace = transformer_options.get("patches_replace", {})
+ blocks_replace = patches_replace.get("dit", {})
+ for idx, block in enumerate(self.blocks):
+ if idx <= self.depth // 2:
+ skip_input = None
+ else:
+ skip_input = skip_stack.pop()
+
+ if ("block", idx) in blocks_replace:
+
+ combined = blocks_replace[("block", idx)](
+ {
+ "x": combined,
+ "t": time_embedded,
+ "cond": main_condition,
+ "skip": skip_input,
+ },
+ {"original_block": block_wrap},
+ )
+ else:
+ combined = block(combined, time_embedded, main_condition, skip_tensor=skip_input)
+
+ if idx < self.depth // 2:
+ skip_stack.append(combined)
+
+ output = self.final_layer(combined)
+ output = output.movedim(-2, -1) * (-1.0)
+
+ if swap_cfg_halves:
+ first_half, second_half = output.chunk(2, dim = 0)
+ output = torch.cat([second_half, first_half], dim = 0)
+
+ return output
diff --git a/ComfyUI/comfy/ldm/hunyuan_video/__pycache__/model.cpython-312.pyc b/ComfyUI/comfy/ldm/hunyuan_video/__pycache__/model.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..e30188ba1e34137baf19b0ea3e2b2a4ecf4292be
Binary files /dev/null and b/ComfyUI/comfy/ldm/hunyuan_video/__pycache__/model.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/hunyuan_video/__pycache__/upsampler.cpython-312.pyc b/ComfyUI/comfy/ldm/hunyuan_video/__pycache__/upsampler.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..fb87bfaf534909685ef5831644339b3e537b8ca5
Binary files /dev/null and b/ComfyUI/comfy/ldm/hunyuan_video/__pycache__/upsampler.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/hunyuan_video/__pycache__/vae.cpython-312.pyc b/ComfyUI/comfy/ldm/hunyuan_video/__pycache__/vae.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..2e99cdf0db1928af868a3e8b8d92dc83a3ee43f0
Binary files /dev/null and b/ComfyUI/comfy/ldm/hunyuan_video/__pycache__/vae.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/hunyuan_video/__pycache__/vae_refiner.cpython-312.pyc b/ComfyUI/comfy/ldm/hunyuan_video/__pycache__/vae_refiner.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..5be0072d1e31f79b1b8c6dafc9908bc8e5eb2756
Binary files /dev/null and b/ComfyUI/comfy/ldm/hunyuan_video/__pycache__/vae_refiner.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/hunyuan_video/model.py b/ComfyUI/comfy/ldm/hunyuan_video/model.py
new file mode 100644
index 0000000000000000000000000000000000000000..b94cdfa8762e2cab70811b529dc8b6aef459410b
--- /dev/null
+++ b/ComfyUI/comfy/ldm/hunyuan_video/model.py
@@ -0,0 +1,497 @@
+#Based on Flux code because of weird hunyuan video code license.
+
+import torch
+import comfy.patcher_extension
+import comfy.ldm.flux.layers
+import comfy.ldm.modules.diffusionmodules.mmdit
+from comfy.ldm.modules.attention import optimized_attention
+
+from dataclasses import dataclass
+from einops import repeat
+
+from torch import Tensor, nn
+
+from comfy.ldm.flux.layers import (
+ DoubleStreamBlock,
+ EmbedND,
+ LastLayer,
+ MLPEmbedder,
+ SingleStreamBlock,
+ timestep_embedding
+)
+
+import comfy.ldm.common_dit
+
+
+@dataclass
+class HunyuanVideoParams:
+ in_channels: int
+ out_channels: int
+ vec_in_dim: int
+ context_in_dim: int
+ hidden_size: int
+ mlp_ratio: float
+ num_heads: int
+ depth: int
+ depth_single_blocks: int
+ axes_dim: list
+ theta: int
+ patch_size: list
+ qkv_bias: bool
+ guidance_embed: bool
+ byt5: bool
+ meanflow: bool
+ use_cond_type_embedding: bool
+ vision_in_dim: int
+ meanflow_sum: bool
+
+
+class SelfAttentionRef(nn.Module):
+ def __init__(self, dim: int, qkv_bias: bool = False, dtype=None, device=None, operations=None):
+ super().__init__()
+ self.qkv = operations.Linear(dim, dim * 3, bias=qkv_bias, dtype=dtype, device=device)
+ self.proj = operations.Linear(dim, dim, dtype=dtype, device=device)
+
+
+class TokenRefinerBlock(nn.Module):
+ def __init__(
+ self,
+ hidden_size,
+ heads,
+ dtype=None,
+ device=None,
+ operations=None
+ ):
+ super().__init__()
+ self.heads = heads
+ mlp_hidden_dim = hidden_size * 4
+
+ self.adaLN_modulation = nn.Sequential(
+ nn.SiLU(),
+ operations.Linear(hidden_size, 2 * hidden_size, bias=True, dtype=dtype, device=device),
+ )
+
+ self.norm1 = operations.LayerNorm(hidden_size, elementwise_affine=True, eps=1e-6, dtype=dtype, device=device)
+ self.self_attn = SelfAttentionRef(hidden_size, True, dtype=dtype, device=device, operations=operations)
+
+ self.norm2 = operations.LayerNorm(hidden_size, elementwise_affine=True, eps=1e-6, dtype=dtype, device=device)
+
+ self.mlp = nn.Sequential(
+ operations.Linear(hidden_size, mlp_hidden_dim, bias=True, dtype=dtype, device=device),
+ nn.SiLU(),
+ operations.Linear(mlp_hidden_dim, hidden_size, bias=True, dtype=dtype, device=device),
+ )
+
+ def forward(self, x, c, mask, transformer_options={}):
+ mod1, mod2 = self.adaLN_modulation(c).chunk(2, dim=1)
+
+ norm_x = self.norm1(x)
+ qkv = self.self_attn.qkv(norm_x)
+ q, k, v = qkv.reshape(qkv.shape[0], qkv.shape[1], 3, self.heads, -1).permute(2, 0, 3, 1, 4)
+ attn = optimized_attention(q, k, v, self.heads, mask=mask, skip_reshape=True, transformer_options=transformer_options)
+
+ x = x + self.self_attn.proj(attn) * mod1.unsqueeze(1)
+ x = x + self.mlp(self.norm2(x)) * mod2.unsqueeze(1)
+ return x
+
+
+class IndividualTokenRefiner(nn.Module):
+ def __init__(
+ self,
+ hidden_size,
+ heads,
+ num_blocks,
+ dtype=None,
+ device=None,
+ operations=None
+ ):
+ super().__init__()
+ self.blocks = nn.ModuleList(
+ [
+ TokenRefinerBlock(
+ hidden_size=hidden_size,
+ heads=heads,
+ dtype=dtype,
+ device=device,
+ operations=operations
+ )
+ for _ in range(num_blocks)
+ ]
+ )
+
+ def forward(self, x, c, mask, transformer_options={}):
+ m = None
+ if mask is not None:
+ m = mask.view(mask.shape[0], 1, 1, mask.shape[1]).repeat(1, 1, mask.shape[1], 1)
+ m = m + m.transpose(2, 3)
+
+ for block in self.blocks:
+ x = block(x, c, m, transformer_options=transformer_options)
+ return x
+
+
+
+class TokenRefiner(nn.Module):
+ def __init__(
+ self,
+ text_dim,
+ hidden_size,
+ heads,
+ num_blocks,
+ dtype=None,
+ device=None,
+ operations=None
+ ):
+ super().__init__()
+
+ self.input_embedder = operations.Linear(text_dim, hidden_size, bias=True, dtype=dtype, device=device)
+ self.t_embedder = MLPEmbedder(256, hidden_size, dtype=dtype, device=device, operations=operations)
+ self.c_embedder = MLPEmbedder(text_dim, hidden_size, dtype=dtype, device=device, operations=operations)
+ self.individual_token_refiner = IndividualTokenRefiner(hidden_size, heads, num_blocks, dtype=dtype, device=device, operations=operations)
+
+ def forward(
+ self,
+ x,
+ timesteps,
+ mask,
+ transformer_options={},
+ ):
+ t = self.t_embedder(timestep_embedding(timesteps, 256, time_factor=1.0).to(x.dtype))
+ # m = mask.float().unsqueeze(-1)
+ # c = (x.float() * m).sum(dim=1) / m.sum(dim=1) #TODO: the following works when the x.shape is the same length as the tokens but might break otherwise
+ if x.dtype == torch.float16:
+ c = x.float().sum(dim=1) / x.shape[1]
+ else:
+ c = x.sum(dim=1) / x.shape[1]
+
+ c = t + self.c_embedder(c.to(x.dtype))
+ x = self.input_embedder(x)
+ x = self.individual_token_refiner(x, c, mask, transformer_options=transformer_options)
+ return x
+
+
+class ByT5Mapper(nn.Module):
+ def __init__(self, in_dim, out_dim, hidden_dim, out_dim1, use_res=False, dtype=None, device=None, operations=None):
+ super().__init__()
+ self.layernorm = operations.LayerNorm(in_dim, dtype=dtype, device=device)
+ self.fc1 = operations.Linear(in_dim, hidden_dim, dtype=dtype, device=device)
+ self.fc2 = operations.Linear(hidden_dim, out_dim, dtype=dtype, device=device)
+ self.fc3 = operations.Linear(out_dim, out_dim1, dtype=dtype, device=device)
+ self.use_res = use_res
+ self.act_fn = nn.GELU()
+
+ def forward(self, x):
+ if self.use_res:
+ res = x
+ x = self.layernorm(x)
+ x = self.fc1(x)
+ x = self.act_fn(x)
+ x = self.fc2(x)
+ x2 = self.act_fn(x)
+ x2 = self.fc3(x2)
+ if self.use_res:
+ x2 = x2 + res
+ return x2
+
+class HunyuanVideo(nn.Module):
+ """
+ Transformer model for flow matching on sequences.
+ """
+
+ def __init__(self, image_model=None, final_layer=True, dtype=None, device=None, operations=None, **kwargs):
+ super().__init__()
+ self.dtype = dtype
+ operation_settings = {"operations": operations, "device": device, "dtype": dtype}
+
+ params = HunyuanVideoParams(**kwargs)
+ self.params = params
+ self.patch_size = params.patch_size
+ self.in_channels = params.in_channels
+ self.out_channels = params.out_channels
+ self.use_cond_type_embedding = params.use_cond_type_embedding
+ self.vision_in_dim = params.vision_in_dim
+ if params.hidden_size % params.num_heads != 0:
+ raise ValueError(
+ f"Hidden size {params.hidden_size} must be divisible by num_heads {params.num_heads}"
+ )
+ pe_dim = params.hidden_size // params.num_heads
+ if sum(params.axes_dim) != pe_dim:
+ raise ValueError(f"Got {params.axes_dim} but expected positional dim {pe_dim}")
+ self.hidden_size = params.hidden_size
+ self.num_heads = params.num_heads
+ self.pe_embedder = EmbedND(dim=pe_dim, theta=params.theta, axes_dim=params.axes_dim)
+
+ self.img_in = comfy.ldm.modules.diffusionmodules.mmdit.PatchEmbed(None, self.patch_size, self.in_channels, self.hidden_size, conv3d=len(self.patch_size) == 3, dtype=dtype, device=device, operations=operations)
+ self.time_in = MLPEmbedder(in_dim=256, hidden_dim=self.hidden_size, dtype=dtype, device=device, operations=operations)
+ if params.vec_in_dim is not None:
+ self.vector_in = MLPEmbedder(params.vec_in_dim, self.hidden_size, dtype=dtype, device=device, operations=operations)
+ else:
+ self.vector_in = None
+
+ self.guidance_in = (
+ MLPEmbedder(in_dim=256, hidden_dim=self.hidden_size, dtype=dtype, device=device, operations=operations) if params.guidance_embed else nn.Identity()
+ )
+
+ self.txt_in = TokenRefiner(params.context_in_dim, self.hidden_size, self.num_heads, 2, dtype=dtype, device=device, operations=operations)
+
+ self.double_blocks = nn.ModuleList(
+ [
+ DoubleStreamBlock(
+ self.hidden_size,
+ self.num_heads,
+ mlp_ratio=params.mlp_ratio,
+ qkv_bias=params.qkv_bias,
+ dtype=dtype, device=device, operations=operations
+ )
+ for _ in range(params.depth)
+ ]
+ )
+
+ self.single_blocks = nn.ModuleList(
+ [
+ SingleStreamBlock(self.hidden_size, self.num_heads, mlp_ratio=params.mlp_ratio, dtype=dtype, device=device, operations=operations)
+ for _ in range(params.depth_single_blocks)
+ ]
+ )
+
+ if params.byt5:
+ self.byt5_in = ByT5Mapper(
+ in_dim=1472,
+ out_dim=2048,
+ hidden_dim=2048,
+ out_dim1=self.hidden_size,
+ use_res=False,
+ dtype=dtype, device=device, operations=operations
+ )
+ else:
+ self.byt5_in = None
+
+ if params.meanflow:
+ self.time_r_in = MLPEmbedder(in_dim=256, hidden_dim=self.hidden_size, dtype=dtype, device=device, operations=operations)
+ else:
+ self.time_r_in = None
+
+ if final_layer:
+ self.final_layer = LastLayer(self.hidden_size, self.patch_size[-1], self.out_channels, dtype=dtype, device=device, operations=operations)
+
+ # HunyuanVideo 1.5 specific modules
+ if self.vision_in_dim is not None:
+ from comfy.ldm.wan.model import MLPProj
+ self.vision_in = MLPProj(in_dim=self.vision_in_dim, out_dim=self.hidden_size, operation_settings=operation_settings)
+ else:
+ self.vision_in = None
+ if self.use_cond_type_embedding:
+ # 0: text_encoder feature 1: byt5 feature 2: vision_encoder feature
+ self.cond_type_embedding = nn.Embedding(3, self.hidden_size)
+ else:
+ self.cond_type_embedding = None
+
+ def forward_orig(
+ self,
+ img: Tensor,
+ img_ids: Tensor,
+ txt: Tensor,
+ txt_ids: Tensor,
+ txt_mask: Tensor,
+ timesteps: Tensor,
+ y: Tensor = None,
+ txt_byt5=None,
+ clip_fea=None,
+ guidance: Tensor = None,
+ guiding_frame_index=None,
+ ref_latent=None,
+ disable_time_r=False,
+ control=None,
+ transformer_options={},
+ ) -> Tensor:
+ transformer_options = transformer_options.copy()
+ patches_replace = transformer_options.get("patches_replace", {})
+
+ initial_shape = list(img.shape)
+ # running on sequences img
+ img = self.img_in(img)
+ vec = self.time_in(timestep_embedding(timesteps, 256, time_factor=1.0).to(img.dtype))
+
+ if (self.time_r_in is not None) and (not disable_time_r):
+ w = torch.where(transformer_options['sigmas'][0] == transformer_options['sample_sigmas'])[0] # This most likely could be improved
+ if len(w) > 0:
+ timesteps_r = transformer_options['sample_sigmas'][w[0] + 1]
+ timesteps_r = timesteps_r.unsqueeze(0).to(device=timesteps.device, dtype=timesteps.dtype)
+ vec_r = self.time_r_in(timestep_embedding(timesteps_r, 256, time_factor=1000.0).to(img.dtype))
+ vec = (vec + vec_r) if self.params.meanflow_sum else (vec + vec_r) / 2
+
+ if ref_latent is not None:
+ ref_latent_ids = self.img_ids(ref_latent)
+ ref_latent = self.img_in(ref_latent)
+ img = torch.cat([ref_latent, img], dim=-2)
+ ref_latent_ids[..., 0] = -1
+ ref_latent_ids[..., 2] += (initial_shape[-1] // self.patch_size[-1])
+ img_ids = torch.cat([ref_latent_ids, img_ids], dim=-2)
+
+ if guiding_frame_index is not None:
+ token_replace_vec = self.time_in(timestep_embedding(guiding_frame_index, 256, time_factor=1.0))
+ if self.vector_in is not None:
+ vec_ = self.vector_in(y[:, :self.params.vec_in_dim])
+ vec = torch.cat([(vec_ + token_replace_vec).unsqueeze(1), (vec_ + vec).unsqueeze(1)], dim=1)
+ else:
+ vec = torch.cat([(token_replace_vec).unsqueeze(1), (vec).unsqueeze(1)], dim=1)
+ frame_tokens = (initial_shape[-1] // self.patch_size[-1]) * (initial_shape[-2] // self.patch_size[-2])
+ modulation_dims = [(0, frame_tokens, 0), (frame_tokens, None, 1)]
+ modulation_dims_txt = [(0, None, 1)]
+ else:
+ if self.vector_in is not None:
+ vec = vec + self.vector_in(y[:, :self.params.vec_in_dim])
+ modulation_dims = None
+ modulation_dims_txt = None
+
+ if self.params.guidance_embed:
+ if guidance is not None:
+ vec = vec + self.guidance_in(timestep_embedding(guidance, 256).to(img.dtype))
+
+ if txt_mask is not None and not torch.is_floating_point(txt_mask):
+ txt_mask = (txt_mask - 1).to(img.dtype) * torch.finfo(img.dtype).max
+
+ txt = self.txt_in(txt, timesteps, txt_mask, transformer_options=transformer_options)
+
+ if self.cond_type_embedding is not None:
+ self.cond_type_embedding.to(txt.device)
+ cond_emb = self.cond_type_embedding(torch.zeros_like(txt[:, :, 0], device=txt.device, dtype=torch.long))
+ txt = txt + cond_emb.to(txt.dtype)
+
+ if self.byt5_in is not None and txt_byt5 is not None:
+ txt_byt5 = self.byt5_in(txt_byt5)
+ if self.cond_type_embedding is not None:
+ cond_emb = self.cond_type_embedding(torch.ones_like(txt_byt5[:, :, 0], device=txt_byt5.device, dtype=torch.long))
+ txt_byt5 = txt_byt5 + cond_emb.to(txt_byt5.dtype)
+ txt = torch.cat((txt_byt5, txt), dim=1) # byt5 first for HunyuanVideo1.5
+ else:
+ txt = torch.cat((txt, txt_byt5), dim=1)
+ txt_byt5_ids = torch.zeros((txt_ids.shape[0], txt_byt5.shape[1], txt_ids.shape[-1]), device=txt_ids.device, dtype=txt_ids.dtype)
+ txt_ids = torch.cat((txt_ids, txt_byt5_ids), dim=1)
+
+ if clip_fea is not None:
+ txt_vision_states = self.vision_in(clip_fea)
+ if self.cond_type_embedding is not None:
+ cond_emb = self.cond_type_embedding(2 * torch.ones_like(txt_vision_states[:, :, 0], dtype=torch.long, device=txt_vision_states.device))
+ txt_vision_states = txt_vision_states + cond_emb
+ txt = torch.cat((txt_vision_states.to(txt.dtype), txt), dim=1)
+ extra_txt_ids = torch.zeros((txt_ids.shape[0], txt_vision_states.shape[1], txt_ids.shape[-1]), device=txt_ids.device, dtype=txt_ids.dtype)
+ txt_ids = torch.cat((txt_ids, extra_txt_ids), dim=1)
+
+ ids = torch.cat((txt_ids, img_ids), dim=1)
+ pe = self.pe_embedder(ids)
+
+ img_len = img.shape[1]
+ if txt_mask is not None:
+ attn_mask_len = img_len + txt.shape[1]
+ attn_mask = torch.zeros((1, 1, attn_mask_len), dtype=img.dtype, device=img.device)
+ attn_mask[:, 0, :txt.shape[1]] = txt_mask
+ else:
+ attn_mask = None
+
+ blocks_replace = patches_replace.get("dit", {})
+ transformer_options["total_blocks"] = len(self.double_blocks)
+ transformer_options["block_type"] = "double"
+ for i, block in enumerate(self.double_blocks):
+ transformer_options["block_index"] = i
+ if ("double_block", i) in blocks_replace:
+ def block_wrap(args):
+ out = {}
+ out["img"], out["txt"] = block(img=args["img"], txt=args["txt"], vec=args["vec"], pe=args["pe"], attn_mask=args["attention_mask"], modulation_dims_img=args["modulation_dims_img"], modulation_dims_txt=args["modulation_dims_txt"], transformer_options=args["transformer_options"])
+ return out
+
+ out = blocks_replace[("double_block", i)]({"img": img, "txt": txt, "vec": vec, "pe": pe, "attention_mask": attn_mask, 'modulation_dims_img': modulation_dims, 'modulation_dims_txt': modulation_dims_txt, 'transformer_options': transformer_options}, {"original_block": block_wrap})
+ txt = out["txt"]
+ img = out["img"]
+ else:
+ img, txt = block(img=img, txt=txt, vec=vec, pe=pe, attn_mask=attn_mask, modulation_dims_img=modulation_dims, modulation_dims_txt=modulation_dims_txt, transformer_options=transformer_options)
+
+ if control is not None: # Controlnet
+ control_i = control.get("input")
+ if i < len(control_i):
+ add = control_i[i]
+ if add is not None:
+ img += add
+
+ img = torch.cat((txt, img), 1)
+
+ transformer_options["total_blocks"] = len(self.single_blocks)
+ transformer_options["block_type"] = "single"
+ transformer_options["img_slice"] = [txt.shape[1], img.shape[1]]
+ for i, block in enumerate(self.single_blocks):
+ transformer_options["block_index"] = i
+ if ("single_block", i) in blocks_replace:
+ def block_wrap(args):
+ out = {}
+ out["img"] = block(args["img"], vec=args["vec"], pe=args["pe"], attn_mask=args["attention_mask"], modulation_dims=args["modulation_dims"], transformer_options=args["transformer_options"])
+ return out
+
+ out = blocks_replace[("single_block", i)]({"img": img, "vec": vec, "pe": pe, "attention_mask": attn_mask, 'modulation_dims': modulation_dims, 'transformer_options': transformer_options}, {"original_block": block_wrap})
+ img = out["img"]
+ else:
+ img = block(img, vec=vec, pe=pe, attn_mask=attn_mask, modulation_dims=modulation_dims, transformer_options=transformer_options)
+
+ if control is not None: # Controlnet
+ control_o = control.get("output")
+ if i < len(control_o):
+ add = control_o[i]
+ if add is not None:
+ img[:, txt.shape[1]: img_len + txt.shape[1]] += add
+
+ img = img[:, txt.shape[1]: img_len + txt.shape[1]]
+ if ref_latent is not None:
+ img = img[:, ref_latent.shape[1]:]
+
+ img = self.final_layer(img, vec, modulation_dims=modulation_dims) # (N, T, patch_size ** 2 * out_channels)
+
+ shape = initial_shape[-len(self.patch_size):]
+ for i in range(len(shape)):
+ shape[i] = shape[i] // self.patch_size[i]
+ img = img.reshape([img.shape[0]] + shape + [self.out_channels] + self.patch_size)
+ if img.ndim == 8:
+ img = img.permute(0, 4, 1, 5, 2, 6, 3, 7)
+ img = img.reshape(initial_shape[0], self.out_channels, initial_shape[2], initial_shape[3], initial_shape[4])
+ else:
+ img = img.permute(0, 3, 1, 4, 2, 5)
+ img = img.reshape(initial_shape[0], self.out_channels, initial_shape[2], initial_shape[3])
+ return img
+
+ def img_ids(self, x):
+ bs, c, t, h, w = x.shape
+ patch_size = self.patch_size
+ t_len = ((t + (patch_size[0] // 2)) // patch_size[0])
+ h_len = ((h + (patch_size[1] // 2)) // patch_size[1])
+ w_len = ((w + (patch_size[2] // 2)) // patch_size[2])
+ img_ids = torch.zeros((t_len, h_len, w_len, 3), device=x.device, dtype=x.dtype)
+ img_ids[:, :, :, 0] = img_ids[:, :, :, 0] + torch.linspace(0, t_len - 1, steps=t_len, device=x.device, dtype=x.dtype).reshape(-1, 1, 1)
+ img_ids[:, :, :, 1] = img_ids[:, :, :, 1] + torch.linspace(0, h_len - 1, steps=h_len, device=x.device, dtype=x.dtype).reshape(1, -1, 1)
+ img_ids[:, :, :, 2] = img_ids[:, :, :, 2] + torch.linspace(0, w_len - 1, steps=w_len, device=x.device, dtype=x.dtype).reshape(1, 1, -1)
+ return repeat(img_ids, "t h w c -> b (t h w) c", b=bs)
+
+ def img_ids_2d(self, x):
+ bs, c, h, w = x.shape
+ patch_size = self.patch_size
+ h_len = ((h + (patch_size[0] // 2)) // patch_size[0])
+ w_len = ((w + (patch_size[1] // 2)) // patch_size[1])
+ img_ids = torch.zeros((h_len, w_len, 2), device=x.device, dtype=x.dtype)
+ img_ids[:, :, 0] = img_ids[:, :, 0] + torch.linspace(0, h_len - 1, steps=h_len, device=x.device, dtype=x.dtype).unsqueeze(1)
+ img_ids[:, :, 1] = img_ids[:, :, 1] + torch.linspace(0, w_len - 1, steps=w_len, device=x.device, dtype=x.dtype).unsqueeze(0)
+ return repeat(img_ids, "h w c -> b (h w) c", b=bs)
+
+ def forward(self, x, timestep, context, y=None, txt_byt5=None, clip_fea=None, guidance=None, attention_mask=None, guiding_frame_index=None, ref_latent=None, disable_time_r=False, control=None, transformer_options={}, **kwargs):
+ return comfy.patcher_extension.WrapperExecutor.new_class_executor(
+ self._forward,
+ self,
+ comfy.patcher_extension.get_all_wrappers(comfy.patcher_extension.WrappersMP.DIFFUSION_MODEL, transformer_options)
+ ).execute(x, timestep, context, y, txt_byt5, clip_fea, guidance, attention_mask, guiding_frame_index, ref_latent, disable_time_r, control, transformer_options, **kwargs)
+
+ def _forward(self, x, timestep, context, y=None, txt_byt5=None, clip_fea=None, guidance=None, attention_mask=None, guiding_frame_index=None, ref_latent=None, disable_time_r=False, control=None, transformer_options={}, **kwargs):
+ bs = x.shape[0]
+ if len(self.patch_size) == 3:
+ img_ids = self.img_ids(x)
+ txt_ids = torch.zeros((bs, context.shape[1], 3), device=x.device, dtype=x.dtype)
+ else:
+ img_ids = self.img_ids_2d(x)
+ txt_ids = torch.zeros((bs, context.shape[1], 2), device=x.device, dtype=x.dtype)
+ out = self.forward_orig(x, img_ids, context, txt_ids, attention_mask, timestep, y, txt_byt5, clip_fea, guidance, guiding_frame_index, ref_latent, disable_time_r=disable_time_r, control=control, transformer_options=transformer_options)
+ return out
diff --git a/ComfyUI/comfy/ldm/hunyuan_video/upsampler.py b/ComfyUI/comfy/ldm/hunyuan_video/upsampler.py
new file mode 100644
index 0000000000000000000000000000000000000000..1f68144e2cbe8b1517c996dda4badf7888477c32
--- /dev/null
+++ b/ComfyUI/comfy/ldm/hunyuan_video/upsampler.py
@@ -0,0 +1,122 @@
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+from comfy.ldm.modules.diffusionmodules.model import ResnetBlock, VideoConv3d
+from comfy.ldm.hunyuan_video.vae_refiner import RMS_norm
+import comfy.model_management
+import comfy.model_patcher
+
+class SRResidualCausalBlock3D(nn.Module):
+ def __init__(self, channels: int):
+ super().__init__()
+ self.block = nn.Sequential(
+ VideoConv3d(channels, channels, kernel_size=3),
+ nn.SiLU(inplace=True),
+ VideoConv3d(channels, channels, kernel_size=3),
+ nn.SiLU(inplace=True),
+ VideoConv3d(channels, channels, kernel_size=3),
+ )
+
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
+ return x + self.block(x)
+
+class SRModel3DV2(nn.Module):
+ def __init__(
+ self,
+ in_channels: int,
+ out_channels: int,
+ hidden_channels: int = 64,
+ num_blocks: int = 6,
+ global_residual: bool = False,
+ ):
+ super().__init__()
+ self.in_conv = VideoConv3d(in_channels, hidden_channels, kernel_size=3)
+ self.blocks = nn.ModuleList([SRResidualCausalBlock3D(hidden_channels) for _ in range(num_blocks)])
+ self.out_conv = VideoConv3d(hidden_channels, out_channels, kernel_size=3)
+ self.global_residual = bool(global_residual)
+
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
+ residual = x
+ y = self.in_conv(x)
+ for blk in self.blocks:
+ y = blk(y)
+ y = self.out_conv(y)
+ if self.global_residual and (y.shape == residual.shape):
+ y = y + residual
+ return y
+
+
+class Upsampler(nn.Module):
+ def __init__(
+ self,
+ z_channels: int,
+ out_channels: int,
+ block_out_channels: tuple[int, ...],
+ num_res_blocks: int = 2,
+ ):
+ super().__init__()
+ self.num_res_blocks = num_res_blocks
+ self.block_out_channels = block_out_channels
+ self.z_channels = z_channels
+
+ ch = block_out_channels[0]
+ self.conv_in = VideoConv3d(z_channels, ch, kernel_size=3)
+
+ self.up = nn.ModuleList()
+
+ for i, tgt in enumerate(block_out_channels):
+ stage = nn.Module()
+ stage.block = nn.ModuleList([ResnetBlock(in_channels=ch if j == 0 else tgt,
+ out_channels=tgt,
+ temb_channels=0,
+ conv_shortcut=False,
+ conv_op=VideoConv3d, norm_op=RMS_norm)
+ for j in range(num_res_blocks + 1)])
+ ch = tgt
+ self.up.append(stage)
+
+ self.norm_out = RMS_norm(ch)
+ self.conv_out = VideoConv3d(ch, out_channels, kernel_size=3)
+
+ def forward(self, z):
+ """
+ Args:
+ z: (B, C, T, H, W)
+ target_shape: (H, W)
+ """
+ # z to block_in
+ repeats = self.block_out_channels[0] // (self.z_channels)
+ x = self.conv_in(z) + z.repeat_interleave(repeats=repeats, dim=1)
+
+ # upsampling
+ for stage in self.up:
+ for blk in stage.block:
+ x = blk(x)
+
+ out = self.conv_out(F.silu(self.norm_out(x)))
+ return out
+
+UPSAMPLERS = {
+ "720p": SRModel3DV2,
+ "1080p": Upsampler,
+}
+
+class HunyuanVideo15SRModel():
+ def __init__(self, model_type, config):
+ self.load_device = comfy.model_management.vae_device()
+ offload_device = comfy.model_management.vae_offload_device()
+ self.dtype = comfy.model_management.vae_dtype(self.load_device)
+ self.model_class = UPSAMPLERS.get(model_type)
+ self.model = self.model_class(**config).eval()
+
+ self.patcher = comfy.model_patcher.CoreModelPatcher(self.model, load_device=self.load_device, offload_device=offload_device)
+
+ def load_sd(self, sd):
+ return self.model.load_state_dict(sd, strict=True, assign=self.patcher.is_dynamic())
+
+ def get_sd(self):
+ return self.model.state_dict()
+
+ def resample_latent(self, latent):
+ comfy.model_management.load_model_gpu(self.patcher)
+ return self.model(latent.to(self.load_device))
diff --git a/ComfyUI/comfy/ldm/hunyuan_video/vae.py b/ComfyUI/comfy/ldm/hunyuan_video/vae.py
new file mode 100644
index 0000000000000000000000000000000000000000..40c12b18334dcc003a59c882b63c7044fe5e679e
--- /dev/null
+++ b/ComfyUI/comfy/ldm/hunyuan_video/vae.py
@@ -0,0 +1,136 @@
+import torch.nn as nn
+import torch.nn.functional as F
+from comfy.ldm.modules.diffusionmodules.model import ResnetBlock, AttnBlock
+import comfy.ops
+ops = comfy.ops.disable_weight_init
+
+
+class PixelShuffle2D(nn.Module):
+ def __init__(self, in_dim, out_dim, op=ops.Conv2d):
+ super().__init__()
+ self.conv = op(in_dim, out_dim >> 2, 3, 1, 1)
+ self.ratio = (in_dim << 2) // out_dim
+
+ def forward(self, x):
+ b, c, h, w = x.shape
+ h2, w2 = h >> 1, w >> 1
+ y = self.conv(x).view(b, -1, h2, 2, w2, 2).permute(0, 3, 5, 1, 2, 4).reshape(b, -1, h2, w2)
+ r = x.view(b, c, h2, 2, w2, 2).permute(0, 3, 5, 1, 2, 4).reshape(b, c << 2, h2, w2)
+ return y + r.view(b, y.shape[1], self.ratio, h2, w2).mean(2)
+
+
+class PixelUnshuffle2D(nn.Module):
+ def __init__(self, in_dim, out_dim, op=ops.Conv2d):
+ super().__init__()
+ self.conv = op(in_dim, out_dim << 2, 3, 1, 1)
+ self.scale = (out_dim << 2) // in_dim
+
+ def forward(self, x):
+ b, c, h, w = x.shape
+ h2, w2 = h << 1, w << 1
+ y = self.conv(x).view(b, 2, 2, -1, h, w).permute(0, 3, 4, 1, 5, 2).reshape(b, -1, h2, w2)
+ r = x.repeat_interleave(self.scale, 1).view(b, 2, 2, -1, h, w).permute(0, 3, 4, 1, 5, 2).reshape(b, -1, h2, w2)
+ return y + r
+
+
+class Encoder(nn.Module):
+ def __init__(self, in_channels, z_channels, block_out_channels, num_res_blocks,
+ ffactor_spatial, downsample_match_channel=True, **_):
+ super().__init__()
+ self.z_channels = z_channels
+ self.block_out_channels = block_out_channels
+ self.num_res_blocks = num_res_blocks
+ self.conv_in = ops.Conv2d(in_channels, block_out_channels[0], 3, 1, 1)
+
+ self.down = nn.ModuleList()
+ ch = block_out_channels[0]
+ depth = (ffactor_spatial >> 1).bit_length()
+
+ for i, tgt in enumerate(block_out_channels):
+ stage = nn.Module()
+ stage.block = nn.ModuleList([ResnetBlock(in_channels=ch if j == 0 else tgt,
+ out_channels=tgt,
+ temb_channels=0,
+ conv_op=ops.Conv2d)
+ for j in range(num_res_blocks)])
+ ch = tgt
+ if i < depth:
+ nxt = block_out_channels[i + 1] if i + 1 < len(block_out_channels) and downsample_match_channel else ch
+ stage.downsample = PixelShuffle2D(ch, nxt, ops.Conv2d)
+ ch = nxt
+ self.down.append(stage)
+
+ self.mid = nn.Module()
+ self.mid.block_1 = ResnetBlock(in_channels=ch, out_channels=ch, temb_channels=0, conv_op=ops.Conv2d)
+ self.mid.attn_1 = AttnBlock(ch, conv_op=ops.Conv2d)
+ self.mid.block_2 = ResnetBlock(in_channels=ch, out_channels=ch, temb_channels=0, conv_op=ops.Conv2d)
+
+ self.norm_out = ops.GroupNorm(32, ch, 1e-6, True)
+ self.conv_out = ops.Conv2d(ch, z_channels << 1, 3, 1, 1)
+
+ def forward(self, x):
+ x = self.conv_in(x)
+
+ for stage in self.down:
+ for blk in stage.block:
+ x = blk(x)
+ if hasattr(stage, 'downsample'):
+ x = stage.downsample(x)
+
+ x = self.mid.block_2(self.mid.attn_1(self.mid.block_1(x)))
+
+ b, c, h, w = x.shape
+ grp = c // (self.z_channels << 1)
+ skip = x.view(b, c // grp, grp, h, w).mean(2)
+
+ return self.conv_out(F.silu(self.norm_out(x))) + skip
+
+
+class Decoder(nn.Module):
+ def __init__(self, z_channels, out_channels, block_out_channels, num_res_blocks,
+ ffactor_spatial, upsample_match_channel=True, **_):
+ super().__init__()
+ block_out_channels = block_out_channels[::-1]
+ self.z_channels = z_channels
+ self.block_out_channels = block_out_channels
+ self.num_res_blocks = num_res_blocks
+
+ ch = block_out_channels[0]
+ self.conv_in = ops.Conv2d(z_channels, ch, 3, 1, 1)
+
+ self.mid = nn.Module()
+ self.mid.block_1 = ResnetBlock(in_channels=ch, out_channels=ch, temb_channels=0, conv_op=ops.Conv2d)
+ self.mid.attn_1 = AttnBlock(ch, conv_op=ops.Conv2d)
+ self.mid.block_2 = ResnetBlock(in_channels=ch, out_channels=ch, temb_channels=0, conv_op=ops.Conv2d)
+
+ self.up = nn.ModuleList()
+ depth = (ffactor_spatial >> 1).bit_length()
+
+ for i, tgt in enumerate(block_out_channels):
+ stage = nn.Module()
+ stage.block = nn.ModuleList([ResnetBlock(in_channels=ch if j == 0 else tgt,
+ out_channels=tgt,
+ temb_channels=0,
+ conv_op=ops.Conv2d)
+ for j in range(num_res_blocks + 1)])
+ ch = tgt
+ if i < depth:
+ nxt = block_out_channels[i + 1] if i + 1 < len(block_out_channels) and upsample_match_channel else ch
+ stage.upsample = PixelUnshuffle2D(ch, nxt, ops.Conv2d)
+ ch = nxt
+ self.up.append(stage)
+
+ self.norm_out = ops.GroupNorm(32, ch, 1e-6, True)
+ self.conv_out = ops.Conv2d(ch, out_channels, 3, 1, 1)
+
+ def forward(self, z):
+ x = self.conv_in(z) + z.repeat_interleave(self.block_out_channels[0] // self.z_channels, 1)
+ x = self.mid.block_2(self.mid.attn_1(self.mid.block_1(x)))
+
+ for stage in self.up:
+ for blk in stage.block:
+ x = blk(x)
+ if hasattr(stage, 'upsample'):
+ x = stage.upsample(x)
+
+ return self.conv_out(F.silu(self.norm_out(x)))
diff --git a/ComfyUI/comfy/ldm/hunyuan_video/vae_refiner.py b/ComfyUI/comfy/ldm/hunyuan_video/vae_refiner.py
new file mode 100644
index 0000000000000000000000000000000000000000..ddf77cd0e2b101ac05f88b242dc96d0a5b24fac7
--- /dev/null
+++ b/ComfyUI/comfy/ldm/hunyuan_video/vae_refiner.py
@@ -0,0 +1,313 @@
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+from comfy.ldm.modules.diffusionmodules.model import ResnetBlock, AttnBlock, CarriedConv3d, Normalize, conv_carry_causal_3d, torch_cat_if_needed
+import comfy.ops
+import comfy.ldm.models.autoencoder
+import comfy.model_management
+ops = comfy.ops.disable_weight_init
+
+
+class RMS_norm(nn.Module):
+ def __init__(self, dim):
+ super().__init__()
+ shape = (dim, 1, 1, 1)
+ self.scale = dim**0.5
+ self.gamma = nn.Parameter(torch.empty(shape))
+
+ def forward(self, x):
+ return F.normalize(x, dim=1) * self.scale * comfy.model_management.cast_to(self.gamma, dtype=x.dtype, device=x.device)
+
+class DnSmpl(nn.Module):
+ def __init__(self, ic, oc, tds, refiner_vae, op):
+ super().__init__()
+ fct = 2 * 2 * 2 if tds else 1 * 2 * 2
+ assert oc % fct == 0
+ self.conv = op(ic, oc // fct, kernel_size=3, stride=1, padding=1)
+ self.refiner_vae = refiner_vae
+
+ self.tds = tds
+ self.gs = fct * ic // oc
+
+ def forward(self, x, conv_carry_in=None, conv_carry_out=None):
+ r1 = 2 if self.tds else 1
+ h = conv_carry_causal_3d([x], self.conv, conv_carry_in, conv_carry_out)
+
+ if self.tds and self.refiner_vae and conv_carry_in is None:
+
+ hf = h[:, :, :1, :, :]
+ b, c, f, ht, wd = hf.shape
+ hf = hf.reshape(b, c, f, ht // 2, 2, wd // 2, 2)
+ hf = hf.permute(0, 4, 6, 1, 2, 3, 5)
+ hf = hf.reshape(b, 2 * 2 * c, f, ht // 2, wd // 2)
+ hf = torch.cat([hf, hf], dim=1)
+
+ h = h[:, :, 1:, :, :]
+
+ xf = x[:, :, :1, :, :]
+ b, ci, f, ht, wd = xf.shape
+ xf = xf.reshape(b, ci, f, ht // 2, 2, wd // 2, 2)
+ xf = xf.permute(0, 4, 6, 1, 2, 3, 5)
+ xf = xf.reshape(b, 2 * 2 * ci, f, ht // 2, wd // 2)
+ B, C, T, H, W = xf.shape
+ xf = xf.view(B, hf.shape[1], self.gs // 2, T, H, W).mean(dim=2)
+
+ x = x[:, :, 1:, :, :]
+
+ if h.shape[2] == 0:
+ return hf + xf
+
+ b, c, frms, ht, wd = h.shape
+ nf = frms // r1
+ h = h.reshape(b, c, nf, r1, ht // 2, 2, wd // 2, 2)
+ h = h.permute(0, 3, 5, 7, 1, 2, 4, 6)
+ h = h.reshape(b, r1 * 2 * 2 * c, nf, ht // 2, wd // 2)
+
+ b, ci, frms, ht, wd = x.shape
+ nf = frms // r1
+ x = x.reshape(b, ci, nf, r1, ht // 2, 2, wd // 2, 2)
+ x = x.permute(0, 3, 5, 7, 1, 2, 4, 6)
+ x = x.reshape(b, r1 * 2 * 2 * ci, nf, ht // 2, wd // 2)
+ B, C, T, H, W = x.shape
+ x = x.view(B, h.shape[1], self.gs, T, H, W).mean(dim=2)
+
+ if self.tds and self.refiner_vae and conv_carry_in is None:
+ h = torch.cat([hf, h], dim=2)
+ x = torch.cat([xf, x], dim=2)
+
+ return h + x
+
+
+class UpSmpl(nn.Module):
+ def __init__(self, ic, oc, tus, refiner_vae, op):
+ super().__init__()
+ fct = 2 * 2 * 2 if tus else 1 * 2 * 2
+ self.conv = op(ic, oc * fct, kernel_size=3, stride=1, padding=1)
+ self.refiner_vae = refiner_vae
+
+ self.tus = tus
+ self.rp = fct * oc // ic
+
+ def forward(self, x, conv_carry_in=None, conv_carry_out=None):
+ r1 = 2 if self.tus else 1
+ h = conv_carry_causal_3d([x], self.conv, conv_carry_in, conv_carry_out)
+
+ if self.tus and self.refiner_vae and conv_carry_in is None:
+ hf = h[:, :, :1, :, :]
+ b, c, f, ht, wd = hf.shape
+ nc = c // (2 * 2)
+ hf = hf.reshape(b, 2, 2, nc, f, ht, wd)
+ hf = hf.permute(0, 3, 4, 5, 1, 6, 2)
+ hf = hf.reshape(b, nc, f, ht * 2, wd * 2)
+ hf = hf[:, : hf.shape[1] // 2]
+
+ h = h[:, :, 1:, :, :]
+
+ xf = x[:, :, :1, :, :]
+ b, ci, f, ht, wd = xf.shape
+ xf = xf.repeat_interleave(repeats=self.rp // 2, dim=1)
+ b, c, f, ht, wd = xf.shape
+ nc = c // (2 * 2)
+ xf = xf.reshape(b, 2, 2, nc, f, ht, wd)
+ xf = xf.permute(0, 3, 4, 5, 1, 6, 2)
+ xf = xf.reshape(b, nc, f, ht * 2, wd * 2)
+
+ x = x[:, :, 1:, :, :]
+
+ b, c, frms, ht, wd = h.shape
+ nc = c // (r1 * 2 * 2)
+ h = h.reshape(b, r1, 2, 2, nc, frms, ht, wd)
+ h = h.permute(0, 4, 5, 1, 6, 2, 7, 3)
+ h = h.reshape(b, nc, frms * r1, ht * 2, wd * 2)
+
+ x = x.repeat_interleave(repeats=self.rp, dim=1)
+ b, c, frms, ht, wd = x.shape
+ nc = c // (r1 * 2 * 2)
+ x = x.reshape(b, r1, 2, 2, nc, frms, ht, wd)
+ x = x.permute(0, 4, 5, 1, 6, 2, 7, 3)
+ x = x.reshape(b, nc, frms * r1, ht * 2, wd * 2)
+
+ if self.tus and self.refiner_vae and conv_carry_in is None:
+ h = torch.cat([hf, h], dim=2)
+ x = torch.cat([xf, x], dim=2)
+
+ return h + x
+
+class Encoder(nn.Module):
+ def __init__(self, in_channels, z_channels, block_out_channels, num_res_blocks,
+ ffactor_spatial, ffactor_temporal, downsample_match_channel=True, refiner_vae=True, **_):
+ super().__init__()
+ self.z_channels = z_channels
+ self.block_out_channels = block_out_channels
+ self.num_res_blocks = num_res_blocks
+ self.ffactor_temporal = ffactor_temporal
+
+ self.refiner_vae = refiner_vae
+ if self.refiner_vae:
+ conv_op = CarriedConv3d
+ norm_op = RMS_norm
+ else:
+ conv_op = ops.Conv3d
+ norm_op = Normalize
+
+ self.conv_in = conv_op(in_channels, block_out_channels[0], 3, 1, 1)
+
+ self.down = nn.ModuleList()
+ ch = block_out_channels[0]
+ depth = (ffactor_spatial >> 1).bit_length()
+ depth_temporal = ((ffactor_spatial // self.ffactor_temporal) >> 1).bit_length()
+
+ for i, tgt in enumerate(block_out_channels):
+ stage = nn.Module()
+ stage.block = nn.ModuleList([ResnetBlock(in_channels=ch if j == 0 else tgt,
+ out_channels=tgt,
+ temb_channels=0,
+ conv_op=conv_op, norm_op=norm_op)
+ for j in range(num_res_blocks)])
+ ch = tgt
+ if i < depth:
+ nxt = block_out_channels[i + 1] if i + 1 < len(block_out_channels) and downsample_match_channel else ch
+ stage.downsample = DnSmpl(ch, nxt, tds=i >= depth_temporal, refiner_vae=self.refiner_vae, op=conv_op)
+ ch = nxt
+ self.down.append(stage)
+
+ self.mid = nn.Module()
+ self.mid.block_1 = ResnetBlock(in_channels=ch, out_channels=ch, conv_op=conv_op, norm_op=norm_op)
+ self.mid.attn_1 = AttnBlock(ch, conv_op=ops.Conv3d, norm_op=norm_op)
+ self.mid.block_2 = ResnetBlock(in_channels=ch, out_channels=ch, conv_op=conv_op, norm_op=norm_op)
+
+ self.norm_out = norm_op(ch)
+ self.conv_out = conv_op(ch, z_channels << 1, 3, 1, 1)
+
+ self.regul = comfy.ldm.models.autoencoder.DiagonalGaussianRegularizer()
+
+ def forward(self, x):
+ if not self.refiner_vae and x.shape[2] == 1:
+ x = x.expand(-1, -1, self.ffactor_temporal, -1, -1)
+
+ if self.refiner_vae:
+ xl = [x[:, :, :1, :, :]]
+ if x.shape[2] > self.ffactor_temporal:
+ xl += torch.split(x[:, :, 1: 1 + ((x.shape[2] - 1) // self.ffactor_temporal) * self.ffactor_temporal, :, :], self.ffactor_temporal * 2, dim=2)
+ x = xl
+ else:
+ x = [x]
+ out = []
+
+ conv_carry_in = None
+
+ for i, x1 in enumerate(x):
+ conv_carry_out = []
+ if i == len(x) - 1:
+ conv_carry_out = None
+
+ x1 = [ x1 ]
+ x1 = conv_carry_causal_3d(x1, self.conv_in, conv_carry_in, conv_carry_out)
+
+ for stage in self.down:
+ for blk in stage.block:
+ x1 = blk(x1, None, conv_carry_in, conv_carry_out)
+ if hasattr(stage, 'downsample'):
+ x1 = stage.downsample(x1, conv_carry_in, conv_carry_out)
+
+ out.append(x1)
+ conv_carry_in = conv_carry_out
+
+ out = torch_cat_if_needed(out, dim=2)
+
+ x = self.mid.block_2(self.mid.attn_1(self.mid.block_1(out)))
+ del out
+
+ b, c, t, h, w = x.shape
+ grp = c // (self.z_channels << 1)
+ skip = x.view(b, c // grp, grp, t, h, w).mean(2)
+
+ out = conv_carry_causal_3d([F.silu(self.norm_out(x))], self.conv_out) + skip
+
+ if self.refiner_vae:
+ out = self.regul(out)[0]
+
+ return out
+
+class Decoder(nn.Module):
+ def __init__(self, z_channels, out_channels, block_out_channels, num_res_blocks,
+ ffactor_spatial, ffactor_temporal, upsample_match_channel=True, refiner_vae=True, **_):
+ super().__init__()
+ block_out_channels = block_out_channels[::-1]
+ self.z_channels = z_channels
+ self.block_out_channels = block_out_channels
+ self.num_res_blocks = num_res_blocks
+
+ self.refiner_vae = refiner_vae
+ if self.refiner_vae:
+ conv_op = CarriedConv3d
+ norm_op = RMS_norm
+ else:
+ conv_op = ops.Conv3d
+ norm_op = Normalize
+
+ ch = block_out_channels[0]
+ self.conv_in = conv_op(z_channels, ch, kernel_size=3, stride=1, padding=1)
+
+ self.mid = nn.Module()
+ self.mid.block_1 = ResnetBlock(in_channels=ch, out_channels=ch, conv_op=conv_op, norm_op=norm_op)
+ self.mid.attn_1 = AttnBlock(ch, conv_op=ops.Conv3d, norm_op=norm_op)
+ self.mid.block_2 = ResnetBlock(in_channels=ch, out_channels=ch, conv_op=conv_op, norm_op=norm_op)
+
+ self.up = nn.ModuleList()
+ depth = (ffactor_spatial >> 1).bit_length()
+ depth_temporal = (ffactor_temporal >> 1).bit_length()
+
+ for i, tgt in enumerate(block_out_channels):
+ stage = nn.Module()
+ stage.block = nn.ModuleList([ResnetBlock(in_channels=ch if j == 0 else tgt,
+ out_channels=tgt,
+ temb_channels=0,
+ conv_op=conv_op, norm_op=norm_op)
+ for j in range(num_res_blocks + 1)])
+ ch = tgt
+ if i < depth:
+ nxt = block_out_channels[i + 1] if i + 1 < len(block_out_channels) and upsample_match_channel else ch
+ stage.upsample = UpSmpl(ch, nxt, tus=i < depth_temporal, refiner_vae=self.refiner_vae, op=conv_op)
+ ch = nxt
+ self.up.append(stage)
+
+ self.norm_out = norm_op(ch)
+ self.conv_out = conv_op(ch, out_channels, 3, stride=1, padding=1)
+
+ def forward(self, z):
+ x = conv_carry_causal_3d([z], self.conv_in) + z.repeat_interleave(self.block_out_channels[0] // self.z_channels, 1)
+ x = self.mid.block_2(self.mid.attn_1(self.mid.block_1(x)))
+
+ if self.refiner_vae:
+ x = torch.split(x, 2, dim=2)
+ else:
+ x = [ x ]
+ out = []
+
+ conv_carry_in = None
+
+ for i, x1 in enumerate(x):
+ conv_carry_out = []
+ if i == len(x) - 1:
+ conv_carry_out = None
+ for stage in self.up:
+ for blk in stage.block:
+ x1 = blk(x1, None, conv_carry_in, conv_carry_out)
+ if hasattr(stage, 'upsample'):
+ x1 = stage.upsample(x1, conv_carry_in, conv_carry_out)
+
+ x1 = [ F.silu(self.norm_out(x1)) ]
+ x1 = conv_carry_causal_3d(x1, self.conv_out, conv_carry_in, conv_carry_out)
+ out.append(x1)
+ conv_carry_in = conv_carry_out
+ del x
+
+ out = torch_cat_if_needed(out, dim=2)
+
+ if not self.refiner_vae:
+ if z.shape[-3] == 1:
+ out = out[:, :, -1:]
+
+ return out
+
diff --git a/ComfyUI/comfy/ldm/hydit/__pycache__/attn_layers.cpython-312.pyc b/ComfyUI/comfy/ldm/hydit/__pycache__/attn_layers.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..df1b1caf5813c053fd9cb53687d083d496140112
Binary files /dev/null and b/ComfyUI/comfy/ldm/hydit/__pycache__/attn_layers.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/hydit/__pycache__/controlnet.cpython-312.pyc b/ComfyUI/comfy/ldm/hydit/__pycache__/controlnet.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..34bc9901a1d529168a78bcedd12d29048f0faf8a
Binary files /dev/null and b/ComfyUI/comfy/ldm/hydit/__pycache__/controlnet.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/hydit/__pycache__/models.cpython-312.pyc b/ComfyUI/comfy/ldm/hydit/__pycache__/models.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..4cee9ba0d9c33783a419c2d8e743874ae7d71d74
Binary files /dev/null and b/ComfyUI/comfy/ldm/hydit/__pycache__/models.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/hydit/__pycache__/poolers.cpython-312.pyc b/ComfyUI/comfy/ldm/hydit/__pycache__/poolers.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..1d3bad750a524f566e6eab7fe24e7c44519b520a
Binary files /dev/null and b/ComfyUI/comfy/ldm/hydit/__pycache__/poolers.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/hydit/__pycache__/posemb_layers.cpython-312.pyc b/ComfyUI/comfy/ldm/hydit/__pycache__/posemb_layers.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..ece74323403dbfef2892236e9adc0295bff28418
Binary files /dev/null and b/ComfyUI/comfy/ldm/hydit/__pycache__/posemb_layers.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/hydit/attn_layers.py b/ComfyUI/comfy/ldm/hydit/attn_layers.py
new file mode 100644
index 0000000000000000000000000000000000000000..3ca25a5df175bcadd8e50ad34ee0bfcddcb37aa0
--- /dev/null
+++ b/ComfyUI/comfy/ldm/hydit/attn_layers.py
@@ -0,0 +1,218 @@
+import torch
+import torch.nn as nn
+from typing import Tuple, Union, Optional
+from comfy.ldm.modules.attention import optimized_attention
+
+
+def reshape_for_broadcast(freqs_cis: Union[torch.Tensor, Tuple[torch.Tensor]], x: torch.Tensor, head_first=False):
+ """
+ Reshape frequency tensor for broadcasting it with another tensor.
+
+ This function reshapes the frequency tensor to have the same shape as the target tensor 'x'
+ for the purpose of broadcasting the frequency tensor during element-wise operations.
+
+ Args:
+ freqs_cis (Union[torch.Tensor, Tuple[torch.Tensor]]): Frequency tensor to be reshaped.
+ x (torch.Tensor): Target tensor for broadcasting compatibility.
+ head_first (bool): head dimension first (except batch dim) or not.
+
+ Returns:
+ torch.Tensor: Reshaped frequency tensor.
+
+ Raises:
+ AssertionError: If the frequency tensor doesn't match the expected shape.
+ AssertionError: If the target tensor 'x' doesn't have the expected number of dimensions.
+ """
+ ndim = x.ndim
+ assert 0 <= 1 < ndim
+
+ if isinstance(freqs_cis, tuple):
+ # freqs_cis: (cos, sin) in real space
+ if head_first:
+ assert freqs_cis[0].shape == (x.shape[-2], x.shape[-1]), f'freqs_cis shape {freqs_cis[0].shape} does not match x shape {x.shape}'
+ shape = [d if i == ndim - 2 or i == ndim - 1 else 1 for i, d in enumerate(x.shape)]
+ else:
+ assert freqs_cis[0].shape == (x.shape[1], x.shape[-1]), f'freqs_cis shape {freqs_cis[0].shape} does not match x shape {x.shape}'
+ shape = [d if i == 1 or i == ndim - 1 else 1 for i, d in enumerate(x.shape)]
+ return freqs_cis[0].view(*shape), freqs_cis[1].view(*shape)
+ else:
+ # freqs_cis: values in complex space
+ if head_first:
+ assert freqs_cis.shape == (x.shape[-2], x.shape[-1]), f'freqs_cis shape {freqs_cis.shape} does not match x shape {x.shape}'
+ shape = [d if i == ndim - 2 or i == ndim - 1 else 1 for i, d in enumerate(x.shape)]
+ else:
+ assert freqs_cis.shape == (x.shape[1], x.shape[-1]), f'freqs_cis shape {freqs_cis.shape} does not match x shape {x.shape}'
+ shape = [d if i == 1 or i == ndim - 1 else 1 for i, d in enumerate(x.shape)]
+ return freqs_cis.view(*shape)
+
+
+def rotate_half(x):
+ x_real, x_imag = x.reshape(*x.shape[:-1], -1, 2).unbind(-1) # [B, S, H, D//2]
+ return torch.stack([-x_imag, x_real], dim=-1).flatten(3)
+
+
+def apply_rotary_emb(
+ xq: torch.Tensor,
+ xk: Optional[torch.Tensor],
+ freqs_cis: Union[torch.Tensor, Tuple[torch.Tensor]],
+ head_first: bool = False,
+) -> Tuple[torch.Tensor, torch.Tensor]:
+ """
+ Apply rotary embeddings to input tensors using the given frequency tensor.
+
+ This function applies rotary embeddings to the given query 'xq' and key 'xk' tensors using the provided
+ frequency tensor 'freqs_cis'. The input tensors are reshaped as complex numbers, and the frequency tensor
+ is reshaped for broadcasting compatibility. The resulting tensors contain rotary embeddings and are
+ returned as real tensors.
+
+ Args:
+ xq (torch.Tensor): Query tensor to apply rotary embeddings. [B, S, H, D]
+ xk (torch.Tensor): Key tensor to apply rotary embeddings. [B, S, H, D]
+ freqs_cis (Union[torch.Tensor, Tuple[torch.Tensor]]): Precomputed frequency tensor for complex exponentials.
+ head_first (bool): head dimension first (except batch dim) or not.
+
+ Returns:
+ Tuple[torch.Tensor, torch.Tensor]: Tuple of modified query tensor and key tensor with rotary embeddings.
+
+ """
+ xk_out = None
+ if isinstance(freqs_cis, tuple):
+ cos, sin = reshape_for_broadcast(freqs_cis, xq, head_first) # [S, D]
+ xq_out = (xq * cos + rotate_half(xq) * sin)
+ if xk is not None:
+ xk_out = (xk * cos + rotate_half(xk) * sin)
+ else:
+ xq_ = torch.view_as_complex(xq.float().reshape(*xq.shape[:-1], -1, 2)) # [B, S, H, D//2]
+ freqs_cis = reshape_for_broadcast(freqs_cis, xq_, head_first).to(xq.device) # [S, D//2] --> [1, S, 1, D//2]
+ xq_out = torch.view_as_real(xq_ * freqs_cis).flatten(3).type_as(xq)
+ if xk is not None:
+ xk_ = torch.view_as_complex(xk.float().reshape(*xk.shape[:-1], -1, 2)) # [B, S, H, D//2]
+ xk_out = torch.view_as_real(xk_ * freqs_cis).flatten(3).type_as(xk)
+
+ return xq_out, xk_out
+
+
+
+class CrossAttention(nn.Module):
+ """
+ Use QK Normalization.
+ """
+ def __init__(self,
+ qdim,
+ kdim,
+ num_heads,
+ qkv_bias=True,
+ qk_norm=False,
+ attn_drop=0.0,
+ proj_drop=0.0,
+ attn_precision=None,
+ device=None,
+ dtype=None,
+ operations=None,
+ ):
+ factory_kwargs = {'device': device, 'dtype': dtype}
+ super().__init__()
+ self.attn_precision = attn_precision
+ self.qdim = qdim
+ self.kdim = kdim
+ self.num_heads = num_heads
+ assert self.qdim % num_heads == 0, "self.qdim must be divisible by num_heads"
+ self.head_dim = self.qdim // num_heads
+ assert self.head_dim % 8 == 0 and self.head_dim <= 128, "Only support head_dim <= 128 and divisible by 8"
+ self.scale = self.head_dim ** -0.5
+
+ self.q_proj = operations.Linear(qdim, qdim, bias=qkv_bias, **factory_kwargs)
+ self.kv_proj = operations.Linear(kdim, 2 * qdim, bias=qkv_bias, **factory_kwargs)
+
+ # TODO: eps should be 1 / 65530 if using fp16
+ self.q_norm = operations.LayerNorm(self.head_dim, elementwise_affine=True, eps=1e-6, dtype=dtype, device=device) if qk_norm else nn.Identity()
+ self.k_norm = operations.LayerNorm(self.head_dim, elementwise_affine=True, eps=1e-6, dtype=dtype, device=device) if qk_norm else nn.Identity()
+ self.attn_drop = nn.Dropout(attn_drop)
+ self.out_proj = operations.Linear(qdim, qdim, bias=qkv_bias, **factory_kwargs)
+ self.proj_drop = nn.Dropout(proj_drop)
+
+ def forward(self, x, y, freqs_cis_img=None):
+ """
+ Parameters
+ ----------
+ x: torch.Tensor
+ (batch, seqlen1, hidden_dim) (where hidden_dim = num heads * head dim)
+ y: torch.Tensor
+ (batch, seqlen2, hidden_dim2)
+ freqs_cis_img: torch.Tensor
+ (batch, hidden_dim // 2), RoPE for image
+ """
+ b, s1, c = x.shape # [b, s1, D]
+ _, s2, c = y.shape # [b, s2, 1024]
+
+ q = self.q_proj(x).view(b, s1, self.num_heads, self.head_dim) # [b, s1, h, d]
+ kv = self.kv_proj(y).view(b, s2, 2, self.num_heads, self.head_dim) # [b, s2, 2, h, d]
+ k, v = kv.unbind(dim=2) # [b, s, h, d]
+ q = self.q_norm(q)
+ k = self.k_norm(k)
+
+ # Apply RoPE if needed
+ if freqs_cis_img is not None:
+ qq, _ = apply_rotary_emb(q, None, freqs_cis_img)
+ assert qq.shape == q.shape, f'qq: {qq.shape}, q: {q.shape}'
+ q = qq
+
+ q = q.transpose(-2, -3).contiguous() # q -> B, L1, H, C - B, H, L1, C
+ k = k.transpose(-2, -3).contiguous() # k -> B, L2, H, C - B, H, C, L2
+ v = v.transpose(-2, -3).contiguous()
+
+ context = optimized_attention(q, k, v, self.num_heads, skip_reshape=True, attn_precision=self.attn_precision)
+
+ out = self.out_proj(context) # context.reshape - B, L1, -1
+ out = self.proj_drop(out)
+
+ out_tuple = (out,)
+
+ return out_tuple
+
+
+class Attention(nn.Module):
+ """
+ We rename some layer names to align with flash attention
+ """
+ def __init__(self, dim, num_heads, qkv_bias=True, qk_norm=False, attn_drop=0., proj_drop=0., attn_precision=None, dtype=None, device=None, operations=None):
+ super().__init__()
+ self.attn_precision = attn_precision
+ self.dim = dim
+ self.num_heads = num_heads
+ assert self.dim % num_heads == 0, 'dim should be divisible by num_heads'
+ self.head_dim = self.dim // num_heads
+ # This assertion is aligned with flash attention
+ assert self.head_dim % 8 == 0 and self.head_dim <= 128, "Only support head_dim <= 128 and divisible by 8"
+ self.scale = self.head_dim ** -0.5
+
+ # qkv --> Wqkv
+ self.Wqkv = operations.Linear(dim, dim * 3, bias=qkv_bias, dtype=dtype, device=device)
+ # TODO: eps should be 1 / 65530 if using fp16
+ self.q_norm = operations.LayerNorm(self.head_dim, elementwise_affine=True, eps=1e-6, dtype=dtype, device=device) if qk_norm else nn.Identity()
+ self.k_norm = operations.LayerNorm(self.head_dim, elementwise_affine=True, eps=1e-6, dtype=dtype, device=device) if qk_norm else nn.Identity()
+ self.attn_drop = nn.Dropout(attn_drop)
+ self.out_proj = operations.Linear(dim, dim, dtype=dtype, device=device)
+ self.proj_drop = nn.Dropout(proj_drop)
+
+ def forward(self, x, freqs_cis_img=None):
+ B, N, C = x.shape
+ qkv = self.Wqkv(x).reshape(B, N, 3, self.num_heads, self.head_dim).permute(2, 0, 3, 1, 4) # [3, b, h, s, d]
+ q, k, v = qkv.unbind(0) # [b, h, s, d]
+ q = self.q_norm(q) # [b, h, s, d]
+ k = self.k_norm(k) # [b, h, s, d]
+
+ # Apply RoPE if needed
+ if freqs_cis_img is not None:
+ qq, kk = apply_rotary_emb(q, k, freqs_cis_img, head_first=True)
+ assert qq.shape == q.shape and kk.shape == k.shape, \
+ f'qq: {qq.shape}, q: {q.shape}, kk: {kk.shape}, k: {k.shape}'
+ q, k = qq, kk
+
+ x = optimized_attention(q, k, v, self.num_heads, skip_reshape=True, attn_precision=self.attn_precision)
+ x = self.out_proj(x)
+ x = self.proj_drop(x)
+
+ out_tuple = (x,)
+
+ return out_tuple
diff --git a/ComfyUI/comfy/ldm/hydit/controlnet.py b/ComfyUI/comfy/ldm/hydit/controlnet.py
new file mode 100644
index 0000000000000000000000000000000000000000..31a6bff9409bb5264e552f91197915a136c3964d
--- /dev/null
+++ b/ComfyUI/comfy/ldm/hydit/controlnet.py
@@ -0,0 +1,311 @@
+
+import torch
+import torch.nn as nn
+
+
+from comfy.ldm.modules.diffusionmodules.mmdit import (
+ TimestepEmbedder,
+ PatchEmbed,
+)
+from .poolers import AttentionPool
+
+import comfy.latent_formats
+from .models import HunYuanDiTBlock, calc_rope
+
+
+
+class HunYuanControlNet(nn.Module):
+ """
+ HunYuanDiT: Diffusion model with a Transformer backbone.
+
+ Inherit ModelMixin and ConfigMixin to be compatible with the sampler StableDiffusionPipeline of diffusers.
+
+ Inherit PeftAdapterMixin to be compatible with the PEFT training pipeline.
+
+ Parameters
+ ----------
+ args: argparse.Namespace
+ The arguments parsed by argparse.
+ input_size: tuple
+ The size of the input image.
+ patch_size: int
+ The size of the patch.
+ in_channels: int
+ The number of input channels.
+ hidden_size: int
+ The hidden size of the transformer backbone.
+ depth: int
+ The number of transformer blocks.
+ num_heads: int
+ The number of attention heads.
+ mlp_ratio: float
+ The ratio of the hidden size of the MLP in the transformer block.
+ log_fn: callable
+ The logging function.
+ """
+
+ def __init__(
+ self,
+ input_size: tuple = 128,
+ patch_size: int = 2,
+ in_channels: int = 4,
+ hidden_size: int = 1408,
+ depth: int = 40,
+ num_heads: int = 16,
+ mlp_ratio: float = 4.3637,
+ text_states_dim=1024,
+ text_states_dim_t5=2048,
+ text_len=77,
+ text_len_t5=256,
+ qk_norm=True, # See http://arxiv.org/abs/2302.05442 for details.
+ size_cond=False,
+ use_style_cond=False,
+ learn_sigma=True,
+ norm="layer",
+ log_fn: callable = print,
+ attn_precision=None,
+ dtype=None,
+ device=None,
+ operations=None,
+ **kwargs,
+ ):
+ super().__init__()
+ self.log_fn = log_fn
+ self.depth = depth
+ self.learn_sigma = learn_sigma
+ self.in_channels = in_channels
+ self.out_channels = in_channels * 2 if learn_sigma else in_channels
+ self.patch_size = patch_size
+ self.num_heads = num_heads
+ self.hidden_size = hidden_size
+ self.text_states_dim = text_states_dim
+ self.text_states_dim_t5 = text_states_dim_t5
+ self.text_len = text_len
+ self.text_len_t5 = text_len_t5
+ self.size_cond = size_cond
+ self.use_style_cond = use_style_cond
+ self.norm = norm
+ self.dtype = dtype
+ self.latent_format = comfy.latent_formats.SDXL
+
+ self.mlp_t5 = nn.Sequential(
+ nn.Linear(
+ self.text_states_dim_t5,
+ self.text_states_dim_t5 * 4,
+ bias=True,
+ dtype=dtype,
+ device=device,
+ ),
+ nn.SiLU(),
+ nn.Linear(
+ self.text_states_dim_t5 * 4,
+ self.text_states_dim,
+ bias=True,
+ dtype=dtype,
+ device=device,
+ ),
+ )
+ # learnable replace
+ self.text_embedding_padding = nn.Parameter(
+ torch.randn(
+ self.text_len + self.text_len_t5,
+ self.text_states_dim,
+ dtype=dtype,
+ device=device,
+ )
+ )
+
+ # Attention pooling
+ pooler_out_dim = 1024
+ self.pooler = AttentionPool(
+ self.text_len_t5,
+ self.text_states_dim_t5,
+ num_heads=8,
+ output_dim=pooler_out_dim,
+ dtype=dtype,
+ device=device,
+ operations=operations,
+ )
+
+ # Dimension of the extra input vectors
+ self.extra_in_dim = pooler_out_dim
+
+ if self.size_cond:
+ # Image size and crop size conditions
+ self.extra_in_dim += 6 * 256
+
+ if self.use_style_cond:
+ # Here we use a default learned embedder layer for future extension.
+ self.style_embedder = nn.Embedding(
+ 1, hidden_size, dtype=dtype, device=device
+ )
+ self.extra_in_dim += hidden_size
+
+ # Text embedding for `add`
+ self.x_embedder = PatchEmbed(
+ input_size,
+ patch_size,
+ in_channels,
+ hidden_size,
+ dtype=dtype,
+ device=device,
+ operations=operations,
+ )
+ self.t_embedder = TimestepEmbedder(
+ hidden_size, dtype=dtype, device=device, operations=operations
+ )
+ self.extra_embedder = nn.Sequential(
+ operations.Linear(
+ self.extra_in_dim, hidden_size * 4, dtype=dtype, device=device
+ ),
+ nn.SiLU(),
+ operations.Linear(
+ hidden_size * 4, hidden_size, bias=True, dtype=dtype, device=device
+ ),
+ )
+
+ # HUnYuanDiT Blocks
+ self.blocks = nn.ModuleList(
+ [
+ HunYuanDiTBlock(
+ hidden_size=hidden_size,
+ c_emb_size=hidden_size,
+ num_heads=num_heads,
+ mlp_ratio=mlp_ratio,
+ text_states_dim=self.text_states_dim,
+ qk_norm=qk_norm,
+ norm_type=self.norm,
+ skip=False,
+ attn_precision=attn_precision,
+ dtype=dtype,
+ device=device,
+ operations=operations,
+ )
+ for _ in range(19)
+ ]
+ )
+
+ # Input zero linear for the first block
+ self.before_proj = operations.Linear(self.hidden_size, self.hidden_size, dtype=dtype, device=device)
+
+
+ # Output zero linear for the every block
+ self.after_proj_list = nn.ModuleList(
+ [
+
+ operations.Linear(
+ self.hidden_size, self.hidden_size, dtype=dtype, device=device
+ )
+ for _ in range(len(self.blocks))
+ ]
+ )
+
+ def forward(
+ self,
+ x,
+ hint,
+ timesteps,
+ context,#encoder_hidden_states=None,
+ text_embedding_mask=None,
+ encoder_hidden_states_t5=None,
+ text_embedding_mask_t5=None,
+ image_meta_size=None,
+ style=None,
+ return_dict=False,
+ **kwarg,
+ ):
+ """
+ Forward pass of the encoder.
+
+ Parameters
+ ----------
+ x: torch.Tensor
+ (B, D, H, W)
+ t: torch.Tensor
+ (B)
+ encoder_hidden_states: torch.Tensor
+ CLIP text embedding, (B, L_clip, D)
+ text_embedding_mask: torch.Tensor
+ CLIP text embedding mask, (B, L_clip)
+ encoder_hidden_states_t5: torch.Tensor
+ T5 text embedding, (B, L_t5, D)
+ text_embedding_mask_t5: torch.Tensor
+ T5 text embedding mask, (B, L_t5)
+ image_meta_size: torch.Tensor
+ (B, 6)
+ style: torch.Tensor
+ (B)
+ cos_cis_img: torch.Tensor
+ sin_cis_img: torch.Tensor
+ return_dict: bool
+ Whether to return a dictionary.
+ """
+ condition = hint
+ if condition.shape[0] == 1:
+ condition = torch.repeat_interleave(condition, x.shape[0], dim=0)
+
+ text_states = context # 2,77,1024
+ text_states_t5 = encoder_hidden_states_t5 # 2,256,2048
+ text_states_mask = text_embedding_mask.bool() # 2,77
+ text_states_t5_mask = text_embedding_mask_t5.bool() # 2,256
+ b_t5, l_t5, c_t5 = text_states_t5.shape
+ text_states_t5 = self.mlp_t5(text_states_t5.view(-1, c_t5)).view(b_t5, l_t5, -1)
+
+ padding = comfy.ops.cast_to_input(self.text_embedding_padding, text_states)
+
+ text_states[:, -self.text_len :] = torch.where(
+ text_states_mask[:, -self.text_len :].unsqueeze(2),
+ text_states[:, -self.text_len :],
+ padding[: self.text_len],
+ )
+ text_states_t5[:, -self.text_len_t5 :] = torch.where(
+ text_states_t5_mask[:, -self.text_len_t5 :].unsqueeze(2),
+ text_states_t5[:, -self.text_len_t5 :],
+ padding[self.text_len :],
+ )
+
+ text_states = torch.cat([text_states, text_states_t5], dim=1) # 2,205,1024
+
+ # _, _, oh, ow = x.shape
+ # th, tw = oh // self.patch_size, ow // self.patch_size
+
+ # Get image RoPE embedding according to `reso`lution.
+ freqs_cis_img = calc_rope(
+ x, self.patch_size, self.hidden_size // self.num_heads
+ ) # (cos_cis_img, sin_cis_img)
+
+ # ========================= Build time and image embedding =========================
+ t = self.t_embedder(timesteps, dtype=self.dtype)
+ x = self.x_embedder(x)
+
+ # ========================= Concatenate all extra vectors =========================
+ # Build text tokens with pooling
+ extra_vec = self.pooler(encoder_hidden_states_t5)
+
+ # Build image meta size tokens if applicable
+ # if image_meta_size is not None:
+ # image_meta_size = timestep_embedding(image_meta_size.view(-1), 256) # [B * 6, 256]
+ # if image_meta_size.dtype != self.dtype:
+ # image_meta_size = image_meta_size.half()
+ # image_meta_size = image_meta_size.view(-1, 6 * 256)
+ # extra_vec = torch.cat([extra_vec, image_meta_size], dim=1) # [B, D + 6 * 256]
+
+ # Build style tokens
+ if style is not None:
+ style_embedding = self.style_embedder(style)
+ extra_vec = torch.cat([extra_vec, style_embedding], dim=1)
+
+ # Concatenate all extra vectors
+ c = t + self.extra_embedder(extra_vec) # [B, D]
+
+ # ========================= Deal with Condition =========================
+ condition = self.x_embedder(condition)
+
+ # ========================= Forward pass through HunYuanDiT blocks =========================
+ controls = []
+ x = x + self.before_proj(condition) # add condition
+ for layer, block in enumerate(self.blocks):
+ x = block(x, c, text_states, freqs_cis_img)
+ controls.append(self.after_proj_list[layer](x)) # zero linear for output
+
+ return {"output": controls}
diff --git a/ComfyUI/comfy/ldm/hydit/models.py b/ComfyUI/comfy/ldm/hydit/models.py
new file mode 100644
index 0000000000000000000000000000000000000000..5ba2b76e0cad3c611fce1e74b024a66a2255b814
--- /dev/null
+++ b/ComfyUI/comfy/ldm/hydit/models.py
@@ -0,0 +1,417 @@
+
+import torch
+import torch.nn as nn
+
+import comfy.ops
+from comfy.ldm.modules.diffusionmodules.mmdit import Mlp, TimestepEmbedder, PatchEmbed
+from comfy.ldm.modules.diffusionmodules.util import timestep_embedding
+from torch.utils import checkpoint
+
+from .attn_layers import Attention, CrossAttention
+from .poolers import AttentionPool
+from .posemb_layers import get_2d_rotary_pos_embed, get_fill_resize_and_crop
+
+def calc_rope(x, patch_size, head_size):
+ th = (x.shape[2] + (patch_size // 2)) // patch_size
+ tw = (x.shape[3] + (patch_size // 2)) // patch_size
+ base_size = 512 // 8 // patch_size
+ start, stop = get_fill_resize_and_crop((th, tw), base_size)
+ sub_args = [start, stop, (th, tw)]
+ # head_size = HUNYUAN_DIT_CONFIG['DiT-g/2']['hidden_size'] // HUNYUAN_DIT_CONFIG['DiT-g/2']['num_heads']
+ rope = get_2d_rotary_pos_embed(head_size, *sub_args)
+ rope = (rope[0].to(x), rope[1].to(x))
+ return rope
+
+
+def modulate(x, shift, scale):
+ return x * (1 + scale.unsqueeze(1)) + shift.unsqueeze(1)
+
+
+class HunYuanDiTBlock(nn.Module):
+ """
+ A HunYuanDiT block with `add` conditioning.
+ """
+ def __init__(self,
+ hidden_size,
+ c_emb_size,
+ num_heads,
+ mlp_ratio=4.0,
+ text_states_dim=1024,
+ qk_norm=False,
+ norm_type="layer",
+ skip=False,
+ attn_precision=None,
+ dtype=None,
+ device=None,
+ operations=None,
+ ):
+ super().__init__()
+ use_ele_affine = True
+
+ if norm_type == "layer":
+ norm_layer = operations.LayerNorm
+ elif norm_type == "rms":
+ norm_layer = operations.RMSNorm
+ else:
+ raise ValueError(f"Unknown norm_type: {norm_type}")
+
+ # ========================= Self-Attention =========================
+ self.norm1 = norm_layer(hidden_size, elementwise_affine=use_ele_affine, eps=1e-6, dtype=dtype, device=device)
+ self.attn1 = Attention(hidden_size, num_heads=num_heads, qkv_bias=True, qk_norm=qk_norm, attn_precision=attn_precision, dtype=dtype, device=device, operations=operations)
+
+ # ========================= FFN =========================
+ self.norm2 = norm_layer(hidden_size, elementwise_affine=use_ele_affine, eps=1e-6, dtype=dtype, device=device)
+ mlp_hidden_dim = int(hidden_size * mlp_ratio)
+ approx_gelu = lambda: nn.GELU(approximate="tanh")
+ self.mlp = Mlp(in_features=hidden_size, hidden_features=mlp_hidden_dim, act_layer=approx_gelu, drop=0, dtype=dtype, device=device, operations=operations)
+
+ # ========================= Add =========================
+ # Simply use add like SDXL.
+ self.default_modulation = nn.Sequential(
+ nn.SiLU(),
+ operations.Linear(c_emb_size, hidden_size, bias=True, dtype=dtype, device=device)
+ )
+
+ # ========================= Cross-Attention =========================
+ self.attn2 = CrossAttention(hidden_size, text_states_dim, num_heads=num_heads, qkv_bias=True,
+ qk_norm=qk_norm, attn_precision=attn_precision, dtype=dtype, device=device, operations=operations)
+ self.norm3 = norm_layer(hidden_size, elementwise_affine=True, eps=1e-6, dtype=dtype, device=device)
+
+ # ========================= Skip Connection =========================
+ if skip:
+ self.skip_norm = norm_layer(2 * hidden_size, elementwise_affine=True, eps=1e-6, dtype=dtype, device=device)
+ self.skip_linear = operations.Linear(2 * hidden_size, hidden_size, dtype=dtype, device=device)
+ else:
+ self.skip_linear = None
+
+ self.gradient_checkpointing = False
+
+ def _forward(self, x, c=None, text_states=None, freq_cis_img=None, skip=None):
+ # Long Skip Connection
+ if self.skip_linear is not None:
+ cat = torch.cat([x, skip], dim=-1)
+ if cat.dtype != x.dtype:
+ cat = cat.to(x.dtype)
+ cat = self.skip_norm(cat)
+ x = self.skip_linear(cat)
+
+ # Self-Attention
+ shift_msa = self.default_modulation(c).unsqueeze(dim=1)
+ attn_inputs = (
+ self.norm1(x) + shift_msa, freq_cis_img,
+ )
+ x = x + self.attn1(*attn_inputs)[0]
+
+ # Cross-Attention
+ cross_inputs = (
+ self.norm3(x), text_states, freq_cis_img
+ )
+ x = x + self.attn2(*cross_inputs)[0]
+
+ # FFN Layer
+ mlp_inputs = self.norm2(x)
+ x = x + self.mlp(mlp_inputs)
+
+ return x
+
+ def forward(self, x, c=None, text_states=None, freq_cis_img=None, skip=None):
+ if self.gradient_checkpointing and self.training:
+ return checkpoint.checkpoint(self._forward, x, c, text_states, freq_cis_img, skip)
+ return self._forward(x, c, text_states, freq_cis_img, skip)
+
+
+class FinalLayer(nn.Module):
+ """
+ The final layer of HunYuanDiT.
+ """
+ def __init__(self, final_hidden_size, c_emb_size, patch_size, out_channels, dtype=None, device=None, operations=None):
+ super().__init__()
+ self.norm_final = operations.LayerNorm(final_hidden_size, elementwise_affine=False, eps=1e-6, dtype=dtype, device=device)
+ self.linear = operations.Linear(final_hidden_size, patch_size * patch_size * out_channels, bias=True, dtype=dtype, device=device)
+ self.adaLN_modulation = nn.Sequential(
+ nn.SiLU(),
+ operations.Linear(c_emb_size, 2 * final_hidden_size, bias=True, dtype=dtype, device=device)
+ )
+
+ def forward(self, x, c):
+ shift, scale = self.adaLN_modulation(c).chunk(2, dim=1)
+ x = modulate(self.norm_final(x), shift, scale)
+ x = self.linear(x)
+ return x
+
+
+class HunYuanDiT(nn.Module):
+ """
+ HunYuanDiT: Diffusion model with a Transformer backbone.
+
+ Inherit ModelMixin and ConfigMixin to be compatible with the sampler StableDiffusionPipeline of diffusers.
+
+ Inherit PeftAdapterMixin to be compatible with the PEFT training pipeline.
+
+ Parameters
+ ----------
+ args: argparse.Namespace
+ The arguments parsed by argparse.
+ input_size: tuple
+ The size of the input image.
+ patch_size: int
+ The size of the patch.
+ in_channels: int
+ The number of input channels.
+ hidden_size: int
+ The hidden size of the transformer backbone.
+ depth: int
+ The number of transformer blocks.
+ num_heads: int
+ The number of attention heads.
+ mlp_ratio: float
+ The ratio of the hidden size of the MLP in the transformer block.
+ log_fn: callable
+ The logging function.
+ """
+ #@register_to_config
+ def __init__(self,
+ input_size: tuple = 32,
+ patch_size: int = 2,
+ in_channels: int = 4,
+ hidden_size: int = 1152,
+ depth: int = 28,
+ num_heads: int = 16,
+ mlp_ratio: float = 4.0,
+ text_states_dim = 1024,
+ text_states_dim_t5 = 2048,
+ text_len = 77,
+ text_len_t5 = 256,
+ qk_norm = True,# See http://arxiv.org/abs/2302.05442 for details.
+ size_cond = False,
+ use_style_cond = False,
+ learn_sigma = True,
+ norm = "layer",
+ log_fn: callable = print,
+ attn_precision=None,
+ dtype=None,
+ device=None,
+ operations=None,
+ **kwargs,
+ ):
+ super().__init__()
+ self.log_fn = log_fn
+ self.depth = depth
+ self.learn_sigma = learn_sigma
+ self.in_channels = in_channels
+ self.out_channels = in_channels * 2 if learn_sigma else in_channels
+ self.patch_size = patch_size
+ self.num_heads = num_heads
+ self.hidden_size = hidden_size
+ self.text_states_dim = text_states_dim
+ self.text_states_dim_t5 = text_states_dim_t5
+ self.text_len = text_len
+ self.text_len_t5 = text_len_t5
+ self.size_cond = size_cond
+ self.use_style_cond = use_style_cond
+ self.norm = norm
+ self.dtype = dtype
+ #import pdb
+ #pdb.set_trace()
+
+ self.mlp_t5 = nn.Sequential(
+ operations.Linear(self.text_states_dim_t5, self.text_states_dim_t5 * 4, bias=True, dtype=dtype, device=device),
+ nn.SiLU(),
+ operations.Linear(self.text_states_dim_t5 * 4, self.text_states_dim, bias=True, dtype=dtype, device=device),
+ )
+ # learnable replace
+ self.text_embedding_padding = nn.Parameter(
+ torch.empty(self.text_len + self.text_len_t5, self.text_states_dim, dtype=dtype, device=device))
+
+ # Attention pooling
+ pooler_out_dim = 1024
+ self.pooler = AttentionPool(self.text_len_t5, self.text_states_dim_t5, num_heads=8, output_dim=pooler_out_dim, dtype=dtype, device=device, operations=operations)
+
+ # Dimension of the extra input vectors
+ self.extra_in_dim = pooler_out_dim
+
+ if self.size_cond:
+ # Image size and crop size conditions
+ self.extra_in_dim += 6 * 256
+
+ if self.use_style_cond:
+ # Here we use a default learned embedder layer for future extension.
+ self.style_embedder = operations.Embedding(1, hidden_size, dtype=dtype, device=device)
+ self.extra_in_dim += hidden_size
+
+ # Text embedding for `add`
+ self.x_embedder = PatchEmbed(input_size, patch_size, in_channels, hidden_size, dtype=dtype, device=device, operations=operations)
+ self.t_embedder = TimestepEmbedder(hidden_size, dtype=dtype, device=device, operations=operations)
+ self.extra_embedder = nn.Sequential(
+ operations.Linear(self.extra_in_dim, hidden_size * 4, dtype=dtype, device=device),
+ nn.SiLU(),
+ operations.Linear(hidden_size * 4, hidden_size, bias=True, dtype=dtype, device=device),
+ )
+
+ # HUnYuanDiT Blocks
+ self.blocks = nn.ModuleList([
+ HunYuanDiTBlock(hidden_size=hidden_size,
+ c_emb_size=hidden_size,
+ num_heads=num_heads,
+ mlp_ratio=mlp_ratio,
+ text_states_dim=self.text_states_dim,
+ qk_norm=qk_norm,
+ norm_type=self.norm,
+ skip=layer > depth // 2,
+ attn_precision=attn_precision,
+ dtype=dtype,
+ device=device,
+ operations=operations,
+ )
+ for layer in range(depth)
+ ])
+
+ self.final_layer = FinalLayer(hidden_size, hidden_size, patch_size, self.out_channels, dtype=dtype, device=device, operations=operations)
+ self.unpatchify_channels = self.out_channels
+
+
+
+ def forward(self,
+ x,
+ t,
+ context,#encoder_hidden_states=None,
+ text_embedding_mask=None,
+ encoder_hidden_states_t5=None,
+ text_embedding_mask_t5=None,
+ image_meta_size=None,
+ style=None,
+ return_dict=False,
+ control=None,
+ transformer_options={},
+ ):
+ """
+ Forward pass of the encoder.
+
+ Parameters
+ ----------
+ x: torch.Tensor
+ (B, D, H, W)
+ t: torch.Tensor
+ (B)
+ encoder_hidden_states: torch.Tensor
+ CLIP text embedding, (B, L_clip, D)
+ text_embedding_mask: torch.Tensor
+ CLIP text embedding mask, (B, L_clip)
+ encoder_hidden_states_t5: torch.Tensor
+ T5 text embedding, (B, L_t5, D)
+ text_embedding_mask_t5: torch.Tensor
+ T5 text embedding mask, (B, L_t5)
+ image_meta_size: torch.Tensor
+ (B, 6)
+ style: torch.Tensor
+ (B)
+ cos_cis_img: torch.Tensor
+ sin_cis_img: torch.Tensor
+ return_dict: bool
+ Whether to return a dictionary.
+ """
+ patches_replace = transformer_options.get("patches_replace", {})
+ encoder_hidden_states = context
+ text_states = encoder_hidden_states # 2,77,1024
+ text_states_t5 = encoder_hidden_states_t5 # 2,256,2048
+ text_states_mask = text_embedding_mask.bool() # 2,77
+ text_states_t5_mask = text_embedding_mask_t5.bool() # 2,256
+ b_t5, l_t5, c_t5 = text_states_t5.shape
+ text_states_t5 = self.mlp_t5(text_states_t5.view(-1, c_t5)).view(b_t5, l_t5, -1)
+
+ padding = comfy.ops.cast_to_input(self.text_embedding_padding, text_states)
+
+ text_states[:,-self.text_len:] = torch.where(text_states_mask[:,-self.text_len:].unsqueeze(2), text_states[:,-self.text_len:], padding[:self.text_len])
+ text_states_t5[:,-self.text_len_t5:] = torch.where(text_states_t5_mask[:,-self.text_len_t5:].unsqueeze(2), text_states_t5[:,-self.text_len_t5:], padding[self.text_len:])
+
+ text_states = torch.cat([text_states, text_states_t5], dim=1) # 2,205,1024
+ # clip_t5_mask = torch.cat([text_states_mask, text_states_t5_mask], dim=-1)
+
+ _, _, oh, ow = x.shape
+ th, tw = (oh + (self.patch_size // 2)) // self.patch_size, (ow + (self.patch_size // 2)) // self.patch_size
+
+
+ # Get image RoPE embedding according to `reso`lution.
+ freqs_cis_img = calc_rope(x, self.patch_size, self.hidden_size // self.num_heads) #(cos_cis_img, sin_cis_img)
+
+ # ========================= Build time and image embedding =========================
+ t = self.t_embedder(t, dtype=x.dtype)
+ x = self.x_embedder(x)
+
+ # ========================= Concatenate all extra vectors =========================
+ # Build text tokens with pooling
+ extra_vec = self.pooler(encoder_hidden_states_t5)
+
+ # Build image meta size tokens if applicable
+ if self.size_cond:
+ image_meta_size = timestep_embedding(image_meta_size.view(-1), 256).to(x.dtype) # [B * 6, 256]
+ image_meta_size = image_meta_size.view(-1, 6 * 256)
+ extra_vec = torch.cat([extra_vec, image_meta_size], dim=1) # [B, D + 6 * 256]
+
+ # Build style tokens
+ if self.use_style_cond:
+ if style is None:
+ style = torch.zeros((extra_vec.shape[0],), device=x.device, dtype=torch.int)
+ style_embedding = self.style_embedder(style, out_dtype=x.dtype)
+ extra_vec = torch.cat([extra_vec, style_embedding], dim=1)
+
+ # Concatenate all extra vectors
+ c = t + self.extra_embedder(extra_vec) # [B, D]
+
+ blocks_replace = patches_replace.get("dit", {})
+
+ controls = None
+ if control:
+ controls = control.get("output", None)
+ # ========================= Forward pass through HunYuanDiT blocks =========================
+ skips = []
+ for layer, block in enumerate(self.blocks):
+ if layer > self.depth // 2:
+ if controls is not None:
+ skip = skips.pop() + controls.pop().to(dtype=x.dtype)
+ else:
+ skip = skips.pop()
+ else:
+ skip = None
+
+ if ("double_block", layer) in blocks_replace:
+ def block_wrap(args):
+ out = {}
+ out["img"] = block(args["img"], args["vec"], args["txt"], args["pe"], args["skip"])
+ return out
+
+ out = blocks_replace[("double_block", layer)]({"img": x, "txt": text_states, "vec": c, "pe": freqs_cis_img, "skip": skip}, {"original_block": block_wrap})
+ x = out["img"]
+ else:
+ x = block(x, c, text_states, freqs_cis_img, skip) # (N, L, D)
+
+
+ if layer < (self.depth // 2 - 1):
+ skips.append(x)
+ if controls is not None and len(controls) != 0:
+ raise ValueError("The number of controls is not equal to the number of skip connections.")
+
+ # ========================= Final layer =========================
+ x = self.final_layer(x, c) # (N, L, patch_size ** 2 * out_channels)
+ x = self.unpatchify(x, th, tw) # (N, out_channels, H, W)
+
+ if return_dict:
+ return {'x': x}
+ if self.learn_sigma:
+ return x[:,:self.out_channels // 2,:oh,:ow]
+ return x[:,:,:oh,:ow]
+
+ def unpatchify(self, x, h, w):
+ """
+ x: (N, T, patch_size**2 * C)
+ imgs: (N, H, W, C)
+ """
+ c = self.unpatchify_channels
+ p = self.x_embedder.patch_size[0]
+ # h = w = int(x.shape[1] ** 0.5)
+ assert h * w == x.shape[1]
+
+ x = x.reshape(shape=(x.shape[0], h, w, p, p, c))
+ x = torch.einsum('nhwpqc->nchpwq', x)
+ imgs = x.reshape(shape=(x.shape[0], c, h * p, w * p))
+ return imgs
diff --git a/ComfyUI/comfy/ldm/hydit/poolers.py b/ComfyUI/comfy/ldm/hydit/poolers.py
new file mode 100644
index 0000000000000000000000000000000000000000..c1b878ed6b0541116794635c5c1b53a7ca13af47
--- /dev/null
+++ b/ComfyUI/comfy/ldm/hydit/poolers.py
@@ -0,0 +1,36 @@
+import torch
+import torch.nn as nn
+from comfy.ldm.modules.attention import optimized_attention
+import comfy.ops
+
+class AttentionPool(nn.Module):
+ def __init__(self, spacial_dim: int, embed_dim: int, num_heads: int, output_dim: int = None, dtype=None, device=None, operations=None):
+ super().__init__()
+ self.positional_embedding = nn.Parameter(torch.empty(spacial_dim + 1, embed_dim, dtype=dtype, device=device))
+ self.k_proj = operations.Linear(embed_dim, embed_dim, dtype=dtype, device=device)
+ self.q_proj = operations.Linear(embed_dim, embed_dim, dtype=dtype, device=device)
+ self.v_proj = operations.Linear(embed_dim, embed_dim, dtype=dtype, device=device)
+ self.c_proj = operations.Linear(embed_dim, output_dim or embed_dim, dtype=dtype, device=device)
+ self.num_heads = num_heads
+ self.embed_dim = embed_dim
+
+ def forward(self, x):
+ x = x[:,:self.positional_embedding.shape[0] - 1]
+ x = x.permute(1, 0, 2) # NLC -> LNC
+ x = torch.cat([x.mean(dim=0, keepdim=True), x], dim=0) # (L+1)NC
+ x = x + comfy.ops.cast_to_input(self.positional_embedding[:, None, :], x) # (L+1)NC
+
+ q = self.q_proj(x[:1])
+ k = self.k_proj(x)
+ v = self.v_proj(x)
+
+ batch_size = q.shape[1]
+ head_dim = self.embed_dim // self.num_heads
+ q = q.view(1, batch_size * self.num_heads, head_dim).transpose(0, 1).view(batch_size, self.num_heads, -1, head_dim)
+ k = k.view(k.shape[0], batch_size * self.num_heads, head_dim).transpose(0, 1).view(batch_size, self.num_heads, -1, head_dim)
+ v = v.view(v.shape[0], batch_size * self.num_heads, head_dim).transpose(0, 1).view(batch_size, self.num_heads, -1, head_dim)
+
+ attn_output = optimized_attention(q, k, v, self.num_heads, skip_reshape=True).transpose(0, 1)
+
+ attn_output = self.c_proj(attn_output)
+ return attn_output.squeeze(0)
diff --git a/ComfyUI/comfy/ldm/hydit/posemb_layers.py b/ComfyUI/comfy/ldm/hydit/posemb_layers.py
new file mode 100644
index 0000000000000000000000000000000000000000..dcb41a713cd94ea8472ff26e8865066887b1e486
--- /dev/null
+++ b/ComfyUI/comfy/ldm/hydit/posemb_layers.py
@@ -0,0 +1,224 @@
+import torch
+import numpy as np
+from typing import Union
+
+
+def _to_tuple(x):
+ if isinstance(x, int):
+ return x, x
+ else:
+ return x
+
+
+def get_fill_resize_and_crop(src, tgt):
+ th, tw = _to_tuple(tgt)
+ h, w = _to_tuple(src)
+
+ tr = th / tw # base resolution
+ r = h / w # target resolution
+
+ # resize
+ if r > tr:
+ resize_height = th
+ resize_width = int(round(th / h * w))
+ else:
+ resize_width = tw
+ resize_height = int(round(tw / w * h)) # resize the target resolution down based on the base resolution
+
+ crop_top = int(round((th - resize_height) / 2.0))
+ crop_left = int(round((tw - resize_width) / 2.0))
+
+ return (crop_top, crop_left), (crop_top + resize_height, crop_left + resize_width)
+
+
+def get_meshgrid(start, *args):
+ if len(args) == 0:
+ # start is grid_size
+ num = _to_tuple(start)
+ start = (0, 0)
+ stop = num
+ elif len(args) == 1:
+ # start is start, args[0] is stop, step is 1
+ start = _to_tuple(start)
+ stop = _to_tuple(args[0])
+ num = (stop[0] - start[0], stop[1] - start[1])
+ elif len(args) == 2:
+ # start is start, args[0] is stop, args[1] is num
+ start = _to_tuple(start)
+ stop = _to_tuple(args[0])
+ num = _to_tuple(args[1])
+ else:
+ raise ValueError(f"len(args) should be 0, 1 or 2, but got {len(args)}")
+
+ grid_h = np.linspace(start[0], stop[0], num[0], endpoint=False, dtype=np.float32)
+ grid_w = np.linspace(start[1], stop[1], num[1], endpoint=False, dtype=np.float32)
+ grid = np.meshgrid(grid_w, grid_h) # here w goes first
+ grid = np.stack(grid, axis=0) # [2, W, H]
+ return grid
+
+#################################################################################
+# Sine/Cosine Positional Embedding Functions #
+#################################################################################
+# https://github.com/facebookresearch/mae/blob/main/util/pos_embed.py
+
+def get_2d_sincos_pos_embed(embed_dim, start, *args, cls_token=False, extra_tokens=0):
+ """
+ grid_size: int of the grid height and width
+ return:
+ pos_embed: [grid_size*grid_size, embed_dim] or [1+grid_size*grid_size, embed_dim] (w/ or w/o cls_token)
+ """
+ grid = get_meshgrid(start, *args) # [2, H, w]
+ # grid_h = np.arange(grid_size, dtype=np.float32)
+ # grid_w = np.arange(grid_size, dtype=np.float32)
+ # grid = np.meshgrid(grid_w, grid_h) # here w goes first
+ # grid = np.stack(grid, axis=0) # [2, W, H]
+
+ grid = grid.reshape([2, 1, *grid.shape[1:]])
+ pos_embed = get_2d_sincos_pos_embed_from_grid(embed_dim, grid)
+ if cls_token and extra_tokens > 0:
+ pos_embed = np.concatenate([np.zeros([extra_tokens, embed_dim]), pos_embed], axis=0)
+ return pos_embed
+
+
+def get_2d_sincos_pos_embed_from_grid(embed_dim, grid):
+ assert embed_dim % 2 == 0
+
+ # use half of dimensions to encode grid_h
+ emb_h = get_1d_sincos_pos_embed_from_grid(embed_dim // 2, grid[0]) # (H*W, D/2)
+ emb_w = get_1d_sincos_pos_embed_from_grid(embed_dim // 2, grid[1]) # (H*W, D/2)
+
+ emb = np.concatenate([emb_h, emb_w], axis=1) # (H*W, D)
+ return emb
+
+
+def get_1d_sincos_pos_embed_from_grid(embed_dim, pos):
+ """
+ embed_dim: output dimension for each position
+ pos: a list of positions to be encoded: size (W,H)
+ out: (M, D)
+ """
+ assert embed_dim % 2 == 0
+ omega = np.arange(embed_dim // 2, dtype=np.float64)
+ omega /= embed_dim / 2.
+ omega = 1. / 10000**omega # (D/2,)
+
+ pos = pos.reshape(-1) # (M,)
+ out = np.einsum('m,d->md', pos, omega) # (M, D/2), outer product
+
+ emb_sin = np.sin(out) # (M, D/2)
+ emb_cos = np.cos(out) # (M, D/2)
+
+ emb = np.concatenate([emb_sin, emb_cos], axis=1) # (M, D)
+ return emb
+
+
+#################################################################################
+# Rotary Positional Embedding Functions #
+#################################################################################
+# https://github.com/facebookresearch/llama/blob/main/llama/model.py#L443
+
+def get_2d_rotary_pos_embed(embed_dim, start, *args, use_real=True):
+ """
+ This is a 2d version of precompute_freqs_cis, which is a RoPE for image tokens with 2d structure.
+
+ Parameters
+ ----------
+ embed_dim: int
+ embedding dimension size
+ start: int or tuple of int
+ If len(args) == 0, start is num; If len(args) == 1, start is start, args[0] is stop, step is 1;
+ If len(args) == 2, start is start, args[0] is stop, args[1] is num.
+ use_real: bool
+ If True, return real part and imaginary part separately. Otherwise, return complex numbers.
+
+ Returns
+ -------
+ pos_embed: torch.Tensor
+ [HW, D/2]
+ """
+ grid = get_meshgrid(start, *args) # [2, H, w]
+ grid = grid.reshape([2, 1, *grid.shape[1:]]) # Returns a sampling matrix with the same resolution as the target resolution
+ pos_embed = get_2d_rotary_pos_embed_from_grid(embed_dim, grid, use_real=use_real)
+ return pos_embed
+
+
+def get_2d_rotary_pos_embed_from_grid(embed_dim, grid, use_real=False):
+ assert embed_dim % 4 == 0
+
+ # use half of dimensions to encode grid_h
+ emb_h = get_1d_rotary_pos_embed(embed_dim // 2, grid[0].reshape(-1), use_real=use_real) # (H*W, D/4)
+ emb_w = get_1d_rotary_pos_embed(embed_dim // 2, grid[1].reshape(-1), use_real=use_real) # (H*W, D/4)
+
+ if use_real:
+ cos = torch.cat([emb_h[0], emb_w[0]], dim=1) # (H*W, D/2)
+ sin = torch.cat([emb_h[1], emb_w[1]], dim=1) # (H*W, D/2)
+ return cos, sin
+ else:
+ emb = torch.cat([emb_h, emb_w], dim=1) # (H*W, D/2)
+ return emb
+
+
+def get_1d_rotary_pos_embed(dim: int, pos: Union[np.ndarray, int], theta: float = 10000.0, use_real=False):
+ """
+ Precompute the frequency tensor for complex exponentials (cis) with given dimensions.
+
+ This function calculates a frequency tensor with complex exponentials using the given dimension 'dim'
+ and the end index 'end'. The 'theta' parameter scales the frequencies.
+ The returned tensor contains complex values in complex64 data type.
+
+ Args:
+ dim (int): Dimension of the frequency tensor.
+ pos (np.ndarray, int): Position indices for the frequency tensor. [S] or scalar
+ theta (float, optional): Scaling factor for frequency computation. Defaults to 10000.0.
+ use_real (bool, optional): If True, return real part and imaginary part separately.
+ Otherwise, return complex numbers.
+
+ Returns:
+ torch.Tensor: Precomputed frequency tensor with complex exponentials. [S, D/2]
+
+ """
+ if isinstance(pos, int):
+ pos = np.arange(pos)
+ freqs = 1.0 / (theta ** (torch.arange(0, dim, 2)[: (dim // 2)].float() / dim)) # [D/2]
+ t = torch.from_numpy(pos).to(freqs.device) # type: ignore # [S]
+ freqs = torch.outer(t, freqs).float() # type: ignore # [S, D/2]
+ if use_real:
+ freqs_cos = freqs.cos().repeat_interleave(2, dim=1) # [S, D]
+ freqs_sin = freqs.sin().repeat_interleave(2, dim=1) # [S, D]
+ return freqs_cos, freqs_sin
+ else:
+ freqs_cis = torch.polar(torch.ones_like(freqs), freqs) # complex64 # [S, D/2]
+ return freqs_cis
+
+
+
+def calc_sizes(rope_img, patch_size, th, tw):
+ if rope_img == 'extend':
+ # Expansion mode
+ sub_args = [(th, tw)]
+ elif rope_img.startswith('base'):
+ # Based on the specified dimensions, other dimensions are obtained through interpolation.
+ base_size = int(rope_img[4:]) // 8 // patch_size
+ start, stop = get_fill_resize_and_crop((th, tw), base_size)
+ sub_args = [start, stop, (th, tw)]
+ else:
+ raise ValueError(f"Unknown rope_img: {rope_img}")
+ return sub_args
+
+
+def init_image_posemb(rope_img,
+ resolutions,
+ patch_size,
+ hidden_size,
+ num_heads,
+ log_fn,
+ rope_real=True,
+ ):
+ freqs_cis_img = {}
+ for reso in resolutions:
+ th, tw = reso.height // 8 // patch_size, reso.width // 8 // patch_size
+ sub_args = calc_sizes(rope_img, patch_size, th, tw)
+ freqs_cis_img[str(reso)] = get_2d_rotary_pos_embed(hidden_size // num_heads, *sub_args, use_real=rope_real)
+ log_fn(f" Using image RoPE ({rope_img}) ({'real' if rope_real else 'complex'}): {sub_args} | ({reso}) "
+ f"{freqs_cis_img[str(reso)][0].shape if rope_real else freqs_cis_img[str(reso)].shape}")
+ return freqs_cis_img
diff --git a/ComfyUI/comfy/ldm/ideogram4/__pycache__/model.cpython-312.pyc b/ComfyUI/comfy/ldm/ideogram4/__pycache__/model.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..19cc83a538f0ec4e6b30cd5902db296f20ab11c9
Binary files /dev/null and b/ComfyUI/comfy/ldm/ideogram4/__pycache__/model.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/ideogram4/model.py b/ComfyUI/comfy/ldm/ideogram4/model.py
new file mode 100644
index 0000000000000000000000000000000000000000..12e1a14fb69e66226b6d98c6d927c92bc0c8bce1
--- /dev/null
+++ b/ComfyUI/comfy/ldm/ideogram4/model.py
@@ -0,0 +1,324 @@
+"""
+The Ideogram 4 transformer is a NextDiT/Lumina2-family single-stream model
+consumes Qwen3-VL hidden-state features (concatenated from 13 layers -> 53248 dims)
+packs ``[text tokens, image tokens]`` into one sequence with block-diagonal segment attention and 3D interleaved MRoPE.
+"""
+
+from __future__ import annotations
+
+import math
+
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+
+import comfy.model_management
+import comfy.ops
+import comfy.patcher_extension
+import comfy.quant_ops
+from comfy.ldm.lumina.model import FeedForward
+from comfy.ldm.modules.attention import optimized_attention_masked
+from comfy.text_encoders.llama import precompute_freqs_cis
+
+# Per-token role indicators
+SEQUENCE_PADDING_INDICATOR = -1
+OUTPUT_IMAGE_INDICATOR = 2
+LLM_TOKEN_INDICATOR = 3
+# Image grid coordinates are offset so they never collide with text positions
+IMAGE_POSITION_OFFSET = 65536
+
+
+def _split_half_rope_matrix(freqs_cis):
+ cos, sin, neg_sin = freqs_cis
+ half_dim = sin.shape[-1]
+ matrix = torch.stack(
+ (cos[..., :half_dim], neg_sin, sin, cos[..., half_dim:]), dim=-1
+ )
+ return matrix.reshape(*matrix.shape[:-1], 2, 2).unsqueeze(2)
+
+
+def _apply_rope_split_half1(x, freqs_cis):
+ x_dtype = x.dtype
+ x = x.reshape(*x.shape[:-1], 2, -1).movedim(-2, -1).unsqueeze(-2).to(freqs_cis.dtype)
+ output = freqs_cis[..., 0] * x[..., 0] + freqs_cis[..., 1] * x[..., 1]
+ return output.movedim(-1, -2).reshape(*x.shape[:-3], -1).to(x_dtype)
+
+
+class Ideogram4Attention(nn.Module):
+ def __init__(self, hidden_size, num_heads, eps=1e-5, dtype=None, device=None, operations=None):
+ super().__init__()
+ self.num_heads = num_heads
+ self.head_dim = hidden_size // num_heads
+ self.hidden_size = hidden_size
+
+ self.qkv = operations.Linear(hidden_size, hidden_size * 3, bias=False, dtype=dtype, device=device)
+ self.norm_q = operations.RMSNorm(self.head_dim, eps=eps, elementwise_affine=True, dtype=dtype, device=device)
+ self.norm_k = operations.RMSNorm(self.head_dim, eps=eps, elementwise_affine=True, dtype=dtype, device=device)
+ self.o = operations.Linear(hidden_size, hidden_size, bias=False, dtype=dtype, device=device)
+
+ def forward(self, x, attn_mask, freqs_cis, transformer_options={}):
+ batch_size, seq_len, _ = x.shape
+ qkv = self.qkv(x).view(batch_size, seq_len, 3, self.num_heads, self.head_dim)
+ q, k, v = qkv.unbind(dim=2)
+
+ if comfy.model_management.in_training:
+ q = _apply_rope_split_half1(self.norm_q(q), freqs_cis)
+ k = _apply_rope_split_half1(self.norm_k(k), freqs_cis)
+ else:
+ q_scale, _, q_offload_stream = comfy.ops.cast_bias_weight(self.norm_q, q, offloadable=True)
+ k_scale, _, k_offload_stream = comfy.ops.cast_bias_weight(self.norm_k, k, offloadable=True)
+ q, k = comfy.quant_ops.ck.rms_rope_split_half(
+ q, k, freqs_cis, q_scale, k_scale, self.norm_q.eps
+ )
+ comfy.ops.uncast_bias_weight(self.norm_q, q_scale, None, q_offload_stream)
+ comfy.ops.uncast_bias_weight(self.norm_k, k_scale, None, k_offload_stream)
+
+ # (B, heads, L, head_dim)
+ q = q.transpose(1, 2)
+ k = k.transpose(1, 2)
+ v = v.transpose(1, 2)
+
+ out = optimized_attention_masked(q, k, v, self.num_heads, attn_mask, skip_reshape=True, transformer_options=transformer_options)
+ return self.o(out)
+
+
+class Ideogram4TransformerBlock(nn.Module):
+ def __init__(self, hidden_size, intermediate_size, num_heads, norm_eps, adaln_dim, dtype=None, device=None, operations=None):
+ super().__init__()
+ self.attention = Ideogram4Attention(hidden_size, num_heads, eps=1e-5, dtype=dtype, device=device, operations=operations)
+ self.feed_forward = FeedForward(
+ dim=hidden_size, hidden_dim=intermediate_size, multiple_of=1, ffn_dim_multiplier=None,
+ operation_settings={"operations": operations, "dtype": dtype, "device": device},
+ )
+
+ self.attention_norm1 = operations.RMSNorm(hidden_size, eps=norm_eps, elementwise_affine=True, dtype=dtype, device=device)
+ self.ffn_norm1 = operations.RMSNorm(hidden_size, eps=norm_eps, elementwise_affine=True, dtype=dtype, device=device)
+ self.attention_norm2 = operations.RMSNorm(hidden_size, eps=norm_eps, elementwise_affine=True, dtype=dtype, device=device)
+ self.ffn_norm2 = operations.RMSNorm(hidden_size, eps=norm_eps, elementwise_affine=True, dtype=dtype, device=device)
+
+ self.adaln_modulation = operations.Linear(adaln_dim, 4 * hidden_size, bias=True, dtype=dtype, device=device)
+
+ def forward(self, x, attn_mask, freqs_cis, adaln_input, transformer_options={}):
+ mod = self.adaln_modulation(adaln_input)
+ scale_msa, gate_msa, scale_mlp, gate_mlp = mod.chunk(4, dim=-1)
+ gate_msa = torch.tanh(gate_msa)
+ gate_mlp = torch.tanh(gate_mlp)
+ scale_msa = 1.0 + scale_msa
+ scale_mlp = 1.0 + scale_mlp
+
+ attn_out = self.attention(self.attention_norm1(x) * scale_msa, attn_mask, freqs_cis, transformer_options=transformer_options)
+ x = x + gate_msa * self.attention_norm2(attn_out)
+ x = x + gate_mlp * self.ffn_norm2(self.feed_forward(self.ffn_norm1(x) * scale_mlp))
+ return x
+
+
+def _sinusoidal_embedding(t, dim, scale=1e4):
+ t = t.to(torch.float32)
+ half = dim // 2
+ freq = math.log(scale) / (half - 1)
+ freq = torch.exp(torch.arange(half, dtype=torch.float32, device=t.device) * -freq)
+ emb = t.unsqueeze(-1) * freq
+ emb = torch.cat([torch.sin(emb), torch.cos(emb)], dim=-1)
+ if dim % 2 == 1:
+ emb = F.pad(emb, (0, 1))
+ return emb
+
+
+class Ideogram4EmbedScalar(nn.Module):
+ def __init__(self, dim, input_range=(0.0, 1.0), dtype=None, device=None, operations=None):
+ super().__init__()
+ self.dim = dim
+ self.range_min, self.range_max = input_range
+ self.mlp_in = operations.Linear(dim, dim, bias=True, dtype=dtype, device=device)
+ self.mlp_out = operations.Linear(dim, dim, bias=True, dtype=dtype, device=device)
+
+ def forward(self, x, dtype):
+ x = x.to(torch.float32)
+ scaled = 1e4 * (x - self.range_min) / (self.range_max - self.range_min)
+ emb = _sinusoidal_embedding(scaled, self.dim)
+ emb = emb.to(dtype)
+ emb = F.silu(self.mlp_in(emb))
+ return self.mlp_out(emb)
+
+
+class Ideogram4FinalLayer(nn.Module):
+ def __init__(self, hidden_size, out_channels, adaln_dim, dtype=None, device=None, operations=None):
+ super().__init__()
+ self.norm_final = operations.LayerNorm(hidden_size, eps=1e-6, elementwise_affine=False, dtype=dtype, device=device)
+ self.linear = operations.Linear(hidden_size, out_channels, bias=True, dtype=dtype, device=device)
+ self.adaln_modulation = operations.Linear(adaln_dim, hidden_size, bias=True, dtype=dtype, device=device)
+
+ def forward(self, x, c):
+ scale = 1.0 + self.adaln_modulation(F.silu(c))
+ return self.linear(self.norm_final(x) * scale)
+
+
+class Ideogram4Transformer(nn.Module):
+ """A single Ideogram 4 backbone operating on a packed token sequence."""
+
+ def __init__(self, emb_dim, num_layers, num_heads, intermediate_size, adaln_dim,
+ in_channels, llm_features_dim, rope_theta, mrope_section, norm_eps,
+ dtype=None, device=None, operations=None):
+ super().__init__()
+ self.head_dim = emb_dim // num_heads
+ self.rope_theta = rope_theta
+ self.mrope_section = tuple(mrope_section)
+
+ self.input_proj = operations.Linear(in_channels, emb_dim, bias=True, dtype=dtype, device=device)
+ self.llm_cond_norm = operations.RMSNorm(llm_features_dim, eps=1e-6, elementwise_affine=True, dtype=dtype, device=device)
+ self.llm_cond_proj = operations.Linear(llm_features_dim, emb_dim, bias=True, dtype=dtype, device=device)
+ self.t_embedding = Ideogram4EmbedScalar(emb_dim, input_range=(0.0, 1.0), dtype=dtype, device=device, operations=operations)
+ self.adaln_proj = operations.Linear(emb_dim, adaln_dim, bias=True, dtype=dtype, device=device)
+
+ self.embed_image_indicator = operations.Embedding(2, emb_dim, dtype=dtype, device=device)
+
+ self.layers = nn.ModuleList([
+ Ideogram4TransformerBlock(emb_dim, intermediate_size, num_heads, norm_eps, adaln_dim,
+ dtype=dtype, device=device, operations=operations)
+ for _ in range(num_layers)
+ ])
+
+ self.final_layer = Ideogram4FinalLayer(emb_dim, in_channels, adaln_dim, dtype=dtype, device=device, operations=operations)
+
+ def _backbone(self, llm_features, x, t, position_ids, attn_mask, indicator, transformer_options={}):
+ indicator = indicator.to(torch.long)
+ output_image_mask = (indicator == OUTPUT_IMAGE_INDICATOR).to(x.dtype).unsqueeze(-1)
+
+ x = x * output_image_mask
+ h = self.input_proj(x) * output_image_mask
+
+ t_cond = self.t_embedding(t, dtype=x.dtype)
+ if t.dim() == 1:
+ t_cond = t_cond.unsqueeze(1)
+ adaln_input = F.silu(self.adaln_proj(t_cond))
+
+ # h is zero on the text rows (content lives only on image rows), add writes the text features in place
+ if llm_features is not None:
+ L_text = llm_features.shape[1]
+ text_mask = (indicator[:, :L_text] == LLM_TOKEN_INDICATOR).to(x.dtype).unsqueeze(-1)
+ llm = self.llm_cond_norm(llm_features * text_mask)
+ llm = self.llm_cond_proj(llm) * text_mask
+ h[:, :L_text] = h[:, :L_text] + llm
+
+ h = h + self.embed_image_indicator((indicator == OUTPUT_IMAGE_INDICATOR).to(torch.long), out_dtype=h.dtype)
+
+ # Qwen3-VL interleaved MRoPE; position_ids (B, L, 3) -> (3, L) (same across batch).
+ freqs_cis = precompute_freqs_cis(
+ self.head_dim, position_ids[0].transpose(0, 1), self.rope_theta,
+ rope_dims=self.mrope_section, interleaved_mrope=True, device=position_ids.device,
+ )
+ freqs_cis = _split_half_rope_matrix(freqs_cis)
+
+ if attn_mask is not None and attn_mask.dtype == torch.bool:
+ attn_mask = torch.zeros_like(attn_mask, dtype=h.dtype).masked_fill_(~attn_mask, -torch.finfo(h.dtype).max)
+
+ for layer in self.layers:
+ h = layer(h, attn_mask, freqs_cis, adaln_input, transformer_options=transformer_options)
+
+ return self.final_layer(h, adaln_input)
+
+
+class Ideogram4Transformer2DModel(Ideogram4Transformer):
+ """Ideogram 4 single-stream DiT.
+
+ Runs a packed ``[text, image]`` sequence when text context is supplied, or an image-only sequence when ``context is None``.
+ """
+
+ def __init__(self, image_model=None, in_channels=128, num_layers=34, num_attention_heads=18, attention_head_dim=256, intermediate_size=12288,
+ adaln_dim=512, llm_features_dim=53248, rope_theta=5000000, mrope_section=(24, 20, 20), norm_eps=1e-5,
+ dtype=None, device=None, operations=None, **kwargs):
+ emb_dim = num_attention_heads * attention_head_dim
+ super().__init__(
+ emb_dim=emb_dim, num_layers=num_layers, num_heads=num_attention_heads,
+ intermediate_size=intermediate_size, adaln_dim=adaln_dim, in_channels=in_channels,
+ llm_features_dim=llm_features_dim, rope_theta=rope_theta, mrope_section=mrope_section,
+ norm_eps=norm_eps, dtype=dtype, device=device, operations=operations)
+ self.dtype = dtype
+ self.in_channels = in_channels
+ self.out_channels = in_channels
+ # 128-dim token = patch (2x2) * ae_channels (32).
+ self.patch_size = 2
+ self.ae_channels = in_channels // (self.patch_size * self.patch_size)
+
+ def _img_to_tokens(self, x):
+ B, C, gh, gw = x.shape
+ x = x.view(B, self.ae_channels, self.patch_size, self.patch_size, gh, gw)
+ x = x.permute(0, 4, 5, 2, 3, 1) # (B, gh, gw, pi, pj, c)
+ return x.reshape(B, gh * gw, C)
+
+ def _tokens_to_img(self, tokens, gh, gw):
+ B = tokens.shape[0]
+ C = tokens.shape[-1]
+ x = tokens.reshape(B, gh, gw, self.patch_size, self.patch_size, self.ae_channels)
+ x = x.permute(0, 5, 3, 4, 1, 2) # (B, c, pi, pj, gh, gw)
+ return x.reshape(B, C, gh, gw)
+
+ def _image_position_ids(self, gh, gw, device):
+ h_idx = torch.arange(gh, device=device).view(-1, 1).expand(gh, gw).reshape(-1)
+ w_idx = torch.arange(gw, device=device).view(1, -1).expand(gh, gw).reshape(-1)
+ t_idx = torch.zeros_like(h_idx)
+ return torch.stack([t_idx, h_idx, w_idx], dim=1) + IMAGE_POSITION_OFFSET # (L_img, 3)
+
+ def _run_conditional(self, x_chunk, context_chunk, attn_mask_chunk, t_chunk, gh, gw, transformer_options):
+ B = x_chunk.shape[0]
+ device = x_chunk.device
+ img_tokens = self._img_to_tokens(x_chunk)
+ L_img = img_tokens.shape[1]
+ L_text = context_chunk.shape[1]
+ L = L_text + L_img
+ latent_dim = img_tokens.shape[-1]
+
+ x_full = torch.zeros(B, L, latent_dim, dtype=img_tokens.dtype, device=device)
+ x_full[:, L_text:] = img_tokens
+
+ text_pos = torch.arange(L_text, device=device).view(-1, 1).expand(L_text, 3)
+ img_pos = self._image_position_ids(gh, gw, device)
+ position_ids = torch.cat([text_pos, img_pos], dim=0).unsqueeze(0).expand(B, L, 3)
+
+ indicator = torch.empty(B, L, dtype=torch.long, device=device)
+ indicator[:, :L_text] = LLM_TOKEN_INDICATOR
+ indicator[:, L_text:] = OUTPUT_IMAGE_INDICATOR
+
+ attn_mask = None
+ if attn_mask_chunk is not None:
+ segment_ids = torch.ones(B, L, dtype=torch.long, device=device)
+ pad = (attn_mask_chunk == 0)
+ segment_ids[:, :L_text][pad] = SEQUENCE_PADDING_INDICATOR
+ indicator[:, :L_text][pad] = 0
+ # Block-diagonal mask from segment ids: (B, 1, L, L), True = attend.
+ attn_mask = (segment_ids.unsqueeze(2) == segment_ids.unsqueeze(1)).unsqueeze(1)
+
+ out = self._backbone(context_chunk, x_full, t_chunk, position_ids, attn_mask, indicator,
+ transformer_options=transformer_options)
+ return self._tokens_to_img(out[:, L_text:], gh, gw)
+
+ def _run_image_only(self, x_chunk, t_chunk, gh, gw, transformer_options):
+ B = x_chunk.shape[0]
+ device = x_chunk.device
+ img_tokens = self._img_to_tokens(x_chunk)
+ L_img = img_tokens.shape[1]
+
+ position_ids = self._image_position_ids(gh, gw, device).unsqueeze(0).expand(B, L_img, 3)
+ indicator = torch.full((B, L_img), OUTPUT_IMAGE_INDICATOR, dtype=torch.long, device=device)
+
+ # Image-only sequence is a single segment -> no mask, full attention, no LLM context.
+ out = self._backbone(None, img_tokens, t_chunk, position_ids, None, indicator, transformer_options=transformer_options)
+ return self._tokens_to_img(out, gh, gw)
+
+ def forward(self, x, timesteps, context=None, attention_mask=None, transformer_options={}, **kwargs):
+ return comfy.patcher_extension.WrapperExecutor.new_class_executor(
+ self._forward,
+ self,
+ comfy.patcher_extension.get_all_wrappers(comfy.patcher_extension.WrappersMP.DIFFUSION_MODEL, transformer_options),
+ ).execute(x, timesteps, context, attention_mask, transformer_options, **kwargs)
+
+ def _forward(self, x, timesteps, context=None, attention_mask=None, transformer_options={}, **kwargs):
+ bs, c, gh, gw = x.shape
+
+ timesteps = 1.0 - timesteps
+
+ # unconditional pass
+ if context is None:
+ return -self._run_image_only(x, timesteps, gh, gw, transformer_options)
+
+ return -self._run_conditional(x, context, attention_mask, timesteps, gh, gw, transformer_options)
diff --git a/ComfyUI/comfy/ldm/joyimage/__pycache__/model.cpython-312.pyc b/ComfyUI/comfy/ldm/joyimage/__pycache__/model.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..bff3f8231fd2fcf92093cfa6dc94fce9f1970b0a
Binary files /dev/null and b/ComfyUI/comfy/ldm/joyimage/__pycache__/model.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/joyimage/model.py b/ComfyUI/comfy/ldm/joyimage/model.py
new file mode 100644
index 0000000000000000000000000000000000000000..9d6951e54e4d8b386cc85d074255c42546661f0f
--- /dev/null
+++ b/ComfyUI/comfy/ldm/joyimage/model.py
@@ -0,0 +1,454 @@
+# https://github.com/jdopensource/JoyAI-Image-Edit (Apache 2.0)
+import math
+from typing import Optional, Tuple
+
+import comfy_kitchen
+import torch
+import torch.nn as nn
+
+import comfy.ldm.common_dit
+import comfy.ops
+import comfy.patcher_extension
+from comfy.ldm.lightricks.model import GELU_approx, PixArtAlphaTextProjection, TimestepEmbedding, Timesteps
+from comfy.ldm.modules.attention import optimized_attention
+
+
+class JoyImageModulate(nn.Module):
+ def __init__(self, hidden_size: int, factor: int, dtype=None, device=None):
+ super().__init__()
+ self.factor = factor
+ self.modulate_table = nn.Parameter(
+ torch.empty(1, factor, hidden_size, dtype=dtype, device=device)
+ )
+
+ def forward(self, x: torch.Tensor) -> list:
+ if x.ndim != 3:
+ x = x.unsqueeze(1)
+ table = comfy.ops.cast_to_input(self.modulate_table, x)
+ return [o.squeeze(1) for o in (table + x).chunk(self.factor, dim=1)]
+
+
+class JoyImageFeedForward(nn.Module):
+ def __init__(
+ self,
+ dim: int,
+ inner_dim: int,
+ dtype=None,
+ device=None,
+ operations=None,
+ ):
+ super().__init__()
+ self.net = nn.ModuleList([
+ GELU_approx(dim, inner_dim, dtype=dtype, device=device, operations=operations),
+ nn.Identity(),
+ operations.Linear(inner_dim, dim, bias=True, dtype=dtype, device=device),
+ ])
+
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
+ for module in self.net:
+ x = module(x)
+ return x
+
+
+class JoyImageAttention(nn.Module):
+ def __init__(
+ self,
+ dim: int,
+ num_attention_heads: int,
+ attention_head_dim: int,
+ eps: float = 1e-6,
+ dtype=None,
+ device=None,
+ operations=None,
+ ):
+ super().__init__()
+ self.num_attention_heads = num_attention_heads
+ inner_dim = num_attention_heads * attention_head_dim
+
+ self.img_attn_qkv = operations.Linear(dim, inner_dim * 3, bias=True, dtype=dtype, device=device)
+ self.img_attn_q_norm = operations.RMSNorm(attention_head_dim, eps=eps, dtype=dtype, device=device)
+ self.img_attn_k_norm = operations.RMSNorm(attention_head_dim, eps=eps, dtype=dtype, device=device)
+ self.img_attn_proj = operations.Linear(inner_dim, dim, bias=True, dtype=dtype, device=device)
+
+ self.txt_attn_qkv = operations.Linear(dim, inner_dim * 3, bias=True, dtype=dtype, device=device)
+ self.txt_attn_q_norm = operations.RMSNorm(attention_head_dim, eps=eps, dtype=dtype, device=device)
+ self.txt_attn_k_norm = operations.RMSNorm(attention_head_dim, eps=eps, dtype=dtype, device=device)
+ self.txt_attn_proj = operations.Linear(inner_dim, dim, bias=True, dtype=dtype, device=device)
+
+ def forward(
+ self,
+ img: torch.Tensor,
+ txt: torch.Tensor,
+ image_rotary_emb: torch.Tensor,
+ transformer_options=None,
+ ) -> Tuple[torch.Tensor, torch.Tensor]:
+ heads = self.num_attention_heads
+
+ img_q, img_k, img_v = self.img_attn_qkv(img).chunk(3, dim=-1)
+ txt_q, txt_k, txt_v = self.txt_attn_qkv(txt).chunk(3, dim=-1)
+
+ img_q = img_q.unflatten(-1, (heads, -1))
+ img_k = img_k.unflatten(-1, (heads, -1))
+ img_v = img_v.unflatten(-1, (heads, -1))
+ txt_q = txt_q.unflatten(-1, (heads, -1))
+ txt_k = txt_k.unflatten(-1, (heads, -1))
+ txt_v = txt_v.unflatten(-1, (heads, -1))
+
+ txt_q = self.txt_attn_q_norm(txt_q)
+ txt_k = self.txt_attn_k_norm(txt_k)
+
+ img_q_scale, _, img_q_offload_stream = comfy.ops.cast_bias_weight(self.img_attn_q_norm, img_q, offloadable=True)
+ img_k_scale, _, img_k_offload_stream = comfy.ops.cast_bias_weight(self.img_attn_k_norm, img_k, offloadable=True)
+ img_q, img_k = comfy_kitchen.rms_rope(
+ img_q,
+ img_k,
+ image_rotary_emb,
+ img_q_scale,
+ img_k_scale,
+ self.img_attn_q_norm.eps,
+ )
+ comfy.ops.uncast_bias_weight(self.img_attn_q_norm, img_q_scale, None, img_q_offload_stream)
+ comfy.ops.uncast_bias_weight(self.img_attn_k_norm, img_k_scale, None, img_k_offload_stream)
+
+ joint_q = torch.cat([img_q, txt_q], dim=1)
+ joint_k = torch.cat([img_k, txt_k], dim=1)
+ joint_v = torch.cat([img_v, txt_v], dim=1)
+
+ joint_q = joint_q.flatten(2, 3)
+ joint_k = joint_k.flatten(2, 3)
+ joint_v = joint_v.flatten(2, 3)
+
+ joint_out = optimized_attention(joint_q, joint_k, joint_v, heads=heads, transformer_options=transformer_options)
+
+ seq_img = img.shape[1]
+ img_out = joint_out[:, :seq_img, :]
+ txt_out = joint_out[:, seq_img:, :]
+
+ img_out = self.img_attn_proj(img_out)
+ txt_out = self.txt_attn_proj(txt_out)
+ return img_out, txt_out
+
+
+class JoyImageTransformerBlock(nn.Module):
+ def __init__(
+ self,
+ dim: int,
+ num_attention_heads: int,
+ attention_head_dim: int,
+ mlp_width_ratio: float = 4.0,
+ eps: float = 1e-6,
+ dtype=None,
+ device=None,
+ operations=None,
+ ):
+ super().__init__()
+ mlp_hidden_dim = int(dim * mlp_width_ratio)
+
+ self.img_mod = JoyImageModulate(dim, factor=6, dtype=dtype, device=device)
+ self.img_norm1 = operations.LayerNorm(dim, elementwise_affine=False, eps=eps, dtype=dtype, device=device)
+ self.img_norm2 = operations.LayerNorm(dim, elementwise_affine=False, eps=eps, dtype=dtype, device=device)
+ self.img_mlp = JoyImageFeedForward(dim, inner_dim=mlp_hidden_dim, dtype=dtype, device=device, operations=operations)
+
+ self.txt_mod = JoyImageModulate(dim, factor=6, dtype=dtype, device=device)
+ self.txt_norm1 = operations.LayerNorm(dim, elementwise_affine=False, eps=eps, dtype=dtype, device=device)
+ self.txt_norm2 = operations.LayerNorm(dim, elementwise_affine=False, eps=eps, dtype=dtype, device=device)
+ self.txt_mlp = JoyImageFeedForward(dim, inner_dim=mlp_hidden_dim, dtype=dtype, device=device, operations=operations)
+
+ self.attn = JoyImageAttention(
+ dim=dim,
+ num_attention_heads=num_attention_heads,
+ attention_head_dim=attention_head_dim,
+ eps=eps,
+ dtype=dtype,
+ device=device,
+ operations=operations,
+ )
+
+ def forward(
+ self,
+ hidden_states: torch.Tensor,
+ encoder_hidden_states: torch.Tensor,
+ temb: torch.Tensor,
+ image_rotary_emb: torch.Tensor,
+ transformer_options=None,
+ ) -> Tuple[torch.Tensor, torch.Tensor]:
+ (
+ img_mod1_shift,
+ img_mod1_scale,
+ img_mod1_gate,
+ img_mod2_shift,
+ img_mod2_scale,
+ img_mod2_gate,
+ ) = self.img_mod(temb)
+ (
+ txt_mod1_shift,
+ txt_mod1_scale,
+ txt_mod1_gate,
+ txt_mod2_shift,
+ txt_mod2_scale,
+ txt_mod2_gate,
+ ) = self.txt_mod(temb)
+
+ img_normed = self.img_norm1(hidden_states)
+ txt_normed = self.txt_norm1(encoder_hidden_states)
+ img_modulated = img_normed * (1 + img_mod1_scale.unsqueeze(1)) + img_mod1_shift.unsqueeze(1)
+ txt_modulated = txt_normed * (1 + txt_mod1_scale.unsqueeze(1)) + txt_mod1_shift.unsqueeze(1)
+
+ img_attn, txt_attn = self.attn(img_modulated, txt_modulated, image_rotary_emb, transformer_options=transformer_options)
+
+ hidden_states = hidden_states + img_attn * img_mod1_gate.unsqueeze(1)
+ encoder_hidden_states = encoder_hidden_states + txt_attn * txt_mod1_gate.unsqueeze(1)
+
+ img_ffn_normed = self.img_norm2(hidden_states)
+ txt_ffn_normed = self.txt_norm2(encoder_hidden_states)
+ img_ffn_input = img_ffn_normed * (1 + img_mod2_scale.unsqueeze(1)) + img_mod2_shift.unsqueeze(1)
+ txt_ffn_input = txt_ffn_normed * (1 + txt_mod2_scale.unsqueeze(1)) + txt_mod2_shift.unsqueeze(1)
+ hidden_states = hidden_states + self.img_mlp(img_ffn_input) * img_mod2_gate.unsqueeze(1)
+ encoder_hidden_states = encoder_hidden_states + self.txt_mlp(txt_ffn_input) * txt_mod2_gate.unsqueeze(1)
+
+ return hidden_states, encoder_hidden_states
+
+
+class JoyImageTimeTextImageEmbedding(nn.Module):
+ def __init__(
+ self,
+ dim: int,
+ time_freq_dim: int,
+ time_proj_dim: int,
+ text_embed_dim: int,
+ dtype=None,
+ device=None,
+ operations=None,
+ ):
+ super().__init__()
+ self.timesteps_proj = Timesteps(num_channels=time_freq_dim, flip_sin_to_cos=True, downscale_freq_shift=0)
+ self.time_embedder = TimestepEmbedding(
+ in_channels=time_freq_dim,
+ time_embed_dim=dim,
+ dtype=dtype,
+ device=device,
+ operations=operations,
+ )
+ self.act_fn = nn.SiLU()
+ self.time_proj = operations.Linear(dim, time_proj_dim, bias=True, dtype=dtype, device=device)
+ self.text_embedder = PixArtAlphaTextProjection(
+ text_embed_dim, dim, act_fn="gelu_tanh", dtype=dtype, device=device, operations=operations,
+ )
+
+ def forward(self, timestep: torch.Tensor, encoder_hidden_states: torch.Tensor):
+ timestep = self.timesteps_proj(timestep)
+ temb = self.time_embedder(timestep.to(dtype=encoder_hidden_states.dtype)).type_as(encoder_hidden_states)
+ timestep_proj = self.time_proj(self.act_fn(temb))
+ encoder_hidden_states = self.text_embedder(encoder_hidden_states)
+ return temb, timestep_proj, encoder_hidden_states
+
+
+class JoyImageTransformer3DModel(nn.Module):
+ def __init__(
+ self,
+ patch_size: list = [1, 2, 2],
+ in_channels: int = 16,
+ out_channels: Optional[int] = None,
+ hidden_size: int = 3072,
+ num_attention_heads: int = 24,
+ text_dim: int = 4096,
+ mlp_width_ratio: float = 4.0,
+ num_layers: int = 20,
+ rope_dim_list: list = [16, 56, 56],
+ theta: int = 256,
+ image_model=None,
+ dtype=None,
+ device=None,
+ operations=None,
+ ):
+ super().__init__()
+ self.dtype = dtype
+ self.out_channels = out_channels or in_channels
+ self.patch_size = list(patch_size)
+ self.rope_dim_list = list(rope_dim_list)
+ self.theta = theta
+
+ attention_head_dim = hidden_size // num_attention_heads
+
+ self.img_in = operations.Conv3d(
+ in_channels,
+ hidden_size,
+ kernel_size=tuple(self.patch_size),
+ stride=tuple(self.patch_size),
+ dtype=dtype,
+ device=device,
+ )
+
+ self.condition_embedder = JoyImageTimeTextImageEmbedding(
+ dim=hidden_size,
+ time_freq_dim=256,
+ time_proj_dim=hidden_size * 6,
+ text_embed_dim=text_dim,
+ dtype=dtype,
+ device=device,
+ operations=operations,
+ )
+
+ self.double_blocks = nn.ModuleList([
+ JoyImageTransformerBlock(
+ dim=hidden_size,
+ num_attention_heads=num_attention_heads,
+ attention_head_dim=attention_head_dim,
+ mlp_width_ratio=mlp_width_ratio,
+ dtype=dtype,
+ device=device,
+ operations=operations,
+ )
+ for _ in range(num_layers)
+ ])
+
+ self.norm_out = operations.LayerNorm(hidden_size, elementwise_affine=False, eps=1e-6, dtype=dtype, device=device)
+ self.proj_out = operations.Linear(
+ hidden_size,
+ self.out_channels * math.prod(self.patch_size),
+ bias=True,
+ dtype=dtype,
+ device=device,
+ )
+
+ def _get_rotary_pos_embed_for_range(
+ self,
+ start: Tuple[int, int, int],
+ stop: Tuple[int, int, int],
+ device=None,
+ ) -> torch.Tensor:
+ # 3D RoPE for the patch grid range [start, stop) over (t, h, w). Token order after
+ # reshape(-1) is (t, h, w), matching the img_in Conv3d flatten.
+ rope_dim_list = self.rope_dim_list
+
+ grids = [torch.arange(start[i], stop[i], dtype=torch.float32, device=device) for i in range(3)]
+ mesh = torch.stack(torch.meshgrid(*grids, indexing="ij"), dim=0)
+
+ angles_parts = []
+ for i, dim in enumerate(rope_dim_list):
+ pos = mesh[i].reshape(-1)
+ freqs = 1.0 / (self.theta ** (torch.arange(0, dim, 2, dtype=torch.float32, device=device)[: (dim // 2)] / dim))
+ angles_parts.append(torch.outer(pos, freqs))
+
+ angles = torch.cat(angles_parts, dim=1)
+ cos = angles.cos()
+ sin = angles.sin()
+ return torch.stack((cos, -sin, sin, cos), dim=-1).unflatten(-1, (2, 2))
+
+ def get_rotary_pos_embed_for_components(
+ self,
+ component_sizes,
+ device=None,
+ ) -> torch.Tensor:
+ # Per-component 3D RoPE. component_sizes is a list of (t, h, w) patch grid sizes in
+ # sequence order [target, ref0, ref1, ...]; h/w restart at 0 for each component while t
+ # continues from the running offset, giving every image its own temporal position band.
+ freqs_parts = []
+ t_offset = 0
+ for (t, h, w) in component_sizes:
+ freqs = self._get_rotary_pos_embed_for_range(
+ start=(t_offset, 0, 0),
+ stop=(t_offset + t, h, w),
+ device=device,
+ )
+ freqs_parts.append(freqs)
+ t_offset += t
+ return torch.cat(freqs_parts, dim=0).unsqueeze(0).unsqueeze(2)
+
+ def unpatchify(self, x: torch.Tensor, t: int, h: int, w: int) -> torch.Tensor:
+ c = self.out_channels
+ pt, ph, pw = self.patch_size
+ x = x.reshape(x.shape[0], t, h, w, pt, ph, pw, c)
+ x = x.permute(0, 7, 1, 4, 2, 5, 3, 6)
+ return x.reshape(x.shape[0], c, t * pt, h * ph, w * pw)
+
+ def forward(
+ self,
+ hidden_states: torch.Tensor,
+ timestep: torch.Tensor,
+ context: torch.Tensor = None,
+ ref_latents=None,
+ control=None,
+ transformer_options=None,
+ **kwargs,
+ ) -> torch.Tensor:
+ transformer_options = {} if transformer_options is None else transformer_options.copy()
+ return comfy.patcher_extension.WrapperExecutor.new_class_executor(
+ self._forward,
+ self,
+ comfy.patcher_extension.get_all_wrappers(comfy.patcher_extension.WrappersMP.DIFFUSION_MODEL, transformer_options)
+ ).execute(hidden_states, timestep, context, ref_latents, transformer_options, **kwargs)
+
+ def _forward(
+ self,
+ hidden_states: torch.Tensor,
+ timestep: torch.Tensor,
+ context: torch.Tensor,
+ ref_latents=None,
+ transformer_options=None,
+ **kwargs,
+ ) -> torch.Tensor:
+ pt, ph, pw = self.patch_size
+ _, _, ot, oh, ow = hidden_states.shape
+
+ components = [hidden_states, *(ref_latents or [])]
+ component_sizes = []
+ img_tokens = []
+ for comp in components:
+ comp = comfy.ldm.common_dit.pad_to_patch_size(comp, self.patch_size)
+ _, _, ct, ch, cw = comp.shape
+ component_sizes.append((ct // pt, ch // ph, cw // pw))
+ tokens = self.img_in(comp).flatten(2).transpose(1, 2) # (B, n_i, D)
+ img_tokens.append(tokens)
+
+ img = torch.cat(img_tokens, dim=1)
+
+ _, vec, txt = self.condition_embedder(timestep, context)
+ vec = vec.unflatten(1, (6, -1))
+
+ image_rotary_emb = self.get_rotary_pos_embed_for_components(
+ component_sizes,
+ device=hidden_states.device,
+ )
+
+ patches_replace = transformer_options.get("patches_replace", {})
+ blocks_replace = patches_replace.get("dit", {})
+ transformer_options["total_blocks"] = len(self.double_blocks)
+ transformer_options["block_type"] = "double"
+ for i, block in enumerate(self.double_blocks):
+ transformer_options["block_index"] = i
+ if ("double_block", i) in blocks_replace:
+ def block_wrap(args):
+ out = {}
+ out["img"], out["txt"] = block(
+ hidden_states=args["img"],
+ encoder_hidden_states=args["txt"],
+ temb=args["vec"],
+ image_rotary_emb=args["pe"],
+ transformer_options=args.get("transformer_options"),
+ )
+ return out
+
+ out = blocks_replace[("double_block", i)]({"img": img,
+ "txt": txt,
+ "vec": vec,
+ "pe": image_rotary_emb,
+ "transformer_options": transformer_options},
+ {"original_block": block_wrap})
+ txt = out["txt"]
+ img = out["img"]
+ else:
+ img, txt = block(
+ hidden_states=img,
+ encoder_hidden_states=txt,
+ temb=vec,
+ image_rotary_emb=image_rotary_emb,
+ transformer_options=transformer_options,
+ )
+
+ tt, th, tw = component_sizes[0]
+ target_tokens = tt * th * tw
+ img = img[:, :target_tokens, :]
+ img = self.proj_out(self.norm_out(img))
+ img = self.unpatchify(img, tt, th, tw)
+ return img[:, :, :ot, :oh, :ow]
diff --git a/ComfyUI/comfy/ldm/kandinsky5/__pycache__/model.cpython-312.pyc b/ComfyUI/comfy/ldm/kandinsky5/__pycache__/model.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..b4a2c16800c62ef0f21639e0b2e5412ee802257e
Binary files /dev/null and b/ComfyUI/comfy/ldm/kandinsky5/__pycache__/model.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/kandinsky5/model.py b/ComfyUI/comfy/ldm/kandinsky5/model.py
new file mode 100644
index 0000000000000000000000000000000000000000..1509de2f83d7c672f32145faa6fb583cc0def989
--- /dev/null
+++ b/ComfyUI/comfy/ldm/kandinsky5/model.py
@@ -0,0 +1,413 @@
+import torch
+from torch import nn
+import math
+
+import comfy.ldm.common_dit
+from comfy.ldm.modules.attention import optimized_attention
+from comfy.ldm.flux.math import apply_rope1
+from comfy.ldm.flux.layers import EmbedND
+
+def attention(q, k, v, heads, transformer_options={}):
+ return optimized_attention(
+ q.transpose(1, 2),
+ k.transpose(1, 2),
+ v.transpose(1, 2),
+ heads=heads,
+ skip_reshape=True,
+ transformer_options=transformer_options
+ )
+
+def apply_scale_shift_norm(norm, x, scale, shift):
+ return torch.addcmul(shift, norm(x), scale + 1.0)
+
+def apply_gate_sum(x, out, gate):
+ return torch.addcmul(x, gate, out)
+
+def get_shift_scale_gate(params):
+ shift, scale, gate = torch.chunk(params, 3, dim=-1)
+ return tuple(x.unsqueeze(1) for x in (shift, scale, gate))
+
+def get_freqs(dim, max_period=10000.0):
+ return torch.exp(-math.log(max_period) * torch.arange(start=0, end=dim, dtype=torch.float32) / dim)
+
+
+class TimeEmbeddings(nn.Module):
+ def __init__(self, model_dim, time_dim, max_period=10000.0, operation_settings=None):
+ super().__init__()
+ assert model_dim % 2 == 0
+ self.model_dim = model_dim
+ self.max_period = max_period
+ self.register_buffer("freqs", get_freqs(model_dim // 2, max_period), persistent=False)
+ operations = operation_settings.get("operations")
+ self.in_layer = operations.Linear(model_dim, time_dim, bias=True, device=operation_settings.get("device"), dtype=operation_settings.get("dtype"))
+ self.activation = nn.SiLU()
+ self.out_layer = operations.Linear(time_dim, time_dim, bias=True, device=operation_settings.get("device"), dtype=operation_settings.get("dtype"))
+
+ def forward(self, timestep, dtype):
+ args = torch.outer(timestep, self.freqs.to(device=timestep.device))
+ time_embed = torch.cat([torch.cos(args), torch.sin(args)], dim=-1).to(dtype)
+ time_embed = self.out_layer(self.activation(self.in_layer(time_embed)))
+ return time_embed
+
+
+class TextEmbeddings(nn.Module):
+ def __init__(self, text_dim, model_dim, operation_settings=None):
+ super().__init__()
+ operations = operation_settings.get("operations")
+ self.in_layer = operations.Linear(text_dim, model_dim, bias=True, device=operation_settings.get("device"), dtype=operation_settings.get("dtype"))
+ self.norm = operations.LayerNorm(model_dim, elementwise_affine=True, device=operation_settings.get("device"), dtype=operation_settings.get("dtype"))
+
+ def forward(self, text_embed):
+ text_embed = self.in_layer(text_embed)
+ return self.norm(text_embed).type_as(text_embed)
+
+
+class VisualEmbeddings(nn.Module):
+ def __init__(self, visual_dim, model_dim, patch_size, operation_settings=None):
+ super().__init__()
+ self.patch_size = patch_size
+ operations = operation_settings.get("operations")
+ self.in_layer = operations.Linear(visual_dim, model_dim, device=operation_settings.get("device"), dtype=operation_settings.get("dtype"))
+
+ def forward(self, x):
+ x = x.movedim(1, -1) # B C T H W -> B T H W C
+ B, T, H, W, dim = x.shape
+ pt, ph, pw = self.patch_size
+
+ x = x.view(
+ B,
+ T // pt, pt,
+ H // ph, ph,
+ W // pw, pw,
+ dim,
+ ).permute(0, 1, 3, 5, 2, 4, 6, 7).flatten(4, 7)
+
+ return self.in_layer(x)
+
+
+class Modulation(nn.Module):
+ def __init__(self, time_dim, model_dim, num_params, operation_settings=None):
+ super().__init__()
+ self.activation = nn.SiLU()
+ self.out_layer = operation_settings.get("operations").Linear(time_dim, num_params * model_dim, device=operation_settings.get("device"), dtype=operation_settings.get("dtype"))
+
+ def forward(self, x):
+ return self.out_layer(self.activation(x))
+
+
+class SelfAttention(nn.Module):
+ def __init__(self, num_channels, head_dim, operation_settings=None):
+ super().__init__()
+ assert num_channels % head_dim == 0
+ self.num_heads = num_channels // head_dim
+ self.head_dim = head_dim
+
+ operations = operation_settings.get("operations")
+ self.to_query = operations.Linear(num_channels, num_channels, bias=True, device=operation_settings.get("device"), dtype=operation_settings.get("dtype"))
+ self.to_key = operations.Linear(num_channels, num_channels, bias=True, device=operation_settings.get("device"), dtype=operation_settings.get("dtype"))
+ self.to_value = operations.Linear(num_channels, num_channels, bias=True, device=operation_settings.get("device"), dtype=operation_settings.get("dtype"))
+ self.query_norm = operations.RMSNorm(head_dim, device=operation_settings.get("device"), dtype=operation_settings.get("dtype"))
+ self.key_norm = operations.RMSNorm(head_dim, device=operation_settings.get("device"), dtype=operation_settings.get("dtype"))
+
+ self.out_layer = operations.Linear(num_channels, num_channels, bias=True, device=operation_settings.get("device"), dtype=operation_settings.get("dtype"))
+ self.num_chunks = 2
+
+ def _compute_qk(self, x, freqs, proj_fn, norm_fn):
+ result = proj_fn(x).view(*x.shape[:-1], self.num_heads, -1)
+ return apply_rope1(norm_fn(result), freqs)
+
+ def _forward(self, x, freqs, transformer_options={}):
+ q = self._compute_qk(x, freqs, self.to_query, self.query_norm)
+ k = self._compute_qk(x, freqs, self.to_key, self.key_norm)
+ v = self.to_value(x).view(*x.shape[:-1], self.num_heads, -1)
+ out = attention(q, k, v, self.num_heads, transformer_options=transformer_options)
+ return self.out_layer(out)
+
+ def _forward_chunked(self, x, freqs, transformer_options={}):
+ def process_chunks(proj_fn, norm_fn):
+ x_chunks = torch.chunk(x, self.num_chunks, dim=1)
+ freqs_chunks = torch.chunk(freqs, self.num_chunks, dim=1)
+ chunks = []
+ for x_chunk, freqs_chunk in zip(x_chunks, freqs_chunks):
+ chunks.append(self._compute_qk(x_chunk, freqs_chunk, proj_fn, norm_fn))
+ return torch.cat(chunks, dim=1)
+
+ q = process_chunks(self.to_query, self.query_norm)
+ k = process_chunks(self.to_key, self.key_norm)
+ v = self.to_value(x).view(*x.shape[:-1], self.num_heads, -1)
+ out = attention(q, k, v, self.num_heads, transformer_options=transformer_options)
+ return self.out_layer(out)
+
+ def forward(self, x, freqs, transformer_options={}):
+ if x.shape[1] > 8192:
+ return self._forward_chunked(x, freqs, transformer_options=transformer_options)
+ else:
+ return self._forward(x, freqs, transformer_options=transformer_options)
+
+
+class CrossAttention(SelfAttention):
+ def get_qkv(self, x, context):
+ q = self.to_query(x).view(*x.shape[:-1], self.num_heads, -1)
+ k = self.to_key(context).view(*context.shape[:-1], self.num_heads, -1)
+ v = self.to_value(context).view(*context.shape[:-1], self.num_heads, -1)
+ return q, k, v
+
+ def forward(self, x, context, transformer_options={}):
+ q, k, v = self.get_qkv(x, context)
+ out = attention(self.query_norm(q), self.key_norm(k), v, self.num_heads, transformer_options=transformer_options)
+ return self.out_layer(out)
+
+
+class FeedForward(nn.Module):
+ def __init__(self, dim, ff_dim, operation_settings=None):
+ super().__init__()
+ operations = operation_settings.get("operations")
+ self.in_layer = operations.Linear(dim, ff_dim, bias=False, device=operation_settings.get("device"), dtype=operation_settings.get("dtype"))
+ self.activation = nn.GELU()
+ self.out_layer = operations.Linear(ff_dim, dim, bias=False, device=operation_settings.get("device"), dtype=operation_settings.get("dtype"))
+ self.num_chunks = 4
+
+ def _forward(self, x):
+ return self.out_layer(self.activation(self.in_layer(x)))
+
+ def _forward_chunked(self, x):
+ chunks = torch.chunk(x, self.num_chunks, dim=1)
+ output_chunks = []
+ for chunk in chunks:
+ output_chunks.append(self._forward(chunk))
+ return torch.cat(output_chunks, dim=1)
+
+ def forward(self, x):
+ if x.shape[1] > 8192:
+ return self._forward_chunked(x)
+ else:
+ return self._forward(x)
+
+
+class OutLayer(nn.Module):
+ def __init__(self, model_dim, time_dim, visual_dim, patch_size, operation_settings=None):
+ super().__init__()
+ self.patch_size = patch_size
+ self.modulation = Modulation(time_dim, model_dim, 2, operation_settings=operation_settings)
+ operations = operation_settings.get("operations")
+ self.norm = operations.LayerNorm(model_dim, elementwise_affine=False, device=operation_settings.get("device"), dtype=operation_settings.get("dtype"))
+ self.out_layer = operations.Linear(model_dim, math.prod(patch_size) * visual_dim, bias=True, device=operation_settings.get("device"), dtype=operation_settings.get("dtype"))
+
+ def forward(self, visual_embed, time_embed):
+ B, T, H, W, _ = visual_embed.shape
+ shift, scale = torch.chunk(self.modulation(time_embed), 2, dim=-1)
+ scale = scale[:, None, None, None, :]
+ shift = shift[:, None, None, None, :]
+ visual_embed = apply_scale_shift_norm(self.norm, visual_embed, scale, shift)
+ x = self.out_layer(visual_embed)
+
+ out_dim = x.shape[-1] // (self.patch_size[0] * self.patch_size[1] * self.patch_size[2])
+ x = x.view(
+ B, T, H, W,
+ out_dim,
+ self.patch_size[0], self.patch_size[1], self.patch_size[2]
+ )
+ return x.permute(0, 4, 1, 5, 2, 6, 3, 7).flatten(2, 3).flatten(3, 4).flatten(4, 5)
+
+
+class TransformerEncoderBlock(nn.Module):
+ def __init__(self, model_dim, time_dim, ff_dim, head_dim, operation_settings=None):
+ super().__init__()
+ self.text_modulation = Modulation(time_dim, model_dim, 6, operation_settings=operation_settings)
+ operations = operation_settings.get("operations")
+
+ self.self_attention_norm = operations.LayerNorm(model_dim, elementwise_affine=False, device=operation_settings.get("device"), dtype=operation_settings.get("dtype"))
+ self.self_attention = SelfAttention(model_dim, head_dim, operation_settings=operation_settings)
+
+ self.feed_forward_norm = operations.LayerNorm(model_dim, elementwise_affine=False, device=operation_settings.get("device"), dtype=operation_settings.get("dtype"))
+ self.feed_forward = FeedForward(model_dim, ff_dim, operation_settings=operation_settings)
+
+ def forward(self, x, time_embed, freqs, transformer_options={}):
+ self_attn_params, ff_params = torch.chunk(self.text_modulation(time_embed), 2, dim=-1)
+ shift, scale, gate = get_shift_scale_gate(self_attn_params)
+ out = apply_scale_shift_norm(self.self_attention_norm, x, scale, shift)
+ out = self.self_attention(out, freqs, transformer_options=transformer_options)
+ x = apply_gate_sum(x, out, gate)
+
+ shift, scale, gate = get_shift_scale_gate(ff_params)
+ out = apply_scale_shift_norm(self.feed_forward_norm, x, scale, shift)
+ out = self.feed_forward(out)
+ x = apply_gate_sum(x, out, gate)
+ return x
+
+
+class TransformerDecoderBlock(nn.Module):
+ def __init__(self, model_dim, time_dim, ff_dim, head_dim, operation_settings=None):
+ super().__init__()
+ self.visual_modulation = Modulation(time_dim, model_dim, 9, operation_settings=operation_settings)
+
+ operations = operation_settings.get("operations")
+ self.self_attention_norm = operations.LayerNorm(model_dim, elementwise_affine=False, device=operation_settings.get("device"), dtype=operation_settings.get("dtype"))
+ self.self_attention = SelfAttention(model_dim, head_dim, operation_settings=operation_settings)
+
+ self.cross_attention_norm = operations.LayerNorm(model_dim, elementwise_affine=False, device=operation_settings.get("device"), dtype=operation_settings.get("dtype"))
+ self.cross_attention = CrossAttention(model_dim, head_dim, operation_settings=operation_settings)
+
+ self.feed_forward_norm = operations.LayerNorm(model_dim, elementwise_affine=False, device=operation_settings.get("device"), dtype=operation_settings.get("dtype"))
+ self.feed_forward = FeedForward(model_dim, ff_dim, operation_settings=operation_settings)
+
+ def forward(self, visual_embed, text_embed, time_embed, freqs, transformer_options={}):
+ self_attn_params, cross_attn_params, ff_params = torch.chunk(self.visual_modulation(time_embed), 3, dim=-1)
+ # self attention
+ shift, scale, gate = get_shift_scale_gate(self_attn_params)
+ visual_out = apply_scale_shift_norm(self.self_attention_norm, visual_embed, scale, shift)
+ visual_out = self.self_attention(visual_out, freqs, transformer_options=transformer_options)
+ visual_embed = apply_gate_sum(visual_embed, visual_out, gate)
+ # cross attention
+ shift, scale, gate = get_shift_scale_gate(cross_attn_params)
+ visual_out = apply_scale_shift_norm(self.cross_attention_norm, visual_embed, scale, shift)
+ visual_out = self.cross_attention(visual_out, text_embed, transformer_options=transformer_options)
+ visual_embed = apply_gate_sum(visual_embed, visual_out, gate)
+ # feed forward
+ shift, scale, gate = get_shift_scale_gate(ff_params)
+ visual_out = apply_scale_shift_norm(self.feed_forward_norm, visual_embed, scale, shift)
+ visual_out = self.feed_forward(visual_out)
+ visual_embed = apply_gate_sum(visual_embed, visual_out, gate)
+ return visual_embed
+
+
+class Kandinsky5(nn.Module):
+ def __init__(
+ self,
+ in_visual_dim=16, out_visual_dim=16, in_text_dim=3584, in_text_dim2=768, time_dim=512,
+ model_dim=1792, ff_dim=7168, visual_embed_dim=132, patch_size=(1, 2, 2), num_text_blocks=2, num_visual_blocks=32,
+ axes_dims=(16, 24, 24), rope_scale_factor=(1.0, 2.0, 2.0),
+ dtype=None, device=None, operations=None, **kwargs
+ ):
+ super().__init__()
+ head_dim = sum(axes_dims)
+ self.rope_scale_factor = rope_scale_factor
+ self.in_visual_dim = in_visual_dim
+ self.model_dim = model_dim
+ self.patch_size = patch_size
+ self.visual_embed_dim = visual_embed_dim
+ self.dtype = dtype
+ self.device = device
+ operation_settings = {"operations": operations, "device": device, "dtype": dtype}
+
+ self.time_embeddings = TimeEmbeddings(model_dim, time_dim, operation_settings=operation_settings)
+ self.text_embeddings = TextEmbeddings(in_text_dim, model_dim, operation_settings=operation_settings)
+ self.pooled_text_embeddings = TextEmbeddings(in_text_dim2, time_dim, operation_settings=operation_settings)
+ self.visual_embeddings = VisualEmbeddings(visual_embed_dim, model_dim, patch_size, operation_settings=operation_settings)
+
+ self.text_transformer_blocks = nn.ModuleList(
+ [TransformerEncoderBlock(model_dim, time_dim, ff_dim, head_dim, operation_settings=operation_settings) for _ in range(num_text_blocks)]
+ )
+
+ self.visual_transformer_blocks = nn.ModuleList(
+ [TransformerDecoderBlock(model_dim, time_dim, ff_dim, head_dim, operation_settings=operation_settings) for _ in range(num_visual_blocks)]
+ )
+
+ self.out_layer = OutLayer(model_dim, time_dim, out_visual_dim, patch_size, operation_settings=operation_settings)
+
+ self.rope_embedder_3d = EmbedND(dim=head_dim, theta=10000.0, axes_dim=axes_dims)
+ self.rope_embedder_1d = EmbedND(dim=head_dim, theta=10000.0, axes_dim=[head_dim])
+
+ def rope_encode_1d(self, seq_len, seq_start=0, steps=None, device=None, dtype=None, transformer_options={}):
+ steps = seq_len if steps is None else steps
+ seq_ids = torch.linspace(seq_start, seq_start + (seq_len - 1), steps=steps, device=device, dtype=dtype)
+ seq_ids = seq_ids.reshape(-1, 1).unsqueeze(0) # Shape: (1, steps, 1)
+ freqs = self.rope_embedder_1d(seq_ids).movedim(1, 2)
+ return freqs
+
+ def rope_encode_3d(self, t, h, w, t_start=0, steps_t=None, steps_h=None, steps_w=None, device=None, dtype=None, transformer_options={}):
+
+ patch_size = self.patch_size
+ t_len = ((t + (patch_size[0] // 2)) // patch_size[0])
+ h_len = ((h + (patch_size[1] // 2)) // patch_size[1])
+ w_len = ((w + (patch_size[2] // 2)) // patch_size[2])
+
+ if steps_t is None:
+ steps_t = t_len
+ if steps_h is None:
+ steps_h = h_len
+ if steps_w is None:
+ steps_w = w_len
+
+ h_start = 0
+ w_start = 0
+ rope_options = transformer_options.get("rope_options", None)
+ if rope_options is not None:
+ t_len = (t_len - 1.0) * rope_options.get("scale_t", 1.0) + 1.0
+ h_len = (h_len - 1.0) * rope_options.get("scale_y", 1.0) + 1.0
+ w_len = (w_len - 1.0) * rope_options.get("scale_x", 1.0) + 1.0
+
+ t_start += rope_options.get("shift_t", 0.0)
+ h_start += rope_options.get("shift_y", 0.0)
+ w_start += rope_options.get("shift_x", 0.0)
+ else:
+ rope_scale_factor = self.rope_scale_factor
+ if self.model_dim == 4096: # pro video model uses different rope scaling at higher resolutions
+ if h * w >= 14080:
+ rope_scale_factor = (1.0, 3.16, 3.16)
+
+ t_len = (t_len - 1.0) / rope_scale_factor[0] + 1.0
+ h_len = (h_len - 1.0) / rope_scale_factor[1] + 1.0
+ w_len = (w_len - 1.0) / rope_scale_factor[2] + 1.0
+
+ img_ids = torch.zeros((steps_t, steps_h, steps_w, 3), device=device, dtype=dtype)
+ img_ids[:, :, :, 0] = img_ids[:, :, :, 0] + torch.linspace(t_start, t_start + (t_len - 1), steps=steps_t, device=device, dtype=dtype).reshape(-1, 1, 1)
+ img_ids[:, :, :, 1] = img_ids[:, :, :, 1] + torch.linspace(h_start, h_start + (h_len - 1), steps=steps_h, device=device, dtype=dtype).reshape(1, -1, 1)
+ img_ids[:, :, :, 2] = img_ids[:, :, :, 2] + torch.linspace(w_start, w_start + (w_len - 1), steps=steps_w, device=device, dtype=dtype).reshape(1, 1, -1)
+ img_ids = img_ids.reshape(1, -1, img_ids.shape[-1])
+
+ freqs = self.rope_embedder_3d(img_ids).movedim(1, 2)
+ return freqs
+
+ def forward_orig(self, x, timestep, context, y, freqs, freqs_text, transformer_options={}, **kwargs):
+ patches_replace = transformer_options.get("patches_replace", {})
+ context = self.text_embeddings(context)
+ time_embed = self.time_embeddings(timestep, x.dtype) + self.pooled_text_embeddings(y)
+
+ for block in self.text_transformer_blocks:
+ context = block(context, time_embed, freqs_text, transformer_options=transformer_options)
+
+ visual_embed = self.visual_embeddings(x)
+ visual_shape = visual_embed.shape[:-1]
+ visual_embed = visual_embed.flatten(1, -2)
+
+ blocks_replace = patches_replace.get("dit", {})
+ transformer_options["total_blocks"] = len(self.visual_transformer_blocks)
+ transformer_options["block_type"] = "double"
+ for i, block in enumerate(self.visual_transformer_blocks):
+ transformer_options["block_index"] = i
+ if ("double_block", i) in blocks_replace:
+ def block_wrap(args):
+ return block(x=args["x"], context=args["context"], time_embed=args["time_embed"], freqs=args["freqs"], transformer_options=args.get("transformer_options"))
+ visual_embed = blocks_replace[("double_block", i)]({"x": visual_embed, "context": context, "time_embed": time_embed, "freqs": freqs, "transformer_options": transformer_options}, {"original_block": block_wrap})["x"]
+ else:
+ visual_embed = block(visual_embed, context, time_embed, freqs=freqs, transformer_options=transformer_options)
+
+ visual_embed = visual_embed.reshape(*visual_shape, -1)
+ return self.out_layer(visual_embed, time_embed)
+
+ def _forward(self, x, timestep, context, y, time_dim_replace=None, transformer_options={}, **kwargs):
+ original_dims = x.ndim
+ if original_dims == 4:
+ x = x.unsqueeze(2)
+ bs, c, t_len, h, w = x.shape
+ x = comfy.ldm.common_dit.pad_to_patch_size(x, self.patch_size)
+
+ if time_dim_replace is not None:
+ time_dim_replace = comfy.ldm.common_dit.pad_to_patch_size(time_dim_replace, self.patch_size)
+ x[:, :time_dim_replace.shape[1], :time_dim_replace.shape[2]] = time_dim_replace
+
+ freqs = self.rope_encode_3d(t_len, h, w, device=x.device, dtype=x.dtype, transformer_options=transformer_options)
+ freqs_text = self.rope_encode_1d(context.shape[1], device=x.device, dtype=x.dtype, transformer_options=transformer_options)
+
+ out = self.forward_orig(x, timestep, context, y, freqs, freqs_text, transformer_options=transformer_options, **kwargs)
+ if original_dims == 4:
+ out = out.squeeze(2)
+ return out
+
+ def forward(self, x, timestep, context, y, time_dim_replace=None, transformer_options={}, **kwargs):
+ return comfy.patcher_extension.WrapperExecutor.new_class_executor(
+ self._forward,
+ self,
+ comfy.patcher_extension.get_all_wrappers(comfy.patcher_extension.WrappersMP.DIFFUSION_MODEL, transformer_options)
+ ).execute(x, timestep, context, y, time_dim_replace=time_dim_replace, transformer_options=transformer_options, **kwargs)
diff --git a/ComfyUI/comfy/ldm/krea2/__pycache__/model.cpython-312.pyc b/ComfyUI/comfy/ldm/krea2/__pycache__/model.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..154661f2f2e0d02f93840ae0c026809e59c3468f
Binary files /dev/null and b/ComfyUI/comfy/ldm/krea2/__pycache__/model.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/krea2/model.py b/ComfyUI/comfy/ldm/krea2/model.py
new file mode 100644
index 0000000000000000000000000000000000000000..8001812d77d2750dbadf25fbec16710ea1ba3e74
--- /dev/null
+++ b/ComfyUI/comfy/ldm/krea2/model.py
@@ -0,0 +1,391 @@
+"""Krea 2 (K2) — single-stream MMDiT.
+
+Text tokens produced by a Qwen3-VL-4B 12-layer ``txtfusion`` adapter and patchified image tokens are
+concatenated into one sequence and run through ``layers`` shared transformer blocks with
+AdaLN-single modulation, GQA + per-head QK-norm + sigmoid-gated attention, SwiGLU MLP, and 3-axis RoPE.
+"""
+
+from typing import Optional
+
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+from einops import rearrange
+
+import comfy.model_management
+import comfy.patcher_extension
+import comfy.ldm.common_dit
+import comfy.utils
+from comfy.ldm.flux.layers import EmbedND, timestep_embedding
+from comfy.ldm.flux.math import apply_rope
+from comfy.ldm.modules.attention import optimized_attention_masked
+
+
+class RMSNorm(nn.Module):
+ """RMSNorm with the reference ``(1 + scale)`` weight convention (scale stored zero-centered)."""
+
+ def __init__(self, features: int, eps: float = 1e-5, device=None, dtype=None, operations=None):
+ super().__init__()
+ self.eps = eps
+ self.scale = nn.Parameter(torch.empty(features, device=device, dtype=dtype))
+
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
+ dtype = x.dtype
+ weight = comfy.model_management.cast_to(self.scale, dtype=torch.float32, device=x.device) + 1.0
+ return F.rms_norm(x.float(), (x.shape[-1],), weight=weight, eps=self.eps).to(dtype)
+
+
+class QKNorm(nn.Module):
+ def __init__(self, dim: int, device=None, dtype=None, operations=None):
+ super().__init__()
+ self.qnorm = RMSNorm(dim, device=device, dtype=dtype, operations=operations)
+ self.knorm = RMSNorm(dim, device=device, dtype=dtype, operations=operations)
+
+ def forward(self, q, k):
+ return self.qnorm(q), self.knorm(k)
+
+
+class SwiGLU(nn.Module):
+ def __init__(self, features: int, multiplier: int, bias: bool = False, multiple: int = 128,
+ device=None, dtype=None, operations=None):
+ super().__init__()
+ mlpdim = int(2 * features / 3) * multiplier
+ mlpdim = multiple * ((mlpdim + multiple - 1) // multiple)
+ self.gate = operations.Linear(features, mlpdim, bias=bias, device=device, dtype=dtype)
+ self.up = operations.Linear(features, mlpdim, bias=bias, device=device, dtype=dtype)
+ self.down = operations.Linear(mlpdim, features, bias=bias, device=device, dtype=dtype)
+
+ def forward(self, x):
+ return self.down(F.silu(self.gate(x)).mul_(self.up(x)))
+
+
+class Attention(nn.Module):
+ def __init__(self, dim: int, heads: int, kvheads: Optional[int] = None, bias: bool = False,
+ device=None, dtype=None, operations=None):
+ super().__init__()
+ self.heads = heads
+ self.kvheads = kvheads if kvheads is not None else heads
+ self.headdim = dim // self.heads
+ self.wq = operations.Linear(dim, self.headdim * self.heads, bias=bias, device=device, dtype=dtype)
+ self.wk = operations.Linear(dim, self.headdim * self.kvheads, bias=bias, device=device, dtype=dtype)
+ self.wv = operations.Linear(dim, self.headdim * self.kvheads, bias=bias, device=device, dtype=dtype)
+ self.gate = operations.Linear(dim, dim, bias=bias, device=device, dtype=dtype)
+ self.qknorm = QKNorm(self.headdim, device=device, dtype=dtype, operations=operations)
+ self.wo = operations.Linear(dim, dim, bias=bias, device=device, dtype=dtype)
+
+ def forward(self, x, freqs=None, mask=None, transformer_options={}):
+ transformer_patches = transformer_options.get("patches", {})
+ extra_options = transformer_options.copy()
+ q, k, v, gate = self.wq(x), self.wk(x), self.wv(x), self.gate(x)
+ q = rearrange(q, "B L (H D) -> B H L D", H=self.heads)
+ k = rearrange(k, "B L (H D) -> B H L D", H=self.kvheads)
+ v = rearrange(v, "B L (H D) -> B H L D", H=self.kvheads)
+ q, k = self.qknorm(q, k)
+
+ if "block_index" in transformer_options and "attn1_patch" in transformer_patches:
+ for p in transformer_patches["attn1_patch"]:
+ out = p(q, k, v, pe=freqs, attn_mask=mask, extra_options=extra_options)
+ q, k, v = out.get("q", q), out.get("k", k), out.get("v", v)
+ freqs, mask = out.get("pe", freqs), out.get("attn_mask", mask)
+
+ if freqs is not None:
+ q, k = apply_rope(q, k, freqs)
+ if self.kvheads != self.heads:
+ rep = self.heads // self.kvheads
+ k = k.repeat_interleave(rep, dim=1)
+ v = v.repeat_interleave(rep, dim=1)
+ out = optimized_attention_masked(q, k, v, self.heads, mask=mask, skip_reshape=True,
+ transformer_options=transformer_options)
+
+ if "block_index" in transformer_options and "attn1_output_patch" in transformer_patches:
+ for p in transformer_patches["attn1_output_patch"]:
+ out = p(out, extra_options)
+
+ return self.wo(out * F.sigmoid(gate))
+
+
+class SimpleModulation(nn.Module):
+ def __init__(self, dim: int, device=None, dtype=None, operations=None):
+ super().__init__()
+ self.lin = nn.Parameter(torch.empty(2, dim, device=device, dtype=dtype))
+
+ def forward(self, vec):
+ out = vec + comfy.model_management.cast_to(self.lin, dtype=vec.dtype, device=vec.device).unsqueeze(0)
+ scale, shift = out.chunk(2, dim=1)
+ return scale, shift
+
+
+class DoubleSharedModulation(nn.Module):
+ def __init__(self, dim: int, device=None, dtype=None, operations=None):
+ super().__init__()
+ self.lin = nn.Parameter(torch.empty(6 * dim, device=device, dtype=dtype))
+
+ def forward(self, vec):
+ out = vec + comfy.model_management.cast_to(self.lin, dtype=vec.dtype, device=vec.device)
+ return out.chunk(6, dim=-1)
+
+
+class TextFusionBlock(nn.Module):
+ def __init__(self, features, heads, multiplier, bias=False, kvheads=None, device=None, dtype=None, operations=None):
+ super().__init__()
+ self.prenorm = RMSNorm(features, device=device, dtype=dtype, operations=operations)
+ self.postnorm = RMSNorm(features, device=device, dtype=dtype, operations=operations)
+ self.attn = Attention(features, heads, kvheads=kvheads, bias=bias, device=device, dtype=dtype, operations=operations)
+ self.mlp = SwiGLU(features, multiplier, bias, device=device, dtype=dtype, operations=operations)
+
+ def forward(self, x, mask=None, transformer_options={}):
+ x = x + self.attn(self.prenorm(x), mask=mask, transformer_options=transformer_options)
+ x = x + self.mlp(self.postnorm(x))
+ return x
+
+
+class TextFusionTransformer(nn.Module):
+ def __init__(self, num_txt_layers, txt_dim, heads, multiplier, bias=False, kvheads=None, device=None, dtype=None, operations=None):
+ super().__init__()
+ self.layerwise_blocks = nn.ModuleList([
+ TextFusionBlock(txt_dim, heads, multiplier, bias, kvheads, device=device, dtype=dtype, operations=operations)
+ for _ in range(2)
+ ])
+ self.projector = operations.Linear(num_txt_layers, 1, bias=False, device=device, dtype=dtype)
+ self.refiner_blocks = nn.ModuleList([
+ TextFusionBlock(txt_dim, heads, multiplier, bias, kvheads, device=device, dtype=dtype, operations=operations)
+ for _ in range(2)
+ ])
+
+ def forward(self, x, mask=None, transformer_options={}):
+ b, l, n, d = x.shape
+ x = x.reshape(b * l, n, d)
+ for block in self.layerwise_blocks:
+ x = block(x.contiguous(), mask=None, transformer_options=transformer_options)
+ x = rearrange(x, "(b l) n d -> b l d n", b=b, l=l)
+ x = self.projector(x).squeeze(-1)
+ for block in self.refiner_blocks:
+ x = block(x, mask=mask, transformer_options=transformer_options)
+ return x
+
+
+class SingleStreamBlock(nn.Module):
+ def __init__(self, features, heads, multiplier, bias=False, kvheads=None, device=None, dtype=None, operations=None):
+ super().__init__()
+ self.mod = DoubleSharedModulation(features, device=device, dtype=dtype, operations=operations)
+ self.prenorm = RMSNorm(features, device=device, dtype=dtype, operations=operations)
+ self.postnorm = RMSNorm(features, device=device, dtype=dtype, operations=operations)
+ self.attn = Attention(features, heads, kvheads=kvheads, bias=bias, device=device, dtype=dtype, operations=operations)
+ self.mlp = SwiGLU(features, multiplier, bias, device=device, dtype=dtype, operations=operations)
+
+ def forward(self, x, vec, freqs, mask=None, timestep_zero_index=None, transformer_options={}):
+ prescale, preshift, pregate, postscale, postshift, postgate = self.mod(vec)
+ if timestep_zero_index is not None:
+ bs = x.shape[0]
+ ref_prescale = prescale[bs:]
+ ref_preshift = preshift[bs:]
+ ref_pregate = pregate[bs:]
+ ref_postscale = postscale[bs:]
+ ref_postshift = postshift[bs:]
+ ref_postgate = postgate[bs:]
+ prescale = prescale[:bs]
+ preshift = preshift[:bs]
+ pregate = pregate[:bs]
+ postscale = postscale[:bs]
+ postshift = postshift[:bs]
+ postgate = postgate[:bs]
+
+ pre = self.prenorm(x)
+ pre[:, :timestep_zero_index].mul_(1 + prescale).add_(preshift)
+ pre[:, timestep_zero_index:].mul_(1 + ref_prescale).add_(ref_preshift)
+ attn = self.attn(pre, freqs, mask, transformer_options=transformer_options)
+ del pre
+ attn[:, :timestep_zero_index].mul_(pregate)
+ attn[:, timestep_zero_index:].mul_(ref_pregate)
+ x = x + attn
+ del attn
+
+ post = self.postnorm(x)
+ post[:, :timestep_zero_index].mul_(1 + postscale).add_(postshift)
+ post[:, timestep_zero_index:].mul_(1 + ref_postscale).add_(ref_postshift)
+ mlp = self.mlp(post)
+ del post
+ mlp[:, :timestep_zero_index].mul_(postgate)
+ mlp[:, timestep_zero_index:].mul_(ref_postgate)
+ x = x + mlp
+ del mlp
+ return x
+
+ x = x + pregate * self.attn((1 + prescale) * self.prenorm(x) + preshift, freqs, mask, transformer_options=transformer_options)
+ x = x + postgate * self.mlp((1 + postscale) * self.postnorm(x) + postshift)
+ return x
+
+
+class LastLayer(nn.Module):
+ def __init__(self, features, patch, channels, device=None, dtype=None, operations=None):
+ super().__init__()
+ self.norm = RMSNorm(features, device=device, dtype=dtype, operations=operations)
+ self.linear = operations.Linear(features, patch * patch * channels, bias=True, device=device, dtype=dtype)
+ self.modulation = SimpleModulation(features, device=device, dtype=dtype, operations=operations)
+
+ def forward(self, x, tvec):
+ scale, shift = self.modulation(tvec)
+ x = (1 + scale) * self.norm(x) + shift
+ return self.linear(x)
+
+
+class SingleStreamDiT(nn.Module):
+ def __init__(self, features=6144, tdim=256, txtdim=2560, heads=48, kvheads=12, multiplier=4,
+ layers=28, patch=2, channels=16, bias=False, theta=1e3, txtlayers=12,
+ txtheads=20, txtkvheads=20, default_ref_method=None, image_model=None,
+ device=None, dtype=None, operations=None, **kwargs):
+ super().__init__()
+ self.dtype = dtype
+ self.patch = patch
+ self.channels = channels
+ self.tdim = tdim
+ self.heads = heads
+ self.txtdim = txtdim
+ self.txtlayers = txtlayers
+ self.default_ref_method = default_ref_method
+
+ headdim = features // heads
+ axes = [headdim - 12 * (headdim // 16), 6 * (headdim // 16), 6 * (headdim // 16)]
+ assert sum(axes) == headdim, f"axes {axes} sum != headdim {headdim}"
+ self.pe_embedder = EmbedND(dim=headdim, theta=int(theta), axes_dim=axes)
+
+ self.first = operations.Linear(channels * patch ** 2, features, bias=True, device=device, dtype=dtype)
+ self.blocks = nn.ModuleList([
+ SingleStreamBlock(features, heads, multiplier, bias, kvheads, device=device, dtype=dtype, operations=operations)
+ for _ in range(layers)
+ ])
+ self.tmlp = nn.Sequential(
+ operations.Linear(tdim, features, device=device, dtype=dtype),
+ nn.GELU(approximate="tanh"),
+ operations.Linear(features, features, device=device, dtype=dtype),
+ )
+ self.txtfusion = TextFusionTransformer(txtlayers, txtdim, txtheads, multiplier, bias, txtkvheads,
+ device=device, dtype=dtype, operations=operations)
+ self.txtmlp = nn.Sequential(
+ RMSNorm(txtdim, device=device, dtype=dtype, operations=operations),
+ operations.Linear(txtdim, features, device=device, dtype=dtype),
+ nn.GELU(approximate="tanh"),
+ operations.Linear(features, features, device=device, dtype=dtype),
+ )
+ self.last = LastLayer(features, patch, channels, device=device, dtype=dtype, operations=operations)
+ self.tproj = nn.Sequential(
+ nn.GELU(approximate="tanh"),
+ operations.Linear(features, features * 6, device=device, dtype=dtype),
+ )
+
+ def forward(self, x, timesteps, context, attention_mask=None, ref_latents=None, transformer_options={}, **kwargs):
+ return comfy.patcher_extension.WrapperExecutor.new_class_executor(
+ self._forward,
+ self,
+ comfy.patcher_extension.get_all_wrappers(comfy.patcher_extension.WrappersMP.DIFFUSION_MODEL, transformer_options),
+ ).execute(x, timesteps, context, attention_mask, ref_latents, transformer_options, **kwargs)
+
+ def process_img(self, x, index=0):
+ patch = self.patch
+ x = comfy.ldm.common_dit.pad_to_patch_size(x, (patch, patch))
+ h, w = x.shape[-2] // patch, x.shape[-1] // patch
+ img = rearrange(x, "b c (h ph) (w pw) -> b (h w) (c ph pw)", ph=patch, pw=patch)
+
+ img_ids = torch.zeros(h, w, 3, device=x.device, dtype=torch.float32)
+ img_ids[..., 0] = index
+ img_ids[..., 1] = torch.arange(h, device=x.device, dtype=torch.float32)[:, None]
+ img_ids[..., 2] = torch.arange(w, device=x.device, dtype=torch.float32)[None, :]
+ return img, img_ids.reshape(1, h * w, 3).repeat(x.shape[0], 1, 1), h, w
+
+ def _forward(self, x, timesteps, context, attention_mask=None, ref_latents=None, transformer_options={}, **kwargs):
+ transformer_options = transformer_options.copy()
+ temporal = x.ndim == 5
+ if temporal:
+ b5, c5, t5, h5, w5 = x.shape
+ x = x.reshape(b5 * t5, c5, h5, w5)
+ bs, _, h_orig, w_orig = x.shape
+ patch = self.patch
+
+ # context arrives as (B, seq, txtlayers*txtdim); reshape to (B, txtlayers, seq, txtdim).
+ context = self._unpack_context(context)
+
+ img, imgpos, h_, w_ = self.process_img(x)
+ img_tokens = img.shape[1]
+ timestep_zero_index = None
+ ref_method = kwargs.get("ref_latents_method", self.default_ref_method)
+ if ref_method is not None and ref_latents is not None and len(ref_latents) > 0:
+ ref_tokens = []
+ ref_pos = []
+ ref_num_tokens = []
+ for index, ref in enumerate(ref_latents, 1):
+ if ref.ndim == 5:
+ rb, rc, rt, rh5, rw5 = ref.shape
+ ref = ref.reshape(rb * rt, rc, rh5, rw5)
+ ref = comfy.utils.repeat_to_batch_size(ref, bs)
+ kontext, kontext_ids, _, _ = self.process_img(ref, index=index)
+ ref_tokens.append(kontext)
+ ref_pos.append(kontext_ids)
+ ref_num_tokens.append(kontext.shape[1])
+ img = torch.cat([img] + ref_tokens, dim=1)
+ imgpos = torch.cat([imgpos] + ref_pos, dim=1)
+ del ref_tokens, ref_pos
+ if ref_method == "index_timestep_zero":
+ timestep_zero_index = img_tokens
+ transformer_options["reference_image_num_tokens"] = ref_num_tokens
+
+ img = self.first(img)
+
+ t = self.tmlp(timestep_embedding(timesteps, self.tdim).unsqueeze(1).to(img.dtype))
+ tvec = self.tproj(t)
+ if timestep_zero_index is not None:
+ t0 = self.tmlp(timestep_embedding(torch.zeros_like(timesteps), self.tdim).unsqueeze(1).to(img.dtype))
+ tvec = torch.cat((tvec, self.tproj(t0)), dim=0)
+
+ context = self.txtfusion(context, mask=None, transformer_options=transformer_options)
+ context = self.txtmlp(context)
+
+ txtlen = context.shape[1]
+ device = context.device
+ txtpos = torch.zeros(bs, txtlen, 3, device=device, dtype=torch.float32)
+
+ patches = transformer_options.get("patches", {})
+ if "post_input" in patches:
+ for p in patches["post_input"]:
+ out = p({"img": img, "txt": context, "img_ids": imgpos, "txt_ids": txtpos, "transformer_options": transformer_options})
+ img, context = out["img"], out["txt"]
+ imgpos, txtpos = out["img_ids"], out["txt_ids"]
+
+ combined = torch.cat((context, img), dim=1)
+ del context, img
+ if timestep_zero_index is not None:
+ timestep_zero_index += txtlen
+
+ # Position ids: text at 0, image at (0, h_idx, w_idx).
+ pos = torch.cat((txtpos, imgpos), dim=1)
+ del txtpos, imgpos
+
+ freqs = self.pe_embedder(pos)
+ del pos
+
+ transformer_options["total_blocks"] = len(self.blocks)
+ transformer_options["block_type"] = "single"
+ transformer_options["img_slice"] = [txtlen, combined.shape[1]]
+ for i, block in enumerate(self.blocks):
+ transformer_options["block_index"] = i
+ combined = block(combined, tvec, freqs, None, timestep_zero_index=timestep_zero_index, transformer_options=transformer_options)
+
+ final = self.last(combined, t)
+ del combined
+ out = final[:, txtlen:txtlen + img_tokens, :]
+ out = rearrange(out, "b (h w) (c ph pw) -> b c (h ph) (w pw)",
+ h=h_, w=w_, ph=patch, pw=patch, c=self.channels)
+ out = out[:, :, :h_orig, :w_orig] # crop padding back off
+ if temporal:
+ out = out.reshape(b5, t5, self.channels, h_orig, w_orig).movedim(1, 2)
+ return out
+
+ def _unpack_context(self, context):
+ # context: (B, seq, txtlayers*txtdim) -> (B, seq, txtlayers, txtdim).
+ b, seq, fused = context.shape
+ if fused != self.txtlayers * self.txtdim:
+ raise ValueError(
+ f"Krea2 expects conditioning with {self.txtlayers}x{self.txtdim}={self.txtlayers * self.txtdim} "
+ f"features (a {self.txtlayers}-layer Qwen3-VL stack) but got {fused}. "
+ f"Load the text encoder with CLIPLoader type 'krea2'."
+ )
+ return context.reshape(b, seq, self.txtlayers, self.txtdim)
diff --git a/ComfyUI/comfy/ldm/lens/__pycache__/model.cpython-312.pyc b/ComfyUI/comfy/ldm/lens/__pycache__/model.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..9a853278bbba810e2f59613ee38aede55d4a3695
Binary files /dev/null and b/ComfyUI/comfy/ldm/lens/__pycache__/model.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/lens/model.py b/ComfyUI/comfy/ldm/lens/model.py
new file mode 100644
index 0000000000000000000000000000000000000000..cd5015ddcaeeb5cdb6f40d0c1505cf36fcbdb9e0
--- /dev/null
+++ b/ComfyUI/comfy/ldm/lens/model.py
@@ -0,0 +1,510 @@
+"""Lens denoising transformer (DiT)"""
+
+from __future__ import annotations
+
+from typing import Any, Dict, Optional, Tuple
+
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+
+import comfy.ldm.flux.layers
+import comfy.patcher_extension
+from comfy.ldm.flux.layers import EmbedND
+from comfy.ldm.flux.math import apply_rope
+from comfy.ldm.modules.attention import optimized_attention
+
+
+def _lens_time_proj(t: torch.Tensor, dim: int = 256) -> torch.Tensor:
+ return comfy.ldm.flux.layers.timestep_embedding(t, dim)
+
+
+def _lens_position_ids(
+ frame: int, height: int, width: int, text_seq_len: int,
+ scale_rope: bool = True, device=None,
+) -> torch.Tensor:
+ """Lens axial (frame, h, w) position ids for joint image + text sequence.
+
+ With ``scale_rope=True`` h/w are centered around 0 (negative + positive
+ halves) and text starts at ``max(h//2, w//2)``. Result shape ``[seq, 3]``;
+ caller adds a batch dim for ``EmbedND``.
+ """
+ if scale_rope:
+ h_pos = torch.cat([torch.arange(-(height - height // 2), 0, device=device),
+ torch.arange(0, height // 2, device=device)])
+ w_pos = torch.cat([torch.arange(-(width - width // 2), 0, device=device),
+ torch.arange(0, width // 2, device=device)])
+ text_start = max(height // 2, width // 2)
+ else:
+ h_pos = torch.arange(height, device=device)
+ w_pos = torch.arange(width, device=device)
+ text_start = max(height, width)
+
+ f_pos = torch.arange(frame, device=device)
+ img_ids = torch.zeros(frame, height, width, 3, device=device)
+ img_ids[..., 0] = f_pos[:, None, None]
+ img_ids[..., 1] = h_pos[None, :, None]
+ img_ids[..., 2] = w_pos[None, None, :]
+ img_ids = img_ids.reshape(-1, 3)
+
+ # Text positions replicate across all 3 axes (matches original packing).
+ txt_pos = torch.arange(text_start, text_start + text_seq_len, device=device).float()
+ txt_ids = txt_pos[:, None].expand(text_seq_len, 3)
+
+ return torch.cat([img_ids, txt_ids], dim=0)
+
+
+class _TimestepEmbedder(nn.Module):
+ def __init__(self, in_channels: int, time_embed_dim: int, dtype=None, device=None, operations=None) -> None:
+ super().__init__()
+ self.linear_1 = operations.Linear(in_channels, time_embed_dim, dtype=dtype, device=device)
+ self.linear_2 = operations.Linear(time_embed_dim, time_embed_dim, dtype=dtype, device=device)
+
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
+ x = self.linear_1(x)
+ x = F.silu(x)
+ return self.linear_2(x)
+
+
+class LensTimestepProjEmbeddings(nn.Module):
+ def __init__(self, embedding_dim: int, dtype=None, device=None, operations=None) -> None:
+ super().__init__()
+ self.timestep_embedder = _TimestepEmbedder(256, embedding_dim, dtype=dtype, device=device, operations=operations)
+
+ def forward(self, timestep: torch.Tensor, hidden_states: torch.Tensor) -> torch.Tensor:
+ proj = _lens_time_proj(timestep, 256)
+ return self.timestep_embedder(proj.to(dtype=hidden_states.dtype))
+
+
+class GateMLP(nn.Module):
+ """SwiGLU MLP."""
+
+ def __init__(self, dim: int, hidden_dim: int, dtype=None, device=None, operations=None) -> None:
+ super().__init__()
+ self.w1 = operations.Linear(dim, hidden_dim, bias=False, dtype=dtype, device=device)
+ self.w2 = operations.Linear(hidden_dim, dim, bias=False, dtype=dtype, device=device)
+ self.w3 = operations.Linear(dim, hidden_dim, bias=False, dtype=dtype, device=device)
+
+ def forward(self, x):
+ return self.w2(F.silu(self.w1(x), inplace=True).mul_(self.w3(x)))
+
+
+class LensJointAttention(nn.Module):
+ """Joint image+text attention with fused QKV per stream."""
+
+ def __init__(
+ self,
+ query_dim: int,
+ added_kv_proj_dim: int,
+ dim_head: int = 64,
+ heads: int = 8,
+ out_dim: Optional[int] = None,
+ eps: float = 1e-5,
+ dtype=None,
+ device=None,
+ operations=None,
+ ) -> None:
+ super().__init__()
+ self.inner_dim = out_dim if out_dim is not None else dim_head * heads
+ self.heads = self.inner_dim // dim_head
+ self.dim_head = dim_head
+ self.out_dim = out_dim if out_dim is not None else query_dim
+
+ self.norm_q = operations.RMSNorm(dim_head, eps=eps, dtype=dtype, device=device)
+ self.norm_k = operations.RMSNorm(dim_head, eps=eps, dtype=dtype, device=device)
+ self.norm_added_q = operations.RMSNorm(dim_head, eps=eps, dtype=dtype, device=device)
+ self.norm_added_k = operations.RMSNorm(dim_head, eps=eps, dtype=dtype, device=device)
+
+ self.img_qkv = operations.Linear(query_dim, 3 * self.inner_dim, bias=True, dtype=dtype, device=device)
+ self.txt_qkv = operations.Linear(added_kv_proj_dim, 3 * self.inner_dim, bias=True, dtype=dtype, device=device)
+
+ # ModuleList([Linear, Identity]) for state-dict key compatibility.
+ self.to_out = nn.ModuleList([
+ operations.Linear(self.inner_dim, self.out_dim, bias=True, dtype=dtype, device=device),
+ nn.Identity(),
+ ])
+ self.to_add_out = operations.Linear(self.inner_dim, query_dim, bias=True, dtype=dtype, device=device)
+
+ def forward(
+ self,
+ hidden_states: torch.Tensor,
+ encoder_hidden_states: torch.Tensor,
+ freqs_cis: torch.Tensor,
+ attention_mask: Optional[torch.Tensor] = None,
+ transformer_options: Optional[Dict[str, Any]] = None,
+ ) -> Tuple[torch.Tensor, torch.Tensor]:
+ bsz, seq_img, _ = hidden_states.shape
+ seq_txt = encoder_hidden_states.shape[1]
+
+ # image stream
+ img_qkv = self.img_qkv(hidden_states).view(bsz, seq_img, 3, self.heads, self.dim_head)
+ img_q, img_k, img_v = img_qkv.unbind(dim=2)
+ img_q = self.norm_q(img_q)
+ img_k = self.norm_k(img_k)
+ del img_qkv
+
+ # text stream
+ txt_qkv = self.txt_qkv(encoder_hidden_states).view(bsz, seq_txt, 3, self.heads, self.dim_head)
+ txt_q, txt_k, txt_v = txt_qkv.unbind(dim=2)
+ txt_q = self.norm_added_q(txt_q)
+ txt_k = self.norm_added_k(txt_k)
+
+ # [B, S, H, D] → [B, H, S, D] for attention, dels to avoid VRAM peaks
+ q = torch.cat([img_q, txt_q], dim=1).transpose(1, 2)
+ del img_q, txt_q
+ k = torch.cat([img_k, txt_k], dim=1).transpose(1, 2)
+ del img_k, txt_k
+ v = torch.cat([img_v, txt_v], dim=1).transpose(1, 2)
+ del img_v, txt_v
+
+ q, k = apply_rope(q, k, freqs_cis)
+
+ if attention_mask is not None:
+ expected = (bsz, 1, 1, seq_img + seq_txt)
+ if attention_mask.shape != expected:
+ raise ValueError(
+ f"attention_mask must be {expected}, got {tuple(attention_mask.shape)}"
+ )
+ attention_mask = attention_mask.to(q.dtype)
+
+ out = optimized_attention(
+ q, k, v, self.heads, mask=attention_mask, skip_reshape=True,
+ transformer_options=transformer_options,
+ )
+
+ img_out = self.to_out[1](self.to_out[0](out[:, :seq_img, :]))
+ txt_out = self.to_add_out(out[:, seq_img:, :])
+ return img_out, txt_out
+
+
+class LensTransformerBlock(nn.Module):
+ def __init__(
+ self,
+ dim: int,
+ num_attention_heads: int,
+ attention_head_dim: int,
+ eps: float = 1e-6,
+ rms_norm: bool = True,
+ dtype=None,
+ device=None,
+ operations=None,
+ ) -> None:
+ super().__init__()
+
+ self.attn = LensJointAttention(
+ query_dim=dim,
+ added_kv_proj_dim=dim,
+ dim_head=attention_head_dim,
+ heads=num_attention_heads,
+ out_dim=dim,
+ eps=1e-5,
+ dtype=dtype,
+ device=device,
+ operations=operations,
+ )
+
+ if rms_norm:
+ NormCls = operations.RMSNorm
+ norm_kwargs = {}
+ else:
+ NormCls = operations.LayerNorm
+ norm_kwargs = {"elementwise_affine": False}
+
+ mlp_hidden = int(dim / 3 * 8)
+
+ # Sequential(SiLU, Linear) so state-dict lands at img_mod.1.{weight,bias}.
+ self.img_mod = nn.Sequential(
+ nn.SiLU(),
+ operations.Linear(dim, 6 * dim, bias=True, dtype=dtype, device=device),
+ )
+ self.img_norm1 = NormCls(dim, eps=eps, dtype=dtype, device=device, **norm_kwargs)
+ self.img_norm2 = NormCls(dim, eps=eps, dtype=dtype, device=device, **norm_kwargs)
+ self.img_mlp = GateMLP(dim, mlp_hidden, dtype=dtype, device=device, operations=operations)
+
+ self.txt_mod = nn.Sequential(
+ nn.SiLU(),
+ operations.Linear(dim, 6 * dim, bias=True, dtype=dtype, device=device),
+ )
+ self.txt_norm1 = NormCls(dim, eps=eps, dtype=dtype, device=device, **norm_kwargs)
+ self.txt_norm2 = NormCls(dim, eps=eps, dtype=dtype, device=device, **norm_kwargs)
+ self.txt_mlp = GateMLP(dim, mlp_hidden, dtype=dtype, device=device, operations=operations)
+
+ @staticmethod
+ def _modulate(x: torch.Tensor, mod_params: torch.Tensor) -> Tuple[torch.Tensor, torch.Tensor]:
+ shift, scale, gate = mod_params.chunk(3, dim=-1)
+ return x * (1 + scale.unsqueeze(1)) + shift.unsqueeze(1), gate.unsqueeze(1)
+
+ def forward(
+ self,
+ hidden_states: torch.Tensor,
+ encoder_hidden_states: torch.Tensor,
+ temb: torch.Tensor,
+ freqs_cis: torch.Tensor,
+ attention_mask: Optional[torch.Tensor] = None,
+ transformer_options: Optional[Dict[str, Any]] = None,
+ ) -> Tuple[torch.Tensor, torch.Tensor]:
+ img_mod1, img_mod2 = self.img_mod(temb).chunk(2, dim=-1)
+ txt_mod1, txt_mod2 = self.txt_mod(temb).chunk(2, dim=-1)
+
+ img_modulated, img_gate1 = self._modulate(self.img_norm1(hidden_states), img_mod1)
+ txt_modulated, txt_gate1 = self._modulate(self.txt_norm1(encoder_hidden_states), txt_mod1)
+
+ img_attn, txt_attn = self.attn(
+ hidden_states=img_modulated,
+ encoder_hidden_states=txt_modulated,
+ freqs_cis=freqs_cis,
+ attention_mask=attention_mask,
+ transformer_options=transformer_options,
+ )
+
+ hidden_states = hidden_states + img_gate1 * img_attn
+ encoder_hidden_states = encoder_hidden_states + txt_gate1 * txt_attn
+
+ img_modulated2, img_gate2 = self._modulate(self.img_norm2(hidden_states), img_mod2)
+ hidden_states = hidden_states + img_gate2 * self.img_mlp(img_modulated2)
+
+ txt_modulated2, txt_gate2 = self._modulate(self.txt_norm2(encoder_hidden_states), txt_mod2)
+ encoder_hidden_states = encoder_hidden_states + txt_gate2 * self.txt_mlp(txt_modulated2)
+
+ return encoder_hidden_states, hidden_states
+
+
+class _AdaLayerNormContinuousNoAffine(nn.Module):
+ """AdaLayerNormContinuous(elementwise_affine=False).
+
+ The reference uses ``scale, shift = chunk(2)`` (scale first) — opposite
+ to Flux's ``LastLayer``.
+ """
+
+ def __init__(self, embedding_dim: int, conditioning_embedding_dim: int, eps: float = 1e-6,
+ dtype=None, device=None, operations=None) -> None:
+ super().__init__()
+ self.linear = operations.Linear(
+ conditioning_embedding_dim, embedding_dim * 2, bias=True, dtype=dtype, device=device
+ )
+ self.eps = eps
+ self.embedding_dim = embedding_dim
+
+ def forward(self, x: torch.Tensor, conditioning: torch.Tensor) -> torch.Tensor:
+ emb = self.linear(F.silu(conditioning))
+ scale, shift = torch.chunk(emb, 2, dim=-1)
+ x = F.layer_norm(x, (self.embedding_dim,), None, None, self.eps)
+ return x * (1 + scale.unsqueeze(1)) + shift.unsqueeze(1)
+
+
+class LensTransformer2DModel(nn.Module):
+ """Lens dual-stream MMDiT (48 blocks, inner_dim=1536, multi-layer text)."""
+
+ def __init__(
+ self,
+ patch_size: int = 2,
+ in_channels: int = 128,
+ out_channels: Optional[int] = 32,
+ num_layers: int = 48,
+ attention_head_dim: int = 64,
+ num_attention_heads: int = 24,
+ enc_hidden_dim: int = 2880,
+ axes_dims_rope: Tuple[int, int, int] = (8, 28, 28),
+ rms_norm: bool = True,
+ multi_layer_encoder_feature: bool = True,
+ selected_layer_index: Tuple[int, ...] = (5, 11, 17, 23),
+ image_model=None, # unused; accepted for detection-side configs.
+ dtype=None,
+ device=None,
+ operations=None,
+ ) -> None:
+ super().__init__()
+ self.patch_size = patch_size
+ self.in_channels = in_channels
+ self.out_channels = out_channels if out_channels is not None else in_channels
+ self.inner_dim = num_attention_heads * attention_head_dim
+ self.multi_layer_encoder_feature = multi_layer_encoder_feature
+ self.selected_layer_index = list(selected_layer_index)
+ self.dtype = dtype
+
+ self.pos_embed = EmbedND(dim=attention_head_dim, theta=10000, axes_dim=list(axes_dims_rope))
+ self.time_text_embed = LensTimestepProjEmbeddings(
+ embedding_dim=self.inner_dim, dtype=dtype, device=device, operations=operations
+ )
+
+ if self.multi_layer_encoder_feature:
+ self.txt_norm = nn.ModuleList(
+ [operations.RMSNorm(enc_hidden_dim, eps=1e-5, dtype=dtype, device=device)
+ for _ in self.selected_layer_index]
+ )
+ self.txt_in = operations.Linear(
+ enc_hidden_dim * len(self.selected_layer_index),
+ self.inner_dim, bias=True, dtype=dtype, device=device,
+ )
+ else:
+ self.txt_norm = operations.RMSNorm(enc_hidden_dim, eps=1e-5, dtype=dtype, device=device)
+ self.txt_in = operations.Linear(enc_hidden_dim, self.inner_dim, bias=True, dtype=dtype, device=device)
+
+ self.img_in = operations.Linear(in_channels, self.inner_dim, bias=True, dtype=dtype, device=device)
+
+ self.transformer_blocks = nn.ModuleList([
+ LensTransformerBlock(
+ dim=self.inner_dim,
+ num_attention_heads=num_attention_heads,
+ attention_head_dim=attention_head_dim,
+ eps=1e-6,
+ rms_norm=rms_norm,
+ dtype=dtype, device=device, operations=operations,
+ )
+ for _ in range(num_layers)
+ ])
+
+ self.norm_out = _AdaLayerNormContinuousNoAffine(
+ self.inner_dim, self.inner_dim, eps=1e-6,
+ dtype=dtype, device=device, operations=operations,
+ )
+ self.proj_out = operations.Linear(
+ self.inner_dim, patch_size * patch_size * self.out_channels, bias=True,
+ dtype=dtype, device=device,
+ )
+
+ def forward(self, x: torch.Tensor, timestep: torch.Tensor, context: torch.Tensor, attention_mask: Optional[torch.Tensor] = None,
+ transformer_options: Optional[Dict[str, Any]] = None, **kwargs) -> torch.Tensor:
+ if transformer_options is None:
+ transformer_options = {}
+ return comfy.patcher_extension.WrapperExecutor.new_class_executor(
+ self._forward, self,
+ comfy.patcher_extension.get_all_wrappers(comfy.patcher_extension.WrappersMP.DIFFUSION_MODEL, transformer_options),
+ ).execute(x, timestep, context, attention_mask, transformer_options, **kwargs)
+
+ def _forward(
+ self,
+ x: torch.Tensor,
+ timestep: torch.Tensor,
+ context: torch.Tensor,
+ attention_mask: Optional[torch.Tensor] = None,
+ transformer_options: Optional[Dict[str, Any]] = None,
+ control: Optional[Dict[str, Any]] = None,
+ **kwargs,
+ ) -> torch.Tensor:
+ """ComfyUI bridge: ``(x[B,128,h,w], t[B], context[B,S,L*H], mask[B,S])``."""
+ if transformer_options is None:
+ transformer_options = {}
+ transformer_options = transformer_options.copy()
+ patches = transformer_options.get("patches", {})
+ patches_replace = transformer_options.get("patches_replace", {})
+ blocks_replace = patches_replace.get("dit", {})
+
+ B, C, h, w = x.shape
+ hidden_states = x.permute(0, 2, 3, 1).reshape(B, h * w, C)
+
+ if self.multi_layer_encoder_feature:
+ L = len(self.selected_layer_index)
+ enc_dim = context.shape[-1] // L
+ encoder_hidden_states = list(
+ context.reshape(B, -1, L, enc_dim).unbind(dim=2)
+ )
+ text_seq_len = encoder_hidden_states[0].shape[1]
+ else:
+ encoder_hidden_states = context
+ text_seq_len = context.shape[1]
+
+ if attention_mask is None:
+ attention_mask = torch.ones(
+ (B, text_seq_len), dtype=torch.bool, device=x.device
+ )
+
+ img_len = h * w
+ joint_mask = self._build_joint_attention_mask(attention_mask, img_len)
+
+ hidden_states = self.img_in(hidden_states)
+ timestep = timestep.to(hidden_states.dtype)
+
+ if self.multi_layer_encoder_feature:
+ normed = [self.txt_norm[i](encoder_hidden_states[i]) for i in range(L)]
+ encoder_hidden_states = torch.cat(normed, dim=-1)
+ else:
+ encoder_hidden_states = self.txt_norm(encoder_hidden_states)
+ encoder_hidden_states = self.txt_in(encoder_hidden_states)
+
+ if "post_input" in patches:
+ for p in patches["post_input"]:
+ out = p({
+ "img": hidden_states,
+ "txt": encoder_hidden_states,
+ "transformer_options": transformer_options,
+ })
+ hidden_states = out["img"]
+ encoder_hidden_states = out["txt"]
+
+ temb = self.time_text_embed(timestep, hidden_states)
+ ids = _lens_position_ids(1, h, w, text_seq_len, device=hidden_states.device).unsqueeze(0)
+ freqs_cis = self.pos_embed(ids)
+
+ transformer_options["total_blocks"] = len(self.transformer_blocks)
+ transformer_options["block_type"] = "double"
+ for i, block in enumerate(self.transformer_blocks):
+ transformer_options["block_index"] = i
+ if ("double_block", i) in blocks_replace:
+ def block_wrap(args):
+ out = {}
+ out["txt"], out["img"] = block(
+ hidden_states=args["img"],
+ encoder_hidden_states=args["txt"],
+ temb=args["vec"],
+ freqs_cis=args["pe"],
+ attention_mask=args.get("attn_mask"),
+ transformer_options=args.get("transformer_options"),
+ )
+ return out
+ out = blocks_replace[("double_block", i)](
+ {
+ "img": hidden_states,
+ "txt": encoder_hidden_states,
+ "vec": temb,
+ "pe": freqs_cis,
+ "attn_mask": joint_mask,
+ "transformer_options": transformer_options,
+ },
+ {"original_block": block_wrap},
+ )
+ encoder_hidden_states = out["txt"]
+ hidden_states = out["img"]
+ else:
+ encoder_hidden_states, hidden_states = block(
+ hidden_states=hidden_states,
+ encoder_hidden_states=encoder_hidden_states,
+ temb=temb,
+ freqs_cis=freqs_cis,
+ attention_mask=joint_mask,
+ transformer_options=transformer_options,
+ )
+
+ if "double_block" in patches:
+ for p in patches["double_block"]:
+ out = p({
+ "img": hidden_states,
+ "txt": encoder_hidden_states,
+ "x": x,
+ "block_index": i,
+ "transformer_options": transformer_options,
+ })
+ hidden_states = out["img"]
+ encoder_hidden_states = out["txt"]
+
+ if control is not None:
+ control_i = control.get("input")
+ if control_i is not None and i < len(control_i):
+ add = control_i[i]
+ if add is not None:
+ hidden_states[:, :add.shape[1]] += add
+
+ hidden_states = self.norm_out(hidden_states, temb)
+ out = self.proj_out(hidden_states)
+ return out.reshape(B, h, w, C).permute(0, 3, 1, 2).contiguous()
+
+ @staticmethod
+ def _build_joint_attention_mask(text_mask: torch.Tensor, img_len: int) -> torch.Tensor:
+ if text_mask.dtype != torch.bool:
+ text_mask = text_mask.bool()
+ bsz = text_mask.shape[0]
+ img_ones = torch.ones((bsz, img_len), dtype=torch.bool, device=text_mask.device)
+ joint = torch.cat([img_ones, text_mask], dim=1)
+ additive = torch.zeros_like(joint, dtype=torch.float32)
+ additive.masked_fill_(~joint, torch.finfo(torch.float32).min)
+ return additive[:, None, None, :]
diff --git a/ComfyUI/comfy/ldm/lightricks/__pycache__/av_model.cpython-312.pyc b/ComfyUI/comfy/ldm/lightricks/__pycache__/av_model.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..2dac76d03e153efcd0c415df827487d628c5d662
Binary files /dev/null and b/ComfyUI/comfy/ldm/lightricks/__pycache__/av_model.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/lightricks/__pycache__/embeddings_connector.cpython-312.pyc b/ComfyUI/comfy/ldm/lightricks/__pycache__/embeddings_connector.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..a640cd2c7eb50b68a302fb220ae18b9a6b27e8a1
Binary files /dev/null and b/ComfyUI/comfy/ldm/lightricks/__pycache__/embeddings_connector.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/lightricks/__pycache__/latent_upsampler.cpython-312.pyc b/ComfyUI/comfy/ldm/lightricks/__pycache__/latent_upsampler.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..20531e67a0aaa6b93961341ae0a7144cf37a1e33
Binary files /dev/null and b/ComfyUI/comfy/ldm/lightricks/__pycache__/latent_upsampler.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/lightricks/__pycache__/model.cpython-312.pyc b/ComfyUI/comfy/ldm/lightricks/__pycache__/model.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..739dbdeaca061832e9651cc842afb38d922e1ec7
Binary files /dev/null and b/ComfyUI/comfy/ldm/lightricks/__pycache__/model.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/lightricks/__pycache__/symmetric_patchifier.cpython-312.pyc b/ComfyUI/comfy/ldm/lightricks/__pycache__/symmetric_patchifier.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..46ccfaeb1bf3217a8effd9461ec9678a2e9c0eb7
Binary files /dev/null and b/ComfyUI/comfy/ldm/lightricks/__pycache__/symmetric_patchifier.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/lightricks/av_model.py b/ComfyUI/comfy/ldm/lightricks/av_model.py
new file mode 100644
index 0000000000000000000000000000000000000000..ef99384652048ded6abf8a189997361a65ec0cb7
--- /dev/null
+++ b/ComfyUI/comfy/ldm/lightricks/av_model.py
@@ -0,0 +1,1078 @@
+from typing import Tuple
+import torch
+import torch.nn as nn
+from comfy.ldm.lightricks.model import (
+ ADALN_BASE_PARAMS_COUNT,
+ ADALN_CROSS_ATTN_PARAMS_COUNT,
+ CrossAttention,
+ FeedForward,
+ AdaLayerNormSingle,
+ PixArtAlphaTextProjection,
+ NormSingleLinearTextProjection,
+ LTXVModel,
+ apply_cross_attention_adaln,
+ compute_prompt_timestep,
+)
+from comfy.ldm.lightricks.symmetric_patchifier import AudioPatchifier
+from comfy.ldm.lightricks.embeddings_connector import Embeddings1DConnector
+import comfy.ldm.common_dit
+import comfy.model_prefetch
+
+class CompressedTimestep:
+ """Store video timestep embeddings in compressed form using per-frame indexing."""
+ __slots__ = ('data', 'batch_size', 'num_frames', 'patches_per_frame', 'feature_dim')
+
+ def __init__(self, tensor: torch.Tensor, patches_per_frame: int, per_frame: bool = False):
+ """
+ tensor: [batch, num_tokens, feature_dim] (per-token, default) or
+ [batch, num_frames, feature_dim] (per_frame=True, already compressed).
+ patches_per_frame: spatial patches per frame; pass None to disable compression.
+ """
+ self.batch_size, n, self.feature_dim = tensor.shape
+ if per_frame:
+ self.patches_per_frame = patches_per_frame
+ self.num_frames = n
+ self.data = tensor
+ elif patches_per_frame is not None and n >= patches_per_frame and n % patches_per_frame == 0:
+ self.patches_per_frame = patches_per_frame
+ self.num_frames = n // patches_per_frame
+ # All patches in a frame are identical — keep only the first.
+ self.data = tensor.view(self.batch_size, self.num_frames, patches_per_frame, self.feature_dim)[:, :, 0, :].contiguous()
+ else:
+ self.patches_per_frame = 1
+ self.num_frames = n
+ self.data = tensor
+
+ def expand(self):
+ """Expand back to original tensor."""
+ if self.patches_per_frame == 1:
+ return self.data
+
+ # [batch, frames, feature_dim] -> [batch, frames, patches_per_frame, feature_dim] -> [batch, tokens, feature_dim]
+ expanded = self.data.unsqueeze(2).expand(self.batch_size, self.num_frames, self.patches_per_frame, self.feature_dim)
+ return expanded.reshape(self.batch_size, -1, self.feature_dim)
+
+ def expand_for_computation(self, scale_shift_table: torch.Tensor, batch_size: int, indices: slice = slice(None, None)):
+ """Compute ada values on compressed per-frame data, then expand spatially."""
+ num_ada_params = scale_shift_table.shape[0]
+
+ # No compression - compute directly
+ if self.patches_per_frame == 1:
+ num_tokens = self.data.shape[1]
+ dim_per_param = self.feature_dim // num_ada_params
+ reshaped = self.data.reshape(batch_size, num_tokens, num_ada_params, dim_per_param)[:, :, indices, :]
+ table_values = scale_shift_table[indices].unsqueeze(0).unsqueeze(0).to(device=self.data.device, dtype=self.data.dtype)
+ ada_values = (table_values + reshaped).unbind(dim=2)
+ return ada_values
+
+ # Compressed: compute on per-frame data then expand spatially
+ # Reshape: [batch, frames, feature_dim] -> [batch, frames, num_ada_params, dim_per_param]
+ frame_reshaped = self.data.reshape(batch_size, self.num_frames, num_ada_params, -1)[:, :, indices, :]
+ table_values = scale_shift_table[indices].unsqueeze(0).unsqueeze(0).to(
+ device=self.data.device, dtype=self.data.dtype
+ )
+ frame_ada = (table_values + frame_reshaped).unbind(dim=2)
+
+ # Expand each ada parameter spatially: [batch, frames, dim] -> [batch, frames, patches, dim] -> [batch, tokens, dim]
+ return tuple(
+ frame_val.unsqueeze(2).expand(batch_size, self.num_frames, self.patches_per_frame, -1)
+ .reshape(batch_size, -1, frame_val.shape[-1])
+ for frame_val in frame_ada
+ )
+
+class BasicAVTransformerBlock(nn.Module):
+ def __init__(
+ self,
+ v_dim,
+ a_dim,
+ v_heads,
+ a_heads,
+ vd_head,
+ ad_head,
+ v_context_dim=None,
+ a_context_dim=None,
+ attn_precision=None,
+ apply_gated_attention=False,
+ cross_attention_adaln=False,
+ dtype=None,
+ device=None,
+ operations=None,
+ ):
+ super().__init__()
+
+ self.attn_precision = attn_precision
+ self.cross_attention_adaln = cross_attention_adaln
+
+ self.attn1 = CrossAttention(
+ query_dim=v_dim,
+ heads=v_heads,
+ dim_head=vd_head,
+ context_dim=None,
+ attn_precision=self.attn_precision,
+ apply_gated_attention=apply_gated_attention,
+ dtype=dtype,
+ device=device,
+ operations=operations,
+ )
+ self.audio_attn1 = CrossAttention(
+ query_dim=a_dim,
+ heads=a_heads,
+ dim_head=ad_head,
+ context_dim=None,
+ attn_precision=self.attn_precision,
+ apply_gated_attention=apply_gated_attention,
+ dtype=dtype,
+ device=device,
+ operations=operations,
+ )
+
+ self.attn2 = CrossAttention(
+ query_dim=v_dim,
+ context_dim=v_context_dim,
+ heads=v_heads,
+ dim_head=vd_head,
+ attn_precision=self.attn_precision,
+ apply_gated_attention=apply_gated_attention,
+ dtype=dtype,
+ device=device,
+ operations=operations,
+ )
+ self.audio_attn2 = CrossAttention(
+ query_dim=a_dim,
+ context_dim=a_context_dim,
+ heads=a_heads,
+ dim_head=ad_head,
+ attn_precision=self.attn_precision,
+ apply_gated_attention=apply_gated_attention,
+ dtype=dtype,
+ device=device,
+ operations=operations,
+ )
+
+ # Q: Video, K,V: Audio
+ self.audio_to_video_attn = CrossAttention(
+ query_dim=v_dim,
+ context_dim=a_dim,
+ heads=a_heads,
+ dim_head=ad_head,
+ attn_precision=self.attn_precision,
+ apply_gated_attention=apply_gated_attention,
+ dtype=dtype,
+ device=device,
+ operations=operations,
+ )
+
+ # Q: Audio, K,V: Video
+ self.video_to_audio_attn = CrossAttention(
+ query_dim=a_dim,
+ context_dim=v_dim,
+ heads=a_heads,
+ dim_head=ad_head,
+ attn_precision=self.attn_precision,
+ apply_gated_attention=apply_gated_attention,
+ dtype=dtype,
+ device=device,
+ operations=operations,
+ )
+
+ self.ff = FeedForward(
+ v_dim, dim_out=v_dim, glu=True, dtype=dtype, device=device, operations=operations
+ )
+ self.audio_ff = FeedForward(
+ a_dim, dim_out=a_dim, glu=True, dtype=dtype, device=device, operations=operations
+ )
+
+ num_ada_params = ADALN_CROSS_ATTN_PARAMS_COUNT if cross_attention_adaln else ADALN_BASE_PARAMS_COUNT
+ self.scale_shift_table = nn.Parameter(torch.empty(num_ada_params, v_dim, device=device, dtype=dtype))
+ self.audio_scale_shift_table = nn.Parameter(
+ torch.empty(num_ada_params, a_dim, device=device, dtype=dtype)
+ )
+
+ if cross_attention_adaln:
+ self.prompt_scale_shift_table = nn.Parameter(torch.empty(2, v_dim, device=device, dtype=dtype))
+ self.audio_prompt_scale_shift_table = nn.Parameter(torch.empty(2, a_dim, device=device, dtype=dtype))
+
+ self.scale_shift_table_a2v_ca_audio = nn.Parameter(
+ torch.empty(5, a_dim, device=device, dtype=dtype)
+ )
+ self.scale_shift_table_a2v_ca_video = nn.Parameter(
+ torch.empty(5, v_dim, device=device, dtype=dtype)
+ )
+
+ def get_ada_values(
+ self, scale_shift_table: torch.Tensor, batch_size: int, timestep: torch.Tensor, indices: slice = slice(None, None)
+ ):
+ if isinstance(timestep, CompressedTimestep):
+ return timestep.expand_for_computation(scale_shift_table, batch_size, indices)
+
+ num_ada_params = scale_shift_table.shape[0]
+
+ ada_values = (
+ scale_shift_table[indices].unsqueeze(0).unsqueeze(0).to(device=timestep.device, dtype=timestep.dtype)
+ + timestep.reshape(batch_size, timestep.shape[1], num_ada_params, -1)[:, :, indices, :]
+ ).unbind(dim=2)
+ return ada_values
+
+ def get_av_ca_ada_values(
+ self,
+ scale_shift_table: torch.Tensor,
+ batch_size: int,
+ scale_shift_timestep: torch.Tensor,
+ gate_timestep: torch.Tensor,
+ num_scale_shift_values: int = 4,
+ ):
+ scale_shift_ada_values = self.get_ada_values(
+ scale_shift_table[:num_scale_shift_values, :],
+ batch_size,
+ scale_shift_timestep,
+ )
+ gate_ada_values = self.get_ada_values(
+ scale_shift_table[num_scale_shift_values:, :],
+ batch_size,
+ gate_timestep,
+ )
+
+ return (*scale_shift_ada_values, *gate_ada_values)
+
+ def _apply_text_cross_attention(
+ self, x, context, attn, scale_shift_table, prompt_scale_shift_table,
+ timestep, prompt_timestep, attention_mask, transformer_options,
+ ):
+ """Apply text cross-attention, with optional ADaLN modulation."""
+ if self.cross_attention_adaln:
+ shift_q, scale_q, gate = self.get_ada_values(
+ scale_shift_table, x.shape[0], timestep, slice(6, 9)
+ )
+ return apply_cross_attention_adaln(
+ x, context, attn, shift_q, scale_q, gate,
+ prompt_scale_shift_table, prompt_timestep,
+ attention_mask, transformer_options,
+ )
+ return attn(
+ comfy.ldm.common_dit.rms_norm(x), context=context,
+ mask=attention_mask, transformer_options=transformer_options,
+ )
+
+ def forward(
+ self, x: Tuple[torch.Tensor, torch.Tensor], v_context=None, a_context=None, attention_mask=None, v_timestep=None, a_timestep=None,
+ v_pe=None, a_pe=None, v_cross_pe=None, a_cross_pe=None, v_cross_scale_shift_timestep=None, a_cross_scale_shift_timestep=None,
+ v_cross_gate_timestep=None, a_cross_gate_timestep=None, transformer_options=None, self_attention_mask=None,
+ v_prompt_timestep=None, a_prompt_timestep=None,
+ ) -> Tuple[torch.Tensor, torch.Tensor]:
+ run_vx = transformer_options.get("run_vx", True)
+ run_ax = transformer_options.get("run_ax", True)
+
+ vx, ax = x
+ run_ax = run_ax and ax.numel() > 0
+ run_a2v = run_vx and transformer_options.get("a2v_cross_attn", True) and ax.numel() > 0
+ run_v2a = run_ax and transformer_options.get("v2a_cross_attn", True)
+
+ # video
+ if run_vx:
+ # video self-attention
+ vshift_msa, vscale_msa = (self.get_ada_values(self.scale_shift_table, vx.shape[0], v_timestep, slice(0, 2)))
+ norm_vx = comfy.ldm.common_dit.rms_norm(vx) * (1 + vscale_msa) + vshift_msa
+ del vshift_msa, vscale_msa
+ attn1_out = self.attn1(norm_vx, pe=v_pe, mask=self_attention_mask, transformer_options=transformer_options)
+ del norm_vx
+ # video cross-attention
+ vgate_msa = self.get_ada_values(self.scale_shift_table, vx.shape[0], v_timestep, slice(2, 3))[0]
+ vx.addcmul_(attn1_out, vgate_msa)
+ del vgate_msa, attn1_out
+ vx.add_(self._apply_text_cross_attention(
+ vx, v_context, self.attn2, self.scale_shift_table,
+ getattr(self, 'prompt_scale_shift_table', None),
+ v_timestep, v_prompt_timestep, attention_mask, transformer_options,)
+ )
+
+ # audio
+ if run_ax:
+ # audio self-attention
+ ashift_msa, ascale_msa = (self.get_ada_values(self.audio_scale_shift_table, ax.shape[0], a_timestep, slice(0, 2)))
+ norm_ax = comfy.ldm.common_dit.rms_norm(ax) * (1 + ascale_msa) + ashift_msa
+ del ashift_msa, ascale_msa
+ attn1_out = self.audio_attn1(norm_ax, pe=a_pe, transformer_options=transformer_options)
+ del norm_ax
+ # audio cross-attention
+ agate_msa = self.get_ada_values(self.audio_scale_shift_table, ax.shape[0], a_timestep, slice(2, 3))[0]
+ ax.addcmul_(attn1_out, agate_msa)
+ del agate_msa, attn1_out
+ ax.add_(self._apply_text_cross_attention(
+ ax, a_context, self.audio_attn2, self.audio_scale_shift_table,
+ getattr(self, 'audio_prompt_scale_shift_table', None),
+ a_timestep, a_prompt_timestep, attention_mask, transformer_options,)
+ )
+
+ # video - audio cross attention.
+ if run_a2v or run_v2a:
+ vx_norm3 = comfy.ldm.common_dit.rms_norm(vx)
+ ax_norm3 = comfy.ldm.common_dit.rms_norm(ax)
+
+ # audio to video cross attention
+ if run_a2v:
+ scale_ca_audio_hidden_states_a2v, shift_ca_audio_hidden_states_a2v = self.get_ada_values(
+ self.scale_shift_table_a2v_ca_audio[:4, :], ax.shape[0], a_cross_scale_shift_timestep)[:2]
+ scale_ca_video_hidden_states_a2v_v, shift_ca_video_hidden_states_a2v_v = self.get_ada_values(
+ self.scale_shift_table_a2v_ca_video[:4, :], vx.shape[0], v_cross_scale_shift_timestep)[:2]
+
+ vx_scaled = vx_norm3 * (1 + scale_ca_video_hidden_states_a2v_v) + shift_ca_video_hidden_states_a2v_v
+ ax_scaled = ax_norm3 * (1 + scale_ca_audio_hidden_states_a2v) + shift_ca_audio_hidden_states_a2v
+ del scale_ca_video_hidden_states_a2v_v, shift_ca_video_hidden_states_a2v_v, scale_ca_audio_hidden_states_a2v, shift_ca_audio_hidden_states_a2v
+
+ a2v_out = self.audio_to_video_attn(vx_scaled, context=ax_scaled, pe=v_cross_pe, k_pe=a_cross_pe, transformer_options=transformer_options)
+ del vx_scaled, ax_scaled
+
+ gate_out_a2v = self.get_ada_values(self.scale_shift_table_a2v_ca_video[4:, :], vx.shape[0], v_cross_gate_timestep)[0]
+ vx.addcmul_(a2v_out, gate_out_a2v)
+ del gate_out_a2v, a2v_out
+
+ # video to audio cross attention
+ if run_v2a:
+ scale_ca_audio_hidden_states_v2a, shift_ca_audio_hidden_states_v2a = self.get_ada_values(
+ self.scale_shift_table_a2v_ca_audio[:4, :], ax.shape[0], a_cross_scale_shift_timestep)[2:4]
+ scale_ca_video_hidden_states_v2a, shift_ca_video_hidden_states_v2a = self.get_ada_values(
+ self.scale_shift_table_a2v_ca_video[:4, :], vx.shape[0], v_cross_scale_shift_timestep)[2:4]
+
+ ax_scaled = ax_norm3 * (1 + scale_ca_audio_hidden_states_v2a) + shift_ca_audio_hidden_states_v2a
+ vx_scaled = vx_norm3 * (1 + scale_ca_video_hidden_states_v2a) + shift_ca_video_hidden_states_v2a
+ del scale_ca_video_hidden_states_v2a, shift_ca_video_hidden_states_v2a, scale_ca_audio_hidden_states_v2a, shift_ca_audio_hidden_states_v2a
+
+ v2a_out = self.video_to_audio_attn(ax_scaled, context=vx_scaled, pe=a_cross_pe, k_pe=v_cross_pe, transformer_options=transformer_options)
+ del ax_scaled, vx_scaled
+
+ gate_out_v2a = self.get_ada_values(self.scale_shift_table_a2v_ca_audio[4:, :], ax.shape[0], a_cross_gate_timestep)[0]
+ ax.addcmul_(v2a_out, gate_out_v2a)
+ del gate_out_v2a, v2a_out
+
+ del vx_norm3, ax_norm3
+
+ # video feedforward
+ if run_vx:
+ vshift_mlp, vscale_mlp = self.get_ada_values(self.scale_shift_table, vx.shape[0], v_timestep, slice(3, 5))
+ vx_scaled = comfy.ldm.common_dit.rms_norm(vx) * (1 + vscale_mlp) + vshift_mlp
+ del vshift_mlp, vscale_mlp
+
+ ff_out = self.ff(vx_scaled)
+ del vx_scaled
+
+ vgate_mlp = self.get_ada_values(self.scale_shift_table, vx.shape[0], v_timestep, slice(5, 6))[0]
+ vx.addcmul_(ff_out, vgate_mlp)
+ del vgate_mlp, ff_out
+
+ # audio feedforward
+ if run_ax:
+ ashift_mlp, ascale_mlp = self.get_ada_values(self.audio_scale_shift_table, ax.shape[0], a_timestep, slice(3, 5))
+ ax_scaled = comfy.ldm.common_dit.rms_norm(ax) * (1 + ascale_mlp) + ashift_mlp
+ del ashift_mlp, ascale_mlp
+
+ ff_out = self.audio_ff(ax_scaled)
+ del ax_scaled
+
+ agate_mlp = self.get_ada_values(self.audio_scale_shift_table, ax.shape[0], a_timestep, slice(5, 6))[0]
+ ax.addcmul_(ff_out, agate_mlp)
+ del agate_mlp, ff_out
+
+ return vx, ax
+
+
+class LTXAVModel(LTXVModel):
+ """LTXAV model for audio-video generation."""
+
+ def __init__(
+ self,
+ in_channels=128,
+ audio_in_channels=128,
+ cross_attention_dim=4096,
+ audio_cross_attention_dim=2048,
+ attention_head_dim=128,
+ audio_attention_head_dim=64,
+ num_attention_heads=32,
+ audio_num_attention_heads=32,
+ caption_channels=3840,
+ num_layers=48,
+ positional_embedding_theta=10000.0,
+ positional_embedding_max_pos=[20, 2048, 2048],
+ audio_positional_embedding_max_pos=[20],
+ causal_temporal_positioning=False,
+ vae_scale_factors=(8, 32, 32),
+ use_middle_indices_grid=False,
+ timestep_scale_multiplier=1000.0,
+ av_ca_timestep_scale_multiplier=1.0,
+ apply_gated_attention=False,
+ caption_proj_before_connector=False,
+ cross_attention_adaln=False,
+ dtype=None,
+ device=None,
+ operations=None,
+ **kwargs,
+ ):
+ # Store audio-specific parameters
+ self.audio_in_channels = audio_in_channels
+ self.audio_cross_attention_dim = audio_cross_attention_dim
+ self.audio_attention_head_dim = audio_attention_head_dim
+ self.audio_num_attention_heads = audio_num_attention_heads
+ self.audio_positional_embedding_max_pos = audio_positional_embedding_max_pos
+ self.apply_gated_attention = apply_gated_attention
+
+ # Calculate audio dimensions
+ self.audio_inner_dim = audio_num_attention_heads * audio_attention_head_dim
+ self.audio_out_channels = audio_in_channels
+
+ # Audio-specific constants
+ self.num_audio_channels = 8
+ self.audio_frequency_bins = 16
+
+ self.av_ca_timestep_scale_multiplier = av_ca_timestep_scale_multiplier
+
+ super().__init__(
+ in_channels=in_channels,
+ cross_attention_dim=cross_attention_dim,
+ attention_head_dim=attention_head_dim,
+ num_attention_heads=num_attention_heads,
+ caption_channels=caption_channels,
+ num_layers=num_layers,
+ positional_embedding_theta=positional_embedding_theta,
+ positional_embedding_max_pos=positional_embedding_max_pos,
+ causal_temporal_positioning=causal_temporal_positioning,
+ vae_scale_factors=vae_scale_factors,
+ use_middle_indices_grid=use_middle_indices_grid,
+ timestep_scale_multiplier=timestep_scale_multiplier,
+ caption_proj_before_connector=caption_proj_before_connector,
+ cross_attention_adaln=cross_attention_adaln,
+ dtype=dtype,
+ device=device,
+ operations=operations,
+ **kwargs,
+ )
+
+ def _init_model_components(self, device, dtype, **kwargs):
+ """Initialize LTXAV-specific components."""
+ # Audio-specific projections
+ self.audio_patchify_proj = self.operations.Linear(
+ self.audio_in_channels, self.audio_inner_dim, bias=True, dtype=dtype, device=device
+ )
+
+ # Audio-specific AdaLN
+ audio_embedding_coefficient = ADALN_CROSS_ATTN_PARAMS_COUNT if self.cross_attention_adaln else ADALN_BASE_PARAMS_COUNT
+ self.audio_adaln_single = AdaLayerNormSingle(
+ self.audio_inner_dim,
+ embedding_coefficient=audio_embedding_coefficient,
+ use_additional_conditions=False,
+ dtype=dtype,
+ device=device,
+ operations=self.operations,
+ )
+
+ if self.cross_attention_adaln:
+ self.audio_prompt_adaln_single = AdaLayerNormSingle(
+ self.audio_inner_dim,
+ embedding_coefficient=2,
+ use_additional_conditions=False,
+ dtype=dtype,
+ device=device,
+ operations=self.operations,
+ )
+ else:
+ self.audio_prompt_adaln_single = None
+
+ num_scale_shift_values = 4
+ self.av_ca_video_scale_shift_adaln_single = AdaLayerNormSingle(
+ self.inner_dim,
+ use_additional_conditions=False,
+ embedding_coefficient=num_scale_shift_values,
+ dtype=dtype,
+ device=device,
+ operations=self.operations,
+ )
+ self.av_ca_a2v_gate_adaln_single = AdaLayerNormSingle(
+ self.inner_dim,
+ use_additional_conditions=False,
+ embedding_coefficient=1,
+ dtype=dtype,
+ device=device,
+ operations=self.operations,
+ )
+ self.av_ca_audio_scale_shift_adaln_single = AdaLayerNormSingle(
+ self.audio_inner_dim,
+ use_additional_conditions=False,
+ embedding_coefficient=num_scale_shift_values,
+ dtype=dtype,
+ device=device,
+ operations=self.operations,
+ )
+ self.av_ca_v2a_gate_adaln_single = AdaLayerNormSingle(
+ self.audio_inner_dim,
+ use_additional_conditions=False,
+ embedding_coefficient=1,
+ dtype=dtype,
+ device=device,
+ operations=self.operations,
+ )
+
+ # Audio caption projection
+ if self.caption_proj_before_connector:
+ if self.caption_projection_first_linear:
+ self.audio_caption_projection = NormSingleLinearTextProjection(
+ in_features=self.caption_channels,
+ hidden_size=self.audio_inner_dim,
+ dtype=dtype,
+ device=device,
+ operations=self.operations,
+ )
+ else:
+ self.audio_caption_projection = lambda a: a
+ else:
+ self.audio_caption_projection = PixArtAlphaTextProjection(
+ in_features=self.caption_channels,
+ hidden_size=self.audio_inner_dim,
+ dtype=dtype,
+ device=device,
+ operations=self.operations,
+ )
+
+ connector_split_rope = kwargs.get("rope_type", "split") == "split"
+ connector_gated_attention = kwargs.get("connector_apply_gated_attention", False)
+ attention_head_dim = kwargs.get("connector_attention_head_dim", 128)
+ num_attention_heads = kwargs.get("connector_num_attention_heads", 30)
+ num_layers = kwargs.get("connector_num_layers", 2)
+
+ self.audio_embeddings_connector = Embeddings1DConnector(
+ attention_head_dim=kwargs.get("audio_connector_attention_head_dim", attention_head_dim),
+ num_attention_heads=kwargs.get("audio_connector_num_attention_heads", num_attention_heads),
+ num_layers=num_layers,
+ split_rope=connector_split_rope,
+ double_precision_rope=True,
+ apply_gated_attention=connector_gated_attention,
+ dtype=dtype,
+ device=device,
+ operations=self.operations,
+ )
+
+ self.video_embeddings_connector = Embeddings1DConnector(
+ attention_head_dim=attention_head_dim,
+ num_attention_heads=num_attention_heads,
+ num_layers=num_layers,
+ split_rope=connector_split_rope,
+ double_precision_rope=True,
+ apply_gated_attention=connector_gated_attention,
+ dtype=dtype,
+ device=device,
+ operations=self.operations,
+ )
+
+ def preprocess_text_embeds(self, context, unprocessed=False):
+ # LTXv2 fully processed context has dimension of self.caption_channels * 2
+ # LTXv2.3 fully processed context has dimension of self.cross_attention_dim + self.audio_cross_attention_dim
+ if not unprocessed:
+ if context.shape[-1] in (self.cross_attention_dim + self.audio_cross_attention_dim, self.caption_channels * 2):
+ return context
+ if context.shape[-1] == self.cross_attention_dim + self.audio_cross_attention_dim:
+ context_vid = context[:, :, :self.cross_attention_dim]
+ context_audio = context[:, :, self.cross_attention_dim:]
+ else:
+ context_vid = context
+ context_audio = context
+ if self.caption_proj_before_connector:
+ context_vid = self.caption_projection(context_vid)
+ context_audio = self.audio_caption_projection(context_audio)
+ out_vid = self.video_embeddings_connector(context_vid)[0]
+ out_audio = self.audio_embeddings_connector(context_audio)[0]
+ return torch.concat((out_vid, out_audio), dim=-1)
+
+ def _init_transformer_blocks(self, device, dtype, **kwargs):
+ """Initialize transformer blocks for LTXAV."""
+ self.transformer_blocks = nn.ModuleList(
+ [
+ BasicAVTransformerBlock(
+ v_dim=self.inner_dim,
+ a_dim=self.audio_inner_dim,
+ v_heads=self.num_attention_heads,
+ a_heads=self.audio_num_attention_heads,
+ vd_head=self.attention_head_dim,
+ ad_head=self.audio_attention_head_dim,
+ v_context_dim=self.cross_attention_dim,
+ a_context_dim=self.audio_cross_attention_dim,
+ apply_gated_attention=self.apply_gated_attention,
+ cross_attention_adaln=self.cross_attention_adaln,
+ dtype=dtype,
+ device=device,
+ operations=self.operations,
+ )
+ for _ in range(self.num_layers)
+ ]
+ )
+
+ def _init_output_components(self, device, dtype):
+ """Initialize output components for LTXAV."""
+ # Video output components
+ super()._init_output_components(device, dtype)
+ # Audio output components
+ self.audio_scale_shift_table = nn.Parameter(
+ torch.empty(2, self.audio_inner_dim, dtype=dtype, device=device)
+ )
+ self.audio_norm_out = self.operations.LayerNorm(
+ self.audio_inner_dim, elementwise_affine=False, eps=1e-6, dtype=dtype, device=device
+ )
+ self.audio_proj_out = self.operations.Linear(
+ self.audio_inner_dim, self.audio_out_channels, dtype=dtype, device=device
+ )
+ self.a_patchifier = AudioPatchifier(1, start_end=True)
+
+ def separate_audio_and_video_latents(self, x, audio_length):
+ """Separate audio and video latents from combined input."""
+ # vx = x[:, : self.in_channels]
+ # ax = x[:, self.in_channels :]
+ #
+ # ax = ax.reshape(ax.shape[0], -1)
+ # ax = ax[:, : audio_length * self.num_audio_channels * self.audio_frequency_bins]
+ #
+ # ax = ax.reshape(
+ # ax.shape[0], self.num_audio_channels, audio_length, self.audio_frequency_bins
+ # )
+
+ vx = x[0]
+ ax = x[1] if len(x) > 1 else torch.zeros(
+ (vx.shape[0], self.num_audio_channels, 0, self.audio_frequency_bins),
+ device=vx.device, dtype=vx.dtype
+ )
+ return vx, ax
+
+ def recombine_audio_and_video_latents(self, vx, ax, target_shape=None):
+ if ax.numel() == 0:
+ return vx
+ else:
+ return [vx, ax]
+ """Recombine audio and video latents for output."""
+ # if ax.device != vx.device or ax.dtype != vx.dtype:
+ # logging.warning("Audio and video latents are on different devices or dtypes.")
+ # ax = ax.to(device=vx.device, dtype=vx.dtype)
+ # logging.warning(f"Audio audio latent moved to device: {ax.device}, dtype: {ax.dtype}")
+ #
+ # ax = ax.reshape(ax.shape[0], -1)
+ # # pad to f x h x w of the video latents
+ # divisor = vx.shape[-1] * vx.shape[-2] * vx.shape[-3]
+ # if target_shape is None:
+ # repetitions = math.ceil(ax.shape[-1] / divisor)
+ # else:
+ # repetitions = target_shape[1] - vx.shape[1]
+ # padded_len = repetitions * divisor
+ # ax = F.pad(ax, (0, padded_len - ax.shape[-1]))
+ # ax = ax.reshape(ax.shape[0], -1, vx.shape[-3], vx.shape[-2], vx.shape[-1])
+ # return torch.cat([vx, ax], dim=1)
+
+ def _process_input(self, x, keyframe_idxs, denoise_mask, **kwargs):
+ """Process input for LTXAV - separate audio and video, then patchify."""
+ audio_length = kwargs.get("audio_length", 0)
+ # Separate audio and video latents
+ vx, ax = self.separate_audio_and_video_latents(x, audio_length)
+
+ has_spatial_mask = False
+ if denoise_mask is not None:
+ # check if any frame has spatial variation (inpainting)
+ for frame_idx in range(denoise_mask.shape[2]):
+ frame_mask = denoise_mask[0, 0, frame_idx]
+ if frame_mask.numel() > 0 and frame_mask.min() != frame_mask.max():
+ has_spatial_mask = True
+ break
+
+ [vx, v_pixel_coords, additional_args] = super()._process_input(
+ vx, keyframe_idxs, denoise_mask, **kwargs
+ )
+ additional_args["has_spatial_mask"] = has_spatial_mask
+
+ ax, a_latent_coords = self.a_patchifier.patchify(ax)
+
+ # Inject reference audio for ID-LoRA in-context conditioning
+ ref_audio = kwargs.get("ref_audio", None)
+ ref_audio_seq_len = 0
+ if ref_audio is not None:
+ ref_tokens = ref_audio["tokens"].to(dtype=ax.dtype, device=ax.device)
+ if ref_tokens.shape[0] < ax.shape[0]:
+ ref_tokens = ref_tokens.expand(ax.shape[0], -1, -1)
+ ref_audio_seq_len = ref_tokens.shape[1]
+ B = ax.shape[0]
+
+ # Compute negative temporal positions matching ID-LoRA convention:
+ # offset by -(end_of_last_token + time_per_latent) so reference ends just before t=0
+ p = self.a_patchifier
+ tpl = p.hop_length * p.audio_latent_downsample_factor / p.sample_rate
+ ref_start = p._get_audio_latent_time_in_sec(0, ref_audio_seq_len, torch.float32, ax.device)
+ ref_end = p._get_audio_latent_time_in_sec(1, ref_audio_seq_len + 1, torch.float32, ax.device)
+ time_offset = ref_end[-1].item() + tpl
+ ref_start = (ref_start - time_offset).unsqueeze(0).expand(B, -1).unsqueeze(1)
+ ref_end = (ref_end - time_offset).unsqueeze(0).expand(B, -1).unsqueeze(1)
+ ref_pos = torch.stack([ref_start, ref_end], dim=-1)
+
+ additional_args["ref_audio_seq_len"] = ref_audio_seq_len
+ additional_args["target_audio_seq_len"] = ax.shape[1]
+ ax = torch.cat([ref_tokens, ax], dim=1)
+ a_latent_coords = torch.cat([ref_pos.to(a_latent_coords), a_latent_coords], dim=2)
+
+ ax = self.audio_patchify_proj(ax)
+
+ # additional_args.update({"av_orig_shape": list(x.shape)})
+ return [vx, ax], [v_pixel_coords, a_latent_coords], additional_args
+
+ def _prepare_timestep(self, timestep, batch_size, hidden_dtype, **kwargs):
+ """Prepare timestep embeddings."""
+ grid_mask = kwargs.get("grid_mask", None)
+ orig_shape = kwargs.get("orig_shape")
+ has_spatial_mask = kwargs.get("has_spatial_mask", None)
+ v_patches_per_frame = None
+ if not has_spatial_mask and orig_shape is not None and len(orig_shape) == 5:
+ v_patches_per_frame = orig_shape[3] * orig_shape[4]
+
+ # Used by compute_prompt_timestep and the audio cross-attention paths.
+ timestep_scaled = (timestep[:, grid_mask] if grid_mask is not None else timestep) * self.timestep_scale_multiplier
+
+ # When patches in a frame share a timestep (no spatial mask), project one row per frame instead of one per token
+ per_frame_path = v_patches_per_frame is not None and (timestep.numel() // batch_size) % v_patches_per_frame == 0
+ if per_frame_path:
+ per_frame = timestep.reshape(batch_size, -1, v_patches_per_frame)[:, :, 0]
+ if grid_mask is not None:
+ # All-or-nothing per frame when has_spatial_mask=False.
+ per_frame = per_frame[:, grid_mask[::v_patches_per_frame]]
+ ts_input = per_frame * self.timestep_scale_multiplier
+ else:
+ ts_input = timestep_scaled
+
+ v_timestep, v_embedded_timestep = self.adaln_single(
+ ts_input.flatten(),
+ {"resolution": None, "aspect_ratio": None},
+ batch_size=batch_size,
+ hidden_dtype=hidden_dtype,
+ )
+ v_timestep = CompressedTimestep(v_timestep.view(batch_size, -1, v_timestep.shape[-1]), v_patches_per_frame, per_frame=per_frame_path)
+ v_embedded_timestep = CompressedTimestep(v_embedded_timestep.view(batch_size, -1, v_embedded_timestep.shape[-1]), v_patches_per_frame, per_frame=per_frame_path)
+
+ v_prompt_timestep = compute_prompt_timestep(
+ self.prompt_adaln_single, timestep_scaled, batch_size, hidden_dtype
+ )
+
+ # Prepare audio timestep
+ a_timestep = kwargs.get("a_timestep")
+ ref_audio_seq_len = kwargs.get("ref_audio_seq_len", 0)
+ if ref_audio_seq_len > 0 and a_timestep is not None:
+ # Reference tokens must have timestep=0, expand scalar/1D timestep to per-token so ref=0 and target=sigma.
+ target_len = kwargs.get("target_audio_seq_len")
+ if a_timestep.dim() <= 1:
+ a_timestep = a_timestep.view(-1, 1).expand(batch_size, target_len)
+ ref_ts = torch.zeros(batch_size, ref_audio_seq_len, *a_timestep.shape[2:], device=a_timestep.device, dtype=a_timestep.dtype)
+ a_timestep = torch.cat([ref_ts, a_timestep], dim=1)
+ if a_timestep is not None:
+ a_timestep_scaled = a_timestep * self.timestep_scale_multiplier
+ a_timestep_flat = a_timestep_scaled.flatten()
+ timestep_flat = timestep_scaled.flatten()
+ av_ca_factor = self.av_ca_timestep_scale_multiplier / self.timestep_scale_multiplier
+
+ # Cross-attention timesteps - compress these too
+ av_ca_audio_scale_shift_timestep, _ = self.av_ca_audio_scale_shift_adaln_single(
+ a_timestep_flat,
+ {"resolution": None, "aspect_ratio": None},
+ batch_size=batch_size,
+ hidden_dtype=hidden_dtype,
+ )
+ av_ca_video_scale_shift_timestep, _ = self.av_ca_video_scale_shift_adaln_single(
+ timestep_flat,
+ {"resolution": None, "aspect_ratio": None},
+ batch_size=batch_size,
+ hidden_dtype=hidden_dtype,
+ )
+ av_ca_a2v_gate_noise_timestep, _ = self.av_ca_a2v_gate_adaln_single(
+ a_timestep_scaled.max().expand_as(timestep_flat) * av_ca_factor,
+ {"resolution": None, "aspect_ratio": None},
+ batch_size=batch_size,
+ hidden_dtype=hidden_dtype,
+ )
+ av_ca_v2a_gate_noise_timestep, _ = self.av_ca_v2a_gate_adaln_single(
+ timestep_scaled.max().expand_as(a_timestep_flat) * av_ca_factor,
+ {"resolution": None, "aspect_ratio": None},
+ batch_size=batch_size,
+ hidden_dtype=hidden_dtype,
+ )
+
+ # Compress cross-attention timesteps (only video side, audio is too small to benefit)
+ # v_patches_per_frame is None for spatial masks, set for temporal masks or no mask
+ cross_av_timestep_ss = [
+ av_ca_audio_scale_shift_timestep.view(batch_size, -1, av_ca_audio_scale_shift_timestep.shape[-1]),
+ CompressedTimestep(av_ca_video_scale_shift_timestep.view(batch_size, -1, av_ca_video_scale_shift_timestep.shape[-1]), v_patches_per_frame), # video - compressed if possible
+ CompressedTimestep(av_ca_a2v_gate_noise_timestep.view(batch_size, -1, av_ca_a2v_gate_noise_timestep.shape[-1]), v_patches_per_frame), # video - compressed if possible
+ av_ca_v2a_gate_noise_timestep.view(batch_size, -1, av_ca_v2a_gate_noise_timestep.shape[-1]),
+ ]
+
+ a_timestep, a_embedded_timestep = self.audio_adaln_single(
+ a_timestep_flat,
+ {"resolution": None, "aspect_ratio": None},
+ batch_size=batch_size,
+ hidden_dtype=hidden_dtype,
+ )
+ # Audio timesteps
+ a_timestep = a_timestep.view(batch_size, -1, a_timestep.shape[-1])
+ a_embedded_timestep = a_embedded_timestep.view(batch_size, -1, a_embedded_timestep.shape[-1])
+
+ a_prompt_timestep = compute_prompt_timestep(
+ self.audio_prompt_adaln_single, a_timestep_scaled, batch_size, hidden_dtype
+ )
+ else:
+ a_timestep = timestep_scaled
+ a_embedded_timestep = kwargs.get("embedded_timestep")
+ cross_av_timestep_ss = []
+ a_prompt_timestep = None
+
+ return [v_timestep, a_timestep, cross_av_timestep_ss, v_prompt_timestep, a_prompt_timestep], [
+ v_embedded_timestep,
+ a_embedded_timestep,
+ ], None
+
+ def _prepare_context(self, context, batch_size, x, attention_mask=None):
+ vx = x[0]
+ ax = x[1]
+ video_dim = vx.shape[-1]
+ audio_dim = ax.shape[-1]
+
+ v_context_dim = self.caption_channels if self.caption_proj_before_connector is False else video_dim
+ a_context_dim = self.caption_channels if self.caption_proj_before_connector is False else audio_dim
+
+ v_context, a_context = torch.split(
+ context, [v_context_dim, a_context_dim], len(context.shape) - 1
+ )
+
+ v_context, attention_mask = super()._prepare_context(
+ v_context, batch_size, vx, attention_mask
+ )
+ if self.caption_proj_before_connector is False:
+ a_context = self.audio_caption_projection(a_context)
+ a_context = a_context.view(batch_size, -1, audio_dim)
+
+ return [v_context, a_context], attention_mask
+
+ def _prepare_positional_embeddings(self, pixel_coords, frame_rate, x_dtype):
+ v_pixel_coords = pixel_coords[0]
+ v_pe = super()._prepare_positional_embeddings(v_pixel_coords, frame_rate, x_dtype)
+
+ a_latent_coords = pixel_coords[1]
+ a_pe = self._precompute_freqs_cis(
+ a_latent_coords,
+ dim=self.audio_inner_dim,
+ out_dtype=x_dtype,
+ max_pos=self.audio_positional_embedding_max_pos,
+ use_middle_indices_grid=self.use_middle_indices_grid,
+ num_attention_heads=self.audio_num_attention_heads,
+ )
+
+ # calculate positional embeddings for the middle of the token duration, to use in av cross attention layers.
+ max_pos = max(
+ self.positional_embedding_max_pos[0], self.audio_positional_embedding_max_pos[0]
+ )
+ v_pixel_coords = v_pixel_coords.to(torch.float32)
+ v_pixel_coords[:, 0] = v_pixel_coords[:, 0] * (1.0 / frame_rate)
+ av_cross_video_freq_cis = self._precompute_freqs_cis(
+ v_pixel_coords[:, 0:1, :],
+ dim=self.audio_cross_attention_dim,
+ out_dtype=x_dtype,
+ max_pos=[max_pos],
+ use_middle_indices_grid=True,
+ num_attention_heads=self.audio_num_attention_heads,
+ )
+ av_cross_audio_freq_cis = self._precompute_freqs_cis(
+ a_latent_coords[:, 0:1, :],
+ dim=self.audio_cross_attention_dim,
+ out_dtype=x_dtype,
+ max_pos=[max_pos],
+ use_middle_indices_grid=True,
+ num_attention_heads=self.audio_num_attention_heads,
+ )
+
+ return [(v_pe, av_cross_video_freq_cis), (a_pe, av_cross_audio_freq_cis)]
+
+ def _process_transformer_blocks(
+ self, x, context, attention_mask, timestep, pe, transformer_options={}, self_attention_mask=None, **kwargs
+ ):
+ vx = x[0]
+ ax = x[1]
+ v_context = context[0]
+ a_context = context[1]
+ v_timestep = timestep[0]
+ a_timestep = timestep[1]
+ v_pe, av_cross_video_freq_cis = pe[0]
+ a_pe, av_cross_audio_freq_cis = pe[1]
+
+ (
+ av_ca_audio_scale_shift_timestep,
+ av_ca_video_scale_shift_timestep,
+ av_ca_a2v_gate_noise_timestep,
+ av_ca_v2a_gate_noise_timestep,
+ ) = timestep[2]
+
+ v_prompt_timestep = timestep[3]
+ a_prompt_timestep = timestep[4]
+
+ """Process transformer blocks for LTXAV."""
+ patches_replace = transformer_options.get("patches_replace", {})
+ blocks_replace = patches_replace.get("dit", {})
+ prefetch_queue = comfy.model_prefetch.make_prefetch_queue(list(self.transformer_blocks), vx.device, transformer_options)
+
+ # Process transformer blocks
+ for i, block in enumerate(self.transformer_blocks):
+ comfy.model_prefetch.prefetch_queue_pop(prefetch_queue, vx.device, block)
+ if ("double_block", i) in blocks_replace:
+
+ def block_wrap(args):
+ out = {}
+ out["img"] = block(
+ args["img"],
+ v_context=args["v_context"],
+ a_context=args["a_context"],
+ attention_mask=args["attention_mask"],
+ v_timestep=args["v_timestep"],
+ a_timestep=args["a_timestep"],
+ v_pe=args["v_pe"],
+ a_pe=args["a_pe"],
+ v_cross_pe=args["v_cross_pe"],
+ a_cross_pe=args["a_cross_pe"],
+ v_cross_scale_shift_timestep=args["v_cross_scale_shift_timestep"],
+ a_cross_scale_shift_timestep=args["a_cross_scale_shift_timestep"],
+ v_cross_gate_timestep=args["v_cross_gate_timestep"],
+ a_cross_gate_timestep=args["a_cross_gate_timestep"],
+ transformer_options=args["transformer_options"],
+ self_attention_mask=args.get("self_attention_mask"),
+ v_prompt_timestep=args.get("v_prompt_timestep"),
+ a_prompt_timestep=args.get("a_prompt_timestep"),
+ )
+ return out
+
+ out = blocks_replace[("double_block", i)](
+ {
+ "img": (vx, ax),
+ "v_context": v_context,
+ "a_context": a_context,
+ "attention_mask": attention_mask,
+ "v_timestep": v_timestep,
+ "a_timestep": a_timestep,
+ "v_pe": v_pe,
+ "a_pe": a_pe,
+ "v_cross_pe": av_cross_video_freq_cis,
+ "a_cross_pe": av_cross_audio_freq_cis,
+ "v_cross_scale_shift_timestep": av_ca_video_scale_shift_timestep,
+ "a_cross_scale_shift_timestep": av_ca_audio_scale_shift_timestep,
+ "v_cross_gate_timestep": av_ca_a2v_gate_noise_timestep,
+ "a_cross_gate_timestep": av_ca_v2a_gate_noise_timestep,
+ "transformer_options": transformer_options,
+ "self_attention_mask": self_attention_mask,
+ "v_prompt_timestep": v_prompt_timestep,
+ "a_prompt_timestep": a_prompt_timestep,
+ },
+ {"original_block": block_wrap},
+ )
+ vx, ax = out["img"]
+ else:
+ vx, ax = block(
+ (vx, ax),
+ v_context=v_context,
+ a_context=a_context,
+ attention_mask=attention_mask,
+ v_timestep=v_timestep,
+ a_timestep=a_timestep,
+ v_pe=v_pe,
+ a_pe=a_pe,
+ v_cross_pe=av_cross_video_freq_cis,
+ a_cross_pe=av_cross_audio_freq_cis,
+ v_cross_scale_shift_timestep=av_ca_video_scale_shift_timestep,
+ a_cross_scale_shift_timestep=av_ca_audio_scale_shift_timestep,
+ v_cross_gate_timestep=av_ca_a2v_gate_noise_timestep,
+ a_cross_gate_timestep=av_ca_v2a_gate_noise_timestep,
+ transformer_options=transformer_options,
+ self_attention_mask=self_attention_mask,
+ v_prompt_timestep=v_prompt_timestep,
+ a_prompt_timestep=a_prompt_timestep,
+ )
+
+ comfy.model_prefetch.prefetch_queue_pop(prefetch_queue, vx.device, None)
+
+ return [vx, ax]
+
+ def _process_output(self, x, embedded_timestep, keyframe_idxs, **kwargs):
+ vx = x[0]
+ ax = x[1]
+ v_embedded_timestep = embedded_timestep[0]
+ a_embedded_timestep = embedded_timestep[1]
+
+ # Trim reference audio tokens before unpatchification
+ ref_audio_seq_len = kwargs.get("ref_audio_seq_len", 0)
+ if ref_audio_seq_len > 0:
+ ax = ax[:, ref_audio_seq_len:]
+ if a_embedded_timestep.shape[1] > 1:
+ a_embedded_timestep = a_embedded_timestep[:, ref_audio_seq_len:]
+
+ # Expand compressed video timestep if needed
+ if isinstance(v_embedded_timestep, CompressedTimestep):
+ v_embedded_timestep = v_embedded_timestep.expand()
+
+ vx = super()._process_output(vx, v_embedded_timestep, keyframe_idxs, **kwargs)
+
+ # Process audio output
+ a_scale_shift_values = (
+ self.audio_scale_shift_table[None, None].to(device=a_embedded_timestep.device, dtype=a_embedded_timestep.dtype)
+ + a_embedded_timestep[:, :, None]
+ )
+ a_shift, a_scale = a_scale_shift_values[:, :, 0], a_scale_shift_values[:, :, 1]
+
+ ax = self.audio_norm_out(ax)
+ ax = ax * (1 + a_scale) + a_shift
+ ax = self.audio_proj_out(ax)
+
+ # Unpatchify audio
+ ax = self.a_patchifier.unpatchify(
+ ax, channels=self.num_audio_channels, freq=self.audio_frequency_bins
+ )
+
+ # Recombine audio and video
+ original_shape = kwargs.get("av_orig_shape")
+ return self.recombine_audio_and_video_latents(vx, ax, original_shape)
+
+ def forward(
+ self,
+ x,
+ timestep,
+ context,
+ attention_mask=None,
+ frame_rate=25,
+ transformer_options={},
+ keyframe_idxs=None,
+ **kwargs,
+ ):
+ """
+ Forward pass for LTXAV model.
+
+ Args:
+ x: Combined audio-video input tensor
+ timestep: Tuple of (video_timestep, audio_timestep) or single timestep
+ context: Context tensor (e.g., text embeddings)
+ attention_mask: Attention mask tensor
+ frame_rate: Frame rate for temporal processing
+ transformer_options: Additional options for transformer blocks
+ keyframe_idxs: Keyframe indices for temporal processing
+ **kwargs: Additional keyword arguments including audio_length
+
+ Returns:
+ Combined audio-video output tensor
+ """
+ # Handle timestep format
+ if isinstance(timestep, (tuple, list)) and len(timestep) == 2:
+ v_timestep, a_timestep = timestep
+ kwargs["a_timestep"] = a_timestep
+ timestep = v_timestep
+ else:
+ kwargs["a_timestep"] = timestep
+
+ # Call parent forward method
+ return super().forward(
+ x,
+ timestep,
+ context,
+ attention_mask,
+ frame_rate,
+ transformer_options,
+ keyframe_idxs,
+ **kwargs,
+ )
diff --git a/ComfyUI/comfy/ldm/lightricks/embeddings_connector.py b/ComfyUI/comfy/ldm/lightricks/embeddings_connector.py
new file mode 100644
index 0000000000000000000000000000000000000000..1a6ddcc8de9f2fabb7030649a312e3467a41baec
--- /dev/null
+++ b/ComfyUI/comfy/ldm/lightricks/embeddings_connector.py
@@ -0,0 +1,309 @@
+import math
+from typing import Optional
+
+import comfy.ldm.common_dit
+import torch
+from comfy.ldm.lightricks.model import (
+ CrossAttention,
+ FeedForward,
+ freqs_cis_matrix,
+ generate_freq_grid_np,
+)
+from torch import nn
+
+
+class BasicTransformerBlock1D(nn.Module):
+ r"""
+ A basic Transformer block.
+
+ Parameters:
+
+ dim (`int`): The number of channels in the input and output.
+ num_attention_heads (`int`): The number of heads to use for multi-head attention.
+ attention_head_dim (`int`): The number of channels in each head.
+ dropout (`float`, *optional*, defaults to 0.0): The dropout probability to use.
+ activation_fn (`str`, *optional*, defaults to `"geglu"`): Activation function to be used in feed-forward.
+ attention_bias (:
+ obj: `bool`, *optional*, defaults to `False`): Configure if the attentions should contain a bias parameter.
+ upcast_attention (`bool`, *optional*):
+ Whether to upcast the attention computation to float32. This is useful for mixed precision training.
+ norm_elementwise_affine (`bool`, *optional*, defaults to `True`):
+ Whether to use learnable elementwise affine parameters for normalization.
+ standardization_norm (`str`, *optional*, defaults to `"layer_norm"`): The type of pre-normalization to use. Can be `"layer_norm"` or `"rms_norm"`.
+ norm_eps (`float`, *optional*, defaults to 1e-5): Epsilon value for normalization layers.
+ qk_norm (`str`, *optional*, defaults to None):
+ Set to 'layer_norm' or `rms_norm` to perform query and key normalization.
+ final_dropout (`bool` *optional*, defaults to False):
+ Whether to apply a final dropout after the last feed-forward layer.
+ ff_inner_dim (`int`, *optional*): Dimension of the inner feed-forward layer. If not provided, defaults to `dim * 4`.
+ ff_bias (`bool`, *optional*, defaults to `True`): Whether to use bias in the feed-forward layer.
+ attention_out_bias (`bool`, *optional*, defaults to `True`): Whether to use bias in the attention output layer.
+ use_rope (`bool`, *optional*, defaults to `False`): Whether to use Rotary Position Embeddings (RoPE).
+ ffn_dim_mult (`int`, *optional*, defaults to 4): Multiplier for the inner dimension of the feed-forward layer.
+ """
+
+ def __init__(
+ self,
+ dim,
+ n_heads,
+ d_head,
+ context_dim=None,
+ attn_precision=None,
+ apply_gated_attention=False,
+ dtype=None,
+ device=None,
+ operations=None,
+ ):
+ super().__init__()
+
+ # Define 3 blocks. Each block has its own normalization layer.
+ # 1. Self-Attn
+ self.attn1 = CrossAttention(
+ query_dim=dim,
+ heads=n_heads,
+ dim_head=d_head,
+ context_dim=None,
+ apply_gated_attention=apply_gated_attention,
+ dtype=dtype,
+ device=device,
+ operations=operations,
+ )
+
+ # 3. Feed-forward
+ self.ff = FeedForward(
+ dim,
+ dim_out=dim,
+ glu=True,
+ dtype=dtype,
+ device=device,
+ operations=operations,
+ )
+
+ def forward(self, hidden_states, attention_mask=None, pe=None) -> torch.FloatTensor:
+
+ # Notice that normalization is always applied before the real computation in the following blocks.
+
+ # 1. Normalization Before Self-Attention
+ norm_hidden_states = comfy.ldm.common_dit.rms_norm(hidden_states)
+
+ norm_hidden_states = norm_hidden_states.squeeze(1)
+
+ # 2. Self-Attention
+ attn_output = self.attn1(norm_hidden_states, mask=attention_mask, pe=pe)
+
+ hidden_states = attn_output + hidden_states
+ if hidden_states.ndim == 4:
+ hidden_states = hidden_states.squeeze(1)
+
+ # 3. Normalization before Feed-Forward
+ norm_hidden_states = comfy.ldm.common_dit.rms_norm(hidden_states)
+
+ # 4. Feed-forward
+ ff_output = self.ff(norm_hidden_states)
+
+ hidden_states = ff_output + hidden_states
+ if hidden_states.ndim == 4:
+ hidden_states = hidden_states.squeeze(1)
+
+ return hidden_states
+
+
+class Embeddings1DConnector(nn.Module):
+ _supports_gradient_checkpointing = True
+
+ def __init__(
+ self,
+ in_channels=128,
+ cross_attention_dim=2048,
+ attention_head_dim=128,
+ num_attention_heads=30,
+ num_layers=2,
+ positional_embedding_theta=10000.0,
+ positional_embedding_max_pos=[4096],
+ causal_temporal_positioning=False,
+ num_learnable_registers: Optional[int] = 128,
+ apply_gated_attention=False,
+ dtype=None,
+ device=None,
+ operations=None,
+ split_rope=False,
+ double_precision_rope=False,
+ **kwargs,
+ ):
+ super().__init__()
+ self.dtype = dtype
+ self.out_channels = in_channels
+ self.num_attention_heads = num_attention_heads
+ self.inner_dim = num_attention_heads * attention_head_dim
+ self.causal_temporal_positioning = causal_temporal_positioning
+ self.positional_embedding_theta = positional_embedding_theta
+ self.positional_embedding_max_pos = positional_embedding_max_pos
+ self.split_rope = split_rope
+ self.double_precision_rope = double_precision_rope
+ self.transformer_1d_blocks = nn.ModuleList(
+ [
+ BasicTransformerBlock1D(
+ self.inner_dim,
+ num_attention_heads,
+ attention_head_dim,
+ context_dim=cross_attention_dim,
+ apply_gated_attention=apply_gated_attention,
+ dtype=dtype,
+ device=device,
+ operations=operations,
+ )
+ for _ in range(num_layers)
+ ]
+ )
+
+ inner_dim = num_attention_heads * attention_head_dim
+ self.num_learnable_registers = num_learnable_registers
+ if self.num_learnable_registers:
+ self.learnable_registers = nn.Parameter(
+ torch.empty(
+ self.num_learnable_registers, inner_dim, dtype=dtype, device=device
+ )
+ )
+
+ def get_fractional_positions(self, indices_grid):
+ fractional_positions = torch.stack(
+ [
+ indices_grid[:, i] / self.positional_embedding_max_pos[i]
+ for i in range(1)
+ ],
+ dim=-1,
+ )
+ return fractional_positions
+
+ def precompute_freqs(self, indices_grid, spacing):
+ source_dtype = indices_grid.dtype
+ dtype = (
+ torch.float32
+ if source_dtype in (torch.bfloat16, torch.float16)
+ else source_dtype
+ )
+
+ fractional_positions = self.get_fractional_positions(indices_grid)
+ indices = (
+ generate_freq_grid_np(
+ self.positional_embedding_theta,
+ indices_grid.shape[1],
+ self.inner_dim,
+ )
+ if self.double_precision_rope
+ else self.generate_freq_grid(spacing, dtype, fractional_positions.device)
+ ).to(device=fractional_positions.device)
+
+ if spacing == "exp_2":
+ freqs = (
+ (indices * fractional_positions.unsqueeze(-1))
+ .transpose(-1, -2)
+ .flatten(2)
+ )
+ else:
+ freqs = (
+ (indices * (fractional_positions.unsqueeze(-1) * 2 - 1))
+ .transpose(-1, -2)
+ .flatten(2)
+ )
+ return freqs
+
+ def generate_freq_grid(self, spacing, dtype, device):
+ dim = self.inner_dim
+ theta = self.positional_embedding_theta
+ n_pos_dims = 1
+ n_elem = 2 * n_pos_dims # 2 for cos and sin e.g. x 3 = 6
+ start = 1
+ end = theta
+
+ if spacing == "exp":
+ indices = theta ** (torch.arange(0, dim, n_elem, device="cpu", dtype=torch.float32) / (dim - n_elem))
+ indices = indices.to(dtype=dtype, device=device)
+ elif spacing == "exp_2":
+ indices = 1.0 / theta ** (torch.arange(0, dim, n_elem, device=device) / dim)
+ indices = indices.to(dtype=dtype)
+ elif spacing == "linear":
+ indices = torch.linspace(
+ start, end, dim // n_elem, device=device, dtype=dtype
+ )
+ elif spacing == "sqrt":
+ indices = torch.linspace(
+ start**2, end**2, dim // n_elem, device=device, dtype=dtype
+ ).sqrt()
+
+ indices = indices * math.pi / 2
+
+ return indices
+
+ def precompute_freqs_cis(self, indices_grid, spacing="exp", out_dtype=None):
+ dim = self.inner_dim
+ n_elem = 2 # 2 because of cos and sin
+ freqs = self.precompute_freqs(indices_grid, spacing)
+ if self.split_rope:
+ expected_freqs = dim // 2
+ current_freqs = freqs.shape[-1]
+ pad_size = expected_freqs - current_freqs
+ else:
+ pad_size = dim % n_elem
+ return freqs_cis_matrix(
+ freqs,
+ pad_size,
+ self.split_rope,
+ self.num_attention_heads,
+ out_dtype,
+ )
+
+ def forward(
+ self,
+ hidden_states: torch.Tensor,
+ attention_mask: Optional[torch.Tensor] = None,
+ ):
+ """
+ The [`Transformer2DModel`] forward method.
+
+ Args:
+ hidden_states (`torch.LongTensor` of shape `(batch size, num latent pixels)` if discrete, `torch.FloatTensor` of shape `(batch size, channel, height, width)` if continuous):
+ Input `hidden_states`.
+ indices_grid (`torch.LongTensor` of shape `(batch size, 3, num latent pixels)`):
+ attention_mask ( `torch.Tensor`, *optional*):
+ An attention mask of shape `(batch, key_tokens)` is applied to `encoder_hidden_states`. If `1` the mask
+ is kept, otherwise if `0` it is discarded. Mask will be converted into a bias, which adds large
+ negative values to the attention scores corresponding to "discard" tokens.
+ Returns:
+ If `return_dict` is True, an [`~models.transformer_2d.Transformer2DModelOutput`] is returned, otherwise a
+ `tuple` where the first element is the sample tensor.
+ """
+ # 1. Input
+
+ if self.num_learnable_registers:
+ num_registers_duplications = math.ceil(
+ max(1024, hidden_states.shape[1]) / self.num_learnable_registers
+ )
+ learnable_registers = torch.tile(
+ self.learnable_registers.to(hidden_states), (num_registers_duplications, 1)
+ )
+
+ hidden_states = torch.cat((hidden_states, learnable_registers[hidden_states.shape[1]:].unsqueeze(0).repeat(hidden_states.shape[0], 1, 1)), dim=1)
+
+ if attention_mask is not None:
+ attention_mask = torch.zeros([1, 1, 1, hidden_states.shape[1]], dtype=attention_mask.dtype, device=attention_mask.device)
+
+ indices_grid = torch.arange(
+ hidden_states.shape[1], dtype=torch.float32, device=hidden_states.device
+ )
+ indices_grid = indices_grid[None, None, :]
+ freqs_cis = self.precompute_freqs_cis(indices_grid, out_dtype=hidden_states.dtype)
+
+ # 2. Blocks
+ for block_idx, block in enumerate(self.transformer_1d_blocks):
+ hidden_states = block(
+ hidden_states, attention_mask=attention_mask, pe=freqs_cis
+ )
+
+ # 3. Output
+ # if self.output_scale is not None:
+ # hidden_states = hidden_states / self.output_scale
+
+ hidden_states = comfy.ldm.common_dit.rms_norm(hidden_states)
+
+ return hidden_states, attention_mask
diff --git a/ComfyUI/comfy/ldm/lightricks/latent_upsampler.py b/ComfyUI/comfy/ldm/lightricks/latent_upsampler.py
new file mode 100644
index 0000000000000000000000000000000000000000..6a4beb1bf29623d79e993da5bf43abdbbd25b468
--- /dev/null
+++ b/ComfyUI/comfy/ldm/lightricks/latent_upsampler.py
@@ -0,0 +1,297 @@
+from typing import Optional, Tuple
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+from einops import rearrange
+
+
+def _rational_for_scale(scale: float) -> Tuple[int, int]:
+ mapping = {0.75: (3, 4), 1.5: (3, 2), 2.0: (2, 1), 4.0: (4, 1)}
+ if float(scale) not in mapping:
+ raise ValueError(
+ f"Unsupported spatial_scale {scale}. Choose from {list(mapping.keys())}"
+ )
+ return mapping[float(scale)]
+
+
+class PixelShuffleND(nn.Module):
+ def __init__(self, dims, upscale_factors=(2, 2, 2)):
+ super().__init__()
+ assert dims in [1, 2, 3], "dims must be 1, 2, or 3"
+ self.dims = dims
+ self.upscale_factors = upscale_factors
+
+ def forward(self, x):
+ if self.dims == 3:
+ return rearrange(
+ x,
+ "b (c p1 p2 p3) d h w -> b c (d p1) (h p2) (w p3)",
+ p1=self.upscale_factors[0],
+ p2=self.upscale_factors[1],
+ p3=self.upscale_factors[2],
+ )
+ elif self.dims == 2:
+ return rearrange(
+ x,
+ "b (c p1 p2) h w -> b c (h p1) (w p2)",
+ p1=self.upscale_factors[0],
+ p2=self.upscale_factors[1],
+ )
+ elif self.dims == 1:
+ return rearrange(
+ x,
+ "b (c p1) f h w -> b c (f p1) h w",
+ p1=self.upscale_factors[0],
+ )
+
+
+class BlurDownsample(nn.Module):
+ """
+ Anti-aliased spatial downsampling by integer stride using a fixed separable binomial kernel.
+ Applies only on H,W. Works for dims=2 or dims=3 (per-frame).
+ """
+
+ def __init__(self, dims: int, stride: int):
+ super().__init__()
+ assert dims in (2, 3)
+ assert stride >= 1 and isinstance(stride, int)
+ self.dims = dims
+ self.stride = stride
+
+ # 5x5 separable binomial kernel [1,4,6,4,1] (outer product), normalized
+ k = torch.tensor([1.0, 4.0, 6.0, 4.0, 1.0])
+ k2d = k[:, None] @ k[None, :]
+ k2d = (k2d / k2d.sum()).float() # shape (5,5)
+ self.register_buffer("kernel", k2d[None, None, :, :]) # (1,1,5,5)
+
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
+ if self.stride == 1:
+ return x
+
+ def _apply_2d(x2d: torch.Tensor) -> torch.Tensor:
+ # x2d: (B, C, H, W)
+ B, C, H, W = x2d.shape
+ weight = self.kernel.expand(C, 1, 5, 5) # depthwise
+ x2d = F.conv2d(
+ x2d, weight=weight, bias=None, stride=self.stride, padding=2, groups=C
+ )
+ return x2d
+
+ if self.dims == 2:
+ return _apply_2d(x)
+ else:
+ # dims == 3: apply per-frame on H,W
+ b, c, f, h, w = x.shape
+ x = rearrange(x, "b c f h w -> (b f) c h w")
+ x = _apply_2d(x)
+ h2, w2 = x.shape[-2:]
+ x = rearrange(x, "(b f) c h w -> b c f h w", b=b, f=f, h=h2, w=w2)
+ return x
+
+
+class SpatialRationalResampler(nn.Module):
+ """
+ Fully-learned rational spatial scaling: up by 'num' via PixelShuffle, then anti-aliased
+ downsample by 'den' using fixed blur + stride. Operates on H,W only.
+
+ For dims==3, work per-frame for spatial scaling (temporal axis untouched).
+ """
+
+ def __init__(self, mid_channels: int, scale: float, operations):
+ super().__init__()
+ self.scale = float(scale)
+ self.num, self.den = _rational_for_scale(self.scale)
+ self.conv = operations.Conv2d(
+ mid_channels, (self.num**2) * mid_channels, kernel_size=3, padding=1
+ )
+ self.pixel_shuffle = PixelShuffleND(2, upscale_factors=(self.num, self.num))
+ self.blur_down = BlurDownsample(dims=2, stride=self.den)
+
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
+ b, c, f, h, w = x.shape
+ x = rearrange(x, "b c f h w -> (b f) c h w")
+ x = self.conv(x)
+ x = self.pixel_shuffle(x)
+ x = self.blur_down(x)
+ x = rearrange(x, "(b f) c h w -> b c f h w", b=b, f=f)
+ return x
+
+
+class ResBlock(nn.Module):
+ def __init__(
+ self, channels: int, operations, mid_channels: Optional[int] = None, dims: int = 3
+ ):
+ super().__init__()
+ if mid_channels is None:
+ mid_channels = channels
+
+ Conv = operations.Conv2d if dims == 2 else operations.Conv3d
+
+ self.conv1 = Conv(channels, mid_channels, kernel_size=3, padding=1)
+ self.norm1 = operations.GroupNorm(32, mid_channels)
+ self.conv2 = Conv(mid_channels, channels, kernel_size=3, padding=1)
+ self.norm2 = operations.GroupNorm(32, channels)
+ self.activation = nn.SiLU()
+
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
+ residual = x
+ x = self.conv1(x)
+ x = self.norm1(x)
+ x = self.activation(x)
+ x = self.conv2(x)
+ x = self.norm2(x)
+ x = self.activation(x + residual)
+ return x
+
+
+class LatentUpsampler(nn.Module):
+ """
+ Model to spatially upsample VAE latents.
+
+ Args:
+ in_channels (`int`): Number of channels in the input latent
+ mid_channels (`int`): Number of channels in the middle layers
+ num_blocks_per_stage (`int`): Number of ResBlocks to use in each stage (pre/post upsampling)
+ dims (`int`): Number of dimensions for convolutions (2 or 3)
+ spatial_upsample (`bool`): Whether to spatially upsample the latent
+ temporal_upsample (`bool`): Whether to temporally upsample the latent
+ """
+
+ def __init__(
+ self,
+ operations,
+ in_channels: int = 128,
+ mid_channels: int = 512,
+ num_blocks_per_stage: int = 4,
+ dims: int = 3,
+ spatial_upsample: bool = True,
+ temporal_upsample: bool = False,
+ spatial_scale: float = 2.0,
+ rational_resampler: bool = False,
+ ):
+ super().__init__()
+
+ self.in_channels = in_channels
+ self.mid_channels = mid_channels
+ self.num_blocks_per_stage = num_blocks_per_stage
+ self.dims = dims
+ self.spatial_upsample = spatial_upsample
+ self.temporal_upsample = temporal_upsample
+ self.spatial_scale = float(spatial_scale)
+ self.rational_resampler = rational_resampler
+
+ Conv = operations.Conv2d if dims == 2 else operations.Conv3d
+
+ self.initial_conv = Conv(in_channels, mid_channels, kernel_size=3, padding=1)
+ self.initial_norm = operations.GroupNorm(32, mid_channels)
+ self.initial_activation = nn.SiLU()
+
+ self.res_blocks = nn.ModuleList(
+ [ResBlock(mid_channels, dims=dims, operations=operations) for _ in range(num_blocks_per_stage)]
+ )
+
+ if spatial_upsample and temporal_upsample:
+ self.upsampler = nn.Sequential(
+ operations.Conv3d(mid_channels, 8 * mid_channels, kernel_size=3, padding=1),
+ PixelShuffleND(3),
+ )
+ elif spatial_upsample:
+ if rational_resampler:
+ self.upsampler = SpatialRationalResampler(
+ mid_channels=mid_channels, scale=self.spatial_scale, operations=operations
+ )
+ else:
+ self.upsampler = nn.Sequential(
+ operations.Conv2d(mid_channels, 4 * mid_channels, kernel_size=3, padding=1),
+ PixelShuffleND(2),
+ )
+ elif temporal_upsample:
+ self.upsampler = nn.Sequential(
+ operations.Conv3d(mid_channels, 2 * mid_channels, kernel_size=3, padding=1),
+ PixelShuffleND(1),
+ )
+ else:
+ raise ValueError(
+ "Either spatial_upsample or temporal_upsample must be True"
+ )
+
+ self.post_upsample_res_blocks = nn.ModuleList(
+ [ResBlock(mid_channels, dims=dims, operations=operations) for _ in range(num_blocks_per_stage)]
+ )
+
+ self.final_conv = Conv(mid_channels, in_channels, kernel_size=3, padding=1)
+
+ def get_dtype(self):
+ return getattr(self.initial_conv, "weight_comfy_model_dtype", self.initial_conv.weight.dtype)
+
+ def forward(self, latent: torch.Tensor) -> torch.Tensor:
+ b, c, f, h, w = latent.shape
+
+ if self.dims == 2:
+ x = rearrange(latent, "b c f h w -> (b f) c h w")
+ x = self.initial_conv(x)
+ x = self.initial_norm(x)
+ x = self.initial_activation(x)
+
+ for block in self.res_blocks:
+ x = block(x)
+
+ x = self.upsampler(x)
+
+ for block in self.post_upsample_res_blocks:
+ x = block(x)
+
+ x = self.final_conv(x)
+ x = rearrange(x, "(b f) c h w -> b c f h w", b=b, f=f)
+ else:
+ x = self.initial_conv(latent)
+ x = self.initial_norm(x)
+ x = self.initial_activation(x)
+
+ for block in self.res_blocks:
+ x = block(x)
+
+ if self.temporal_upsample:
+ x = self.upsampler(x)
+ x = x[:, :, 1:, :, :]
+ else:
+ if isinstance(self.upsampler, SpatialRationalResampler):
+ x = self.upsampler(x)
+ else:
+ x = rearrange(x, "b c f h w -> (b f) c h w")
+ x = self.upsampler(x)
+ x = rearrange(x, "(b f) c h w -> b c f h w", b=b, f=f)
+
+ for block in self.post_upsample_res_blocks:
+ x = block(x)
+
+ x = self.final_conv(x)
+
+ return x
+
+ @classmethod
+ def from_config(cls, config, operations):
+ return cls(
+ in_channels=config.get("in_channels", 4),
+ mid_channels=config.get("mid_channels", 128),
+ num_blocks_per_stage=config.get("num_blocks_per_stage", 4),
+ dims=config.get("dims", 2),
+ spatial_upsample=config.get("spatial_upsample", True),
+ temporal_upsample=config.get("temporal_upsample", False),
+ spatial_scale=config.get("spatial_scale", 2.0),
+ rational_resampler=config.get("rational_resampler", False),
+ operations=operations,
+ )
+
+ def config(self):
+ return {
+ "_class_name": "LatentUpsampler",
+ "in_channels": self.in_channels,
+ "mid_channels": self.mid_channels,
+ "num_blocks_per_stage": self.num_blocks_per_stage,
+ "dims": self.dims,
+ "spatial_upsample": self.spatial_upsample,
+ "temporal_upsample": self.temporal_upsample,
+ "spatial_scale": self.spatial_scale,
+ "rational_resampler": self.rational_resampler,
+ }
diff --git a/ComfyUI/comfy/ldm/lightricks/model.py b/ComfyUI/comfy/ldm/lightricks/model.py
new file mode 100644
index 0000000000000000000000000000000000000000..f9de3a38e24f6fe5ea7ae6652844a56a9eefc56f
--- /dev/null
+++ b/ComfyUI/comfy/ldm/lightricks/model.py
@@ -0,0 +1,1349 @@
+from abc import ABC, abstractmethod
+from enum import Enum
+import functools
+import logging
+import math
+from typing import Dict, Optional, Tuple
+
+from einops import rearrange
+import numpy as np
+import torch
+from torch import nn
+import comfy.patcher_extension
+import comfy.ldm.modules.attention
+import comfy.ldm.common_dit
+import comfy.model_management
+import comfy.quant_ops
+
+from .symmetric_patchifier import SymmetricPatchifier, latent_to_pixel_coords
+
+logger = logging.getLogger(__name__)
+
+def _log_base(x, base):
+ return np.log(x) / np.log(base)
+
+class LTXRopeType(str, Enum):
+ INTERLEAVED = "interleaved"
+ SPLIT = "split"
+
+ KEY = "rope_type"
+
+ @classmethod
+ def from_dict(cls, kwargs, default=None):
+ if default is None:
+ default = cls.INTERLEAVED
+ return cls(kwargs.get(cls.KEY, default))
+
+
+class LTXFrequenciesPrecision(str, Enum):
+ FLOAT32 = "float32"
+ FLOAT64 = "float64"
+
+ KEY = "frequencies_precision"
+
+ @classmethod
+ def from_dict(cls, kwargs, default=None):
+ if default is None:
+ default = cls.FLOAT32
+ return cls(kwargs.get(cls.KEY, default))
+
+
+def get_timestep_embedding(
+ timesteps: torch.Tensor,
+ embedding_dim: int,
+ flip_sin_to_cos: bool = False,
+ downscale_freq_shift: float = 1,
+ scale: float = 1,
+ max_period: int = 10000,
+):
+ """
+ This matches the implementation in Denoising Diffusion Probabilistic Models: Create sinusoidal timestep embeddings.
+
+ Args
+ timesteps (torch.Tensor):
+ a 1-D Tensor of N indices, one per batch element. These may be fractional.
+ embedding_dim (int):
+ the dimension of the output.
+ flip_sin_to_cos (bool):
+ Whether the embedding order should be `cos, sin` (if True) or `sin, cos` (if False)
+ downscale_freq_shift (float):
+ Controls the delta between frequencies between dimensions
+ scale (float):
+ Scaling factor applied to the embeddings.
+ max_period (int):
+ Controls the maximum frequency of the embeddings
+ Returns
+ torch.Tensor: an [N x dim] Tensor of positional embeddings.
+ """
+ assert len(timesteps.shape) == 1, "Timesteps should be a 1d-array"
+
+ half_dim = embedding_dim // 2
+ exponent = -math.log(max_period) * torch.arange(start=0, end=half_dim, dtype=torch.float32, device=timesteps.device)
+ exponent = exponent / (half_dim - downscale_freq_shift)
+
+ emb = torch.exp(exponent)
+ emb = timesteps[:, None].float() * emb[None, :]
+
+ # scale embeddings
+ emb = scale * emb
+
+ # concat sine and cosine embeddings
+ emb = torch.cat([torch.sin(emb), torch.cos(emb)], dim=-1)
+
+ # flip sine and cosine embeddings
+ if flip_sin_to_cos:
+ emb = torch.cat([emb[:, half_dim:], emb[:, :half_dim]], dim=-1)
+
+ # zero pad
+ if embedding_dim % 2 == 1:
+ emb = torch.nn.functional.pad(emb, (0, 1, 0, 0))
+ return emb
+
+
+class TimestepEmbedding(nn.Module):
+ def __init__(
+ self,
+ in_channels: int,
+ time_embed_dim: int,
+ act_fn: str = "silu",
+ out_dim: int = None,
+ post_act_fn: Optional[str] = None,
+ cond_proj_dim=None,
+ sample_proj_bias=True,
+ dtype=None,
+ device=None,
+ operations=None,
+ ):
+ super().__init__()
+
+ self.linear_1 = operations.Linear(in_channels, time_embed_dim, sample_proj_bias, dtype=dtype, device=device)
+
+ if cond_proj_dim is not None:
+ self.cond_proj = operations.Linear(cond_proj_dim, in_channels, bias=False, dtype=dtype, device=device)
+ else:
+ self.cond_proj = None
+
+ self.act = nn.SiLU()
+
+ if out_dim is not None:
+ time_embed_dim_out = out_dim
+ else:
+ time_embed_dim_out = time_embed_dim
+ self.linear_2 = operations.Linear(
+ time_embed_dim, time_embed_dim_out, sample_proj_bias, dtype=dtype, device=device
+ )
+
+ if post_act_fn is None:
+ self.post_act = None
+ # else:
+ # self.post_act = get_activation(post_act_fn)
+
+ def forward(self, sample, condition=None):
+ if condition is not None:
+ sample = sample + self.cond_proj(condition)
+ sample = self.linear_1(sample)
+
+ if self.act is not None:
+ sample = self.act(sample)
+
+ sample = self.linear_2(sample)
+
+ if self.post_act is not None:
+ sample = self.post_act(sample)
+ return sample
+
+
+class Timesteps(nn.Module):
+ def __init__(self, num_channels: int, flip_sin_to_cos: bool, downscale_freq_shift: float, scale: int = 1):
+ super().__init__()
+ self.num_channels = num_channels
+ self.flip_sin_to_cos = flip_sin_to_cos
+ self.downscale_freq_shift = downscale_freq_shift
+ self.scale = scale
+
+ def forward(self, timesteps):
+ t_emb = get_timestep_embedding(
+ timesteps,
+ self.num_channels,
+ flip_sin_to_cos=self.flip_sin_to_cos,
+ downscale_freq_shift=self.downscale_freq_shift,
+ scale=self.scale,
+ )
+ return t_emb
+
+
+class PixArtAlphaCombinedTimestepSizeEmbeddings(nn.Module):
+ """
+ For PixArt-Alpha.
+
+ Reference:
+ https://github.com/PixArt-alpha/PixArt-alpha/blob/0f55e922376d8b797edd44d25d0e7464b260dcab/diffusion/model/nets/PixArtMS.py#L164C9-L168C29
+ """
+
+ def __init__(
+ self,
+ embedding_dim,
+ size_emb_dim,
+ use_additional_conditions: bool = False,
+ dtype=None,
+ device=None,
+ operations=None,
+ ):
+ super().__init__()
+
+ self.outdim = size_emb_dim
+ self.time_proj = Timesteps(num_channels=256, flip_sin_to_cos=True, downscale_freq_shift=0)
+ self.timestep_embedder = TimestepEmbedding(
+ in_channels=256, time_embed_dim=embedding_dim, dtype=dtype, device=device, operations=operations
+ )
+
+ def forward(self, timestep, resolution, aspect_ratio, batch_size, hidden_dtype):
+ timesteps_proj = self.time_proj(timestep)
+ timesteps_emb = self.timestep_embedder(timesteps_proj.to(dtype=hidden_dtype)) # (N, D)
+ return timesteps_emb
+
+
+class AdaLayerNormSingle(nn.Module):
+ r"""
+ Norm layer adaptive layer norm single (adaLN-single).
+
+ As proposed in PixArt-Alpha (see: https://arxiv.org/abs/2310.00426; Section 2.3).
+
+ Parameters:
+ embedding_dim (`int`): The size of each embedding vector.
+ use_additional_conditions (`bool`): To use additional conditions for normalization or not.
+ """
+
+ def __init__(
+ self, embedding_dim: int, embedding_coefficient: int = 6, use_additional_conditions: bool = False, dtype=None, device=None, operations=None
+ ):
+ super().__init__()
+
+ self.emb = PixArtAlphaCombinedTimestepSizeEmbeddings(
+ embedding_dim,
+ size_emb_dim=embedding_dim // 3,
+ use_additional_conditions=use_additional_conditions,
+ dtype=dtype,
+ device=device,
+ operations=operations,
+ )
+
+ self.silu = nn.SiLU()
+ self.linear = operations.Linear(embedding_dim, embedding_coefficient * embedding_dim, bias=True, dtype=dtype, device=device)
+
+ def forward(
+ self,
+ timestep: torch.Tensor,
+ added_cond_kwargs: Optional[Dict[str, torch.Tensor]] = None,
+ batch_size: Optional[int] = None,
+ hidden_dtype: Optional[torch.dtype] = None,
+ ) -> Tuple[torch.Tensor, torch.Tensor, torch.Tensor, torch.Tensor, torch.Tensor]:
+ # No modulation happening here.
+ added_cond_kwargs = added_cond_kwargs or {"resolution": None, "aspect_ratio": None}
+ embedded_timestep = self.emb(timestep, **added_cond_kwargs, batch_size=batch_size, hidden_dtype=hidden_dtype)
+ return self.linear(self.silu(embedded_timestep)), embedded_timestep
+
+
+class PixArtAlphaTextProjection(nn.Module):
+ """
+ Projects caption embeddings. Also handles dropout for classifier-free guidance.
+
+ Adapted from https://github.com/PixArt-alpha/PixArt-alpha/blob/master/diffusion/model/nets/PixArt_blocks.py
+ """
+
+ def __init__(
+ self, in_features, hidden_size, out_features=None, act_fn="gelu_tanh", dtype=None, device=None, operations=None
+ ):
+ super().__init__()
+ if out_features is None:
+ out_features = hidden_size
+ self.linear_1 = operations.Linear(
+ in_features=in_features, out_features=hidden_size, bias=True, dtype=dtype, device=device
+ )
+ if act_fn == "gelu_tanh":
+ self.act_1 = nn.GELU(approximate="tanh")
+ elif act_fn == "silu":
+ self.act_1 = nn.SiLU()
+ else:
+ raise ValueError(f"Unknown activation function: {act_fn}")
+ self.linear_2 = operations.Linear(
+ in_features=hidden_size, out_features=out_features, bias=True, dtype=dtype, device=device
+ )
+
+ def forward(self, caption):
+ hidden_states = self.linear_1(caption)
+ hidden_states = self.act_1(hidden_states)
+ hidden_states = self.linear_2(hidden_states)
+ return hidden_states
+
+
+class NormSingleLinearTextProjection(nn.Module):
+ """Text projection for 20B models - single linear with RMSNorm (no activation)."""
+
+ def __init__(
+ self, in_features, hidden_size, dtype=None, device=None, operations=None
+ ):
+ super().__init__()
+ if operations is None:
+ operations = comfy.ops.disable_weight_init
+ self.in_norm = operations.RMSNorm(
+ in_features, eps=1e-6, elementwise_affine=False
+ )
+ self.linear_1 = operations.Linear(
+ in_features, hidden_size, bias=True, dtype=dtype, device=device
+ )
+ self.hidden_size = hidden_size
+ self.in_features = in_features
+
+ def forward(self, caption):
+ caption = self.in_norm(caption)
+ caption = caption * (self.hidden_size / self.in_features) ** 0.5
+ return self.linear_1(caption)
+
+
+class GELU_approx(nn.Module):
+ def __init__(self, dim_in, dim_out, dtype=None, device=None, operations=None):
+ super().__init__()
+ self.proj = operations.Linear(dim_in, dim_out, dtype=dtype, device=device)
+
+ def forward(self, x):
+ return torch.nn.functional.gelu(self.proj(x), approximate="tanh")
+
+
+class FeedForward(nn.Module):
+ def __init__(self, dim, dim_out, mult=4, glu=False, dropout=0.0, dtype=None, device=None, operations=None):
+ super().__init__()
+ inner_dim = int(dim * mult)
+ project_in = GELU_approx(dim, inner_dim, dtype=dtype, device=device, operations=operations)
+
+ self.net = nn.Sequential(
+ project_in, nn.Dropout(dropout), operations.Linear(inner_dim, dim_out, dtype=dtype, device=device)
+ )
+
+ def forward(self, x):
+ return self.net(x)
+
+def apply_rotary_emb(input_tensor, freqs_cis):
+ rotation_matrix, split_pe = freqs_cis
+ original_shape = input_tensor.shape
+ input_tensor = input_tensor.reshape(
+ input_tensor.shape[0], input_tensor.shape[1], rotation_matrix.shape[2], -1
+ )
+
+ if comfy.model_management.in_training:
+ if split_pe:
+ t = input_tensor.reshape(*input_tensor.shape[:-1], 2, -1).movedim(-2, -1).unsqueeze(-2)
+ else:
+ t = input_tensor.reshape(*input_tensor.shape[:-1], -1, 1, 2)
+ t = t.to(rotation_matrix.dtype)
+ output = rotation_matrix[..., 0] * t[..., 0] + rotation_matrix[..., 1] * t[..., 1]
+ if split_pe:
+ output = output.movedim(-1, -2)
+ output = output.reshape(input_tensor.shape).type_as(input_tensor)
+ elif split_pe:
+ output = comfy.quant_ops.ck.apply_rope_split_half1(input_tensor, rotation_matrix)
+ else:
+ output = comfy.quant_ops.ck.apply_rope1(input_tensor, rotation_matrix)
+ return output.reshape(original_shape)
+
+def apply_rotary_emb_qk(q, k, freqs_cis):
+ if comfy.model_management.in_training:
+ return apply_rotary_emb(q, freqs_cis), apply_rotary_emb(k, freqs_cis)
+
+ rotation_matrix, split_pe = freqs_cis
+ q_shape = q.shape
+ k_shape = k.shape
+ q = q.reshape(q.shape[0], q.shape[1], rotation_matrix.shape[2], -1)
+ k = k.reshape(k.shape[0], k.shape[1], rotation_matrix.shape[2], -1)
+ if split_pe:
+ q, k = comfy.quant_ops.ck.apply_rope_split_half(q, k, rotation_matrix)
+ else:
+ q, k = comfy.quant_ops.ck.apply_rope(q, k, rotation_matrix)
+ return q.reshape(q_shape), k.reshape(k_shape)
+
+
+class GuideAttentionMask:
+ """Holds the two per-group masks for LTXV guide self-attention.
+ _attention_with_guide_mask splits queries into noisy and tracked-guide
+ groups, so the largest mask is (1, 1, tracked_count, T).
+ """
+ __slots__ = ("guide_start", "tracked_count", "noisy_mask", "tracked_mask")
+
+ def __init__(self, total_tokens, guide_start, tracked_count, tracked_weights):
+ device = tracked_weights.device
+ dtype = tracked_weights.dtype
+ finfo = torch.finfo(dtype)
+
+ pos = tracked_weights > 0
+ log_w = torch.full_like(tracked_weights, finfo.min)
+ log_w[pos] = torch.log(tracked_weights[pos].clamp(min=finfo.tiny))
+
+ self.guide_start = guide_start
+ self.tracked_count = tracked_count
+
+ self.noisy_mask = torch.zeros((1, 1, 1, total_tokens), device=device, dtype=dtype)
+ self.noisy_mask[:, :, :, guide_start:guide_start + tracked_count] = log_w.view(1, 1, 1, -1)
+
+ self.tracked_mask = torch.zeros((1, 1, tracked_count, total_tokens), device=device, dtype=dtype)
+ self.tracked_mask[:, :, :, :guide_start] = log_w.view(1, 1, -1, 1)
+
+
+def _attention_with_guide_mask(q, k, v, heads, guide_mask, attn_precision, transformer_options):
+ """Apply the guide mask by partitioning Q into noisy and tracked-guide
+ groups, so each group needs only its own sub-mask. Avoids materializing
+ the (1,1,T,T) dense mask.
+ """
+ guide_start = guide_mask.guide_start
+ tracked_end = guide_start + guide_mask.tracked_count
+
+ out = torch.empty_like(q)
+
+ if guide_start > 0: # In practice currently guides are always after noise, guard for safety if this changes.
+ out[:, :guide_start, :] = comfy.ldm.modules.attention.optimized_attention(
+ q[:, :guide_start, :], k, v, heads, mask=guide_mask.noisy_mask,
+ attn_precision=attn_precision, transformer_options=transformer_options,
+ low_precision_attention=False, # sageattn mask support is unreliable
+ )
+ out[:, guide_start:tracked_end, :] = comfy.ldm.modules.attention.optimized_attention(
+ q[:, guide_start:tracked_end, :], k, v, heads, mask=guide_mask.tracked_mask,
+ attn_precision=attn_precision, transformer_options=transformer_options,
+ low_precision_attention=False,
+ )
+ if tracked_end < q.shape[1]: # Every guide token is tracked, and nothing comes after them, guard for safety if this changes.
+ out[:, tracked_end:, :] = comfy.ldm.modules.attention.optimized_attention(
+ q[:, tracked_end:, :], k, v, heads,
+ attn_precision=attn_precision, transformer_options=transformer_options,
+ )
+ return out
+
+
+class CrossAttention(nn.Module):
+ def __init__(
+ self,
+ query_dim,
+ context_dim=None,
+ heads=8,
+ dim_head=64,
+ dropout=0.0,
+ attn_precision=None,
+ apply_gated_attention=False,
+ dtype=None,
+ device=None,
+ operations=None,
+ ):
+ super().__init__()
+ inner_dim = dim_head * heads
+ context_dim = query_dim if context_dim is None else context_dim
+ self.attn_precision = attn_precision
+
+ self.heads = heads
+ self.dim_head = dim_head
+
+ self.q_norm = operations.RMSNorm(inner_dim, eps=1e-5, dtype=dtype, device=device)
+ self.k_norm = operations.RMSNorm(inner_dim, eps=1e-5, dtype=dtype, device=device)
+
+ self.to_q = operations.Linear(query_dim, inner_dim, bias=True, dtype=dtype, device=device)
+ self.to_k = operations.Linear(context_dim, inner_dim, bias=True, dtype=dtype, device=device)
+ self.to_v = operations.Linear(context_dim, inner_dim, bias=True, dtype=dtype, device=device)
+
+ # Optional per-head gating
+ if apply_gated_attention:
+ self.to_gate_logits = operations.Linear(query_dim, heads, bias=True, dtype=dtype, device=device)
+ else:
+ self.to_gate_logits = None
+
+ self.to_out = nn.Sequential(
+ operations.Linear(inner_dim, query_dim, dtype=dtype, device=device), nn.Dropout(dropout)
+ )
+
+ def forward(self, x, context=None, mask=None, pe=None, k_pe=None, transformer_options={}):
+ q = self.to_q(x)
+ context = x if context is None else context
+ k = self.to_k(context)
+ v = self.to_v(context)
+
+ q = self.q_norm(q)
+ k = self.k_norm(k)
+
+ # These norms span all heads, so the per-head RMS+RoPE kernel is not equivalent.
+ if pe is not None:
+ if k_pe is None and q.shape == k.shape:
+ q, k = apply_rotary_emb_qk(q, k, pe)
+ else:
+ q = apply_rotary_emb(q, pe)
+ k = apply_rotary_emb(k, pe if k_pe is None else k_pe)
+
+ if mask is None:
+ out = comfy.ldm.modules.attention.optimized_attention(q, k, v, self.heads, attn_precision=self.attn_precision, transformer_options=transformer_options)
+ elif isinstance(mask, GuideAttentionMask):
+ out = _attention_with_guide_mask(q, k, v, self.heads, mask, attn_precision=self.attn_precision, transformer_options=transformer_options)
+ else:
+ out = comfy.ldm.modules.attention.optimized_attention(q, k, v, self.heads, mask=mask, attn_precision=self.attn_precision, transformer_options=transformer_options)
+
+ # Apply per-head gating if enabled
+ if self.to_gate_logits is not None:
+ gate_logits = self.to_gate_logits(x) # (B, T, H)
+ b, t, _ = out.shape
+ out = out.view(b, t, self.heads, self.dim_head)
+ gates = 2.0 * torch.sigmoid(gate_logits) # zero-init -> identity
+ out = out * gates.unsqueeze(-1)
+ out = out.view(b, t, self.heads * self.dim_head)
+
+ return self.to_out(out)
+
+# 6 base ADaLN params (shift/scale/gate for MSA + MLP), +3 for cross-attention Q (shift/scale/gate)
+ADALN_BASE_PARAMS_COUNT = 6
+ADALN_CROSS_ATTN_PARAMS_COUNT = 9
+
+class BasicTransformerBlock(nn.Module):
+ def __init__(
+ self, dim, n_heads, d_head, context_dim=None, attn_precision=None, cross_attention_adaln=False, dtype=None, device=None, operations=None
+ ):
+ super().__init__()
+
+ self.attn_precision = attn_precision
+ self.cross_attention_adaln = cross_attention_adaln
+ self.attn1 = CrossAttention(
+ query_dim=dim,
+ heads=n_heads,
+ dim_head=d_head,
+ context_dim=None,
+ attn_precision=self.attn_precision,
+ dtype=dtype,
+ device=device,
+ operations=operations,
+ )
+ self.ff = FeedForward(dim, dim_out=dim, glu=True, dtype=dtype, device=device, operations=operations)
+
+ self.attn2 = CrossAttention(
+ query_dim=dim,
+ context_dim=context_dim,
+ heads=n_heads,
+ dim_head=d_head,
+ attn_precision=self.attn_precision,
+ dtype=dtype,
+ device=device,
+ operations=operations,
+ )
+
+ num_ada_params = ADALN_CROSS_ATTN_PARAMS_COUNT if cross_attention_adaln else ADALN_BASE_PARAMS_COUNT
+ self.scale_shift_table = nn.Parameter(torch.empty(num_ada_params, dim, device=device, dtype=dtype))
+
+ if cross_attention_adaln:
+ self.prompt_scale_shift_table = nn.Parameter(torch.empty(2, dim, device=device, dtype=dtype))
+
+ def forward(self, x, context=None, attention_mask=None, timestep=None, pe=None, transformer_options={}, self_attention_mask=None, prompt_timestep=None):
+ shift_msa, scale_msa, gate_msa, shift_mlp, scale_mlp, gate_mlp = (self.scale_shift_table[None, None, :6].to(device=x.device, dtype=x.dtype) + timestep.reshape(x.shape[0], timestep.shape[1], self.scale_shift_table.shape[0], -1)[:, :, :6, :]).unbind(dim=2)
+
+ x += self.attn1(comfy.ldm.common_dit.rms_norm(x) * (1 + scale_msa) + shift_msa, pe=pe, mask=self_attention_mask, transformer_options=transformer_options) * gate_msa
+
+ if self.cross_attention_adaln:
+ shift_q_mca, scale_q_mca, gate_mca = (self.scale_shift_table[None, None, 6:9].to(device=x.device, dtype=x.dtype) + timestep.reshape(x.shape[0], timestep.shape[1], self.scale_shift_table.shape[0], -1)[:, :, 6:9, :]).unbind(dim=2)
+ x += apply_cross_attention_adaln(
+ x, context, self.attn2, shift_q_mca, scale_q_mca, gate_mca,
+ self.prompt_scale_shift_table, prompt_timestep, attention_mask, transformer_options,
+ )
+ else:
+ x += self.attn2(x, context=context, mask=attention_mask, transformer_options=transformer_options)
+
+ y = comfy.ldm.common_dit.rms_norm(x)
+ y = torch.addcmul(y, y, scale_mlp).add_(shift_mlp)
+ x.addcmul_(self.ff(y), gate_mlp)
+
+ return x
+
+def compute_prompt_timestep(adaln_module, timestep_scaled, batch_size, hidden_dtype):
+ """Compute a single global prompt timestep for cross-attention ADaLN.
+
+ Uses the max across tokens (matching JAX max_per_segment) and broadcasts
+ over text tokens. Returns None when *adaln_module* is None.
+ """
+ if adaln_module is None:
+ return None
+ ts_input = (
+ timestep_scaled.max(dim=1, keepdim=True).values.flatten()
+ if timestep_scaled.dim() > 1
+ else timestep_scaled.flatten()
+ )
+ prompt_ts, _ = adaln_module(
+ ts_input,
+ {"resolution": None, "aspect_ratio": None},
+ batch_size=batch_size,
+ hidden_dtype=hidden_dtype,
+ )
+ return prompt_ts.view(batch_size, 1, prompt_ts.shape[-1])
+
+
+def apply_cross_attention_adaln(
+ x, context, attn, q_shift, q_scale, q_gate,
+ prompt_scale_shift_table, prompt_timestep,
+ attention_mask=None, transformer_options={},
+):
+ """Apply cross-attention with ADaLN modulation (shift/scale/gate on Q and KV).
+
+ Q params (q_shift, q_scale, q_gate) are pre-extracted by the caller so
+ that both regular tensors and CompressedTimestep are supported.
+ """
+ batch_size = x.shape[0]
+ shift_kv, scale_kv = (
+ prompt_scale_shift_table[None, None].to(device=x.device, dtype=x.dtype)
+ + prompt_timestep.reshape(batch_size, prompt_timestep.shape[1], 2, -1)
+ ).unbind(dim=2)
+ attn_input = comfy.ldm.common_dit.rms_norm(x) * (1 + q_scale) + q_shift
+ encoder_hidden_states = context * (1 + scale_kv) + shift_kv
+ return attn(attn_input, context=encoder_hidden_states, mask=attention_mask, transformer_options=transformer_options) * q_gate
+
+def get_fractional_positions(indices_grid, max_pos):
+ n_pos_dims = indices_grid.shape[1]
+ assert n_pos_dims == len(max_pos), f'Number of position dimensions ({n_pos_dims}) must match max_pos length ({len(max_pos)})'
+ fractional_positions = torch.stack(
+ [indices_grid[:, i] / max_pos[i] for i in range(n_pos_dims)],
+ axis=-1,
+ )
+ return fractional_positions
+
+
+@functools.lru_cache(maxsize=5)
+def generate_freq_grid_np(positional_embedding_theta, positional_embedding_max_pos_count, inner_dim, _ = None):
+ theta = positional_embedding_theta
+ start = 1
+ end = theta
+
+ n_elem = 2 * positional_embedding_max_pos_count
+ pow_indices = np.power(
+ theta,
+ np.linspace(
+ _log_base(start, theta),
+ _log_base(end, theta),
+ inner_dim // n_elem,
+ dtype=np.float64,
+ ),
+ )
+ return torch.tensor(pow_indices * math.pi / 2, dtype=torch.float32)
+
+def generate_freq_grid_pytorch(positional_embedding_theta, positional_embedding_max_pos_count, inner_dim, device):
+ theta = positional_embedding_theta
+ start = 1
+ end = theta
+ n_elem = 2 * positional_embedding_max_pos_count
+
+ indices = theta ** (
+ torch.linspace(
+ math.log(start, theta),
+ math.log(end, theta),
+ inner_dim // n_elem,
+ device=device,
+ dtype=torch.float32,
+ )
+ )
+ indices = indices.to(dtype=torch.float32)
+
+ indices = indices * math.pi / 2
+
+ return indices
+
+def generate_freqs(indices, indices_grid, max_pos, use_middle_indices_grid):
+ if use_middle_indices_grid:
+ assert(len(indices_grid.shape) == 4 and indices_grid.shape[-1] ==2)
+ indices_grid_start, indices_grid_end = indices_grid[..., 0], indices_grid[..., 1]
+ indices_grid = (indices_grid_start + indices_grid_end) / 2.0
+ elif len(indices_grid.shape) == 4:
+ indices_grid = indices_grid[..., 0]
+
+ # Get fractional positions and compute frequency indices
+ fractional_positions = get_fractional_positions(indices_grid, max_pos)
+ indices = indices.to(device=fractional_positions.device)
+
+ freqs = (
+ (indices * (fractional_positions.unsqueeze(-1) * 2 - 1))
+ .transpose(-1, -2)
+ .flatten(2)
+ )
+ return freqs
+
+def freqs_cis_matrix(freqs, pad_size, split_mode, num_attention_heads, out_dtype):
+ cos_freq = freqs.cos().to(out_dtype)
+ sin_freq = freqs.sin().to(out_dtype)
+ if pad_size:
+ matrix_pad_size = pad_size if split_mode else pad_size // 2
+ cos_padding = torch.ones_like(cos_freq[:, :, :matrix_pad_size])
+ sin_padding = torch.zeros_like(sin_freq[:, :, :matrix_pad_size])
+ cos_freq = torch.cat((cos_padding, cos_freq), dim=-1)
+ sin_freq = torch.cat((sin_padding, sin_freq), dim=-1)
+
+ B, T, half_HD = cos_freq.shape
+ cos_freq = cos_freq.reshape(B, T, num_attention_heads, half_HD // num_attention_heads)
+ sin_freq = sin_freq.reshape(B, T, num_attention_heads, half_HD // num_attention_heads)
+ rotation_matrix = torch.stack(
+ (cos_freq, -sin_freq, sin_freq, cos_freq), dim=-1
+ )
+ return rotation_matrix.reshape(*rotation_matrix.shape[:-1], 2, 2), split_mode
+
+class LTXBaseModel(torch.nn.Module, ABC):
+ """
+ Abstract base class for LTX models (Lightricks Transformer models).
+
+ This class defines the common interface and shared functionality for all LTX models,
+ including LTXV (video) and LTXAV (audio-video) variants.
+ """
+
+ def __init__(
+ self,
+ in_channels: int,
+ cross_attention_dim: int,
+ attention_head_dim: int,
+ num_attention_heads: int,
+ caption_channels: int,
+ num_layers: int,
+ positional_embedding_theta: float = 10000.0,
+ positional_embedding_max_pos: list = [20, 2048, 2048],
+ causal_temporal_positioning: bool = False,
+ vae_scale_factors: tuple = (8, 32, 32),
+ use_middle_indices_grid=False,
+ timestep_scale_multiplier = 1000.0,
+ caption_proj_before_connector=False,
+ cross_attention_adaln=False,
+ caption_projection_first_linear=True,
+ dtype=None,
+ device=None,
+ operations=None,
+ **kwargs,
+ ):
+ super().__init__()
+ self.generator = None
+ self.vae_scale_factors = vae_scale_factors
+ self.use_middle_indices_grid = use_middle_indices_grid
+ self.dtype = dtype
+ self.in_channels = in_channels
+ self.cross_attention_dim = cross_attention_dim
+ self.attention_head_dim = attention_head_dim
+ self.num_attention_heads = num_attention_heads
+ self.caption_channels = caption_channels
+ self.num_layers = num_layers
+ self.positional_embedding_theta = positional_embedding_theta
+ self.positional_embedding_max_pos = positional_embedding_max_pos
+ self.split_positional_embedding = LTXRopeType.from_dict(kwargs)
+ self.freq_grid_generator = (
+ generate_freq_grid_np if LTXFrequenciesPrecision.from_dict(kwargs) == LTXFrequenciesPrecision.FLOAT64
+ else generate_freq_grid_pytorch
+ )
+ self.causal_temporal_positioning = causal_temporal_positioning
+ self.operations = operations
+ self.timestep_scale_multiplier = timestep_scale_multiplier
+ self.caption_proj_before_connector = caption_proj_before_connector
+ self.cross_attention_adaln = cross_attention_adaln
+ self.caption_projection_first_linear = caption_projection_first_linear
+
+ # Common dimensions
+ self.inner_dim = num_attention_heads * attention_head_dim
+ self.out_channels = in_channels
+
+ # Initialize common components
+ self._init_common_components(device, dtype)
+
+ # Initialize model-specific components
+ self._init_model_components(device, dtype, **kwargs)
+
+ # Initialize transformer blocks
+ self._init_transformer_blocks(device, dtype, **kwargs)
+
+ # Initialize output components
+ self._init_output_components(device, dtype)
+
+ def _init_common_components(self, device, dtype):
+ """Initialize components common to all LTX models
+ - patchify_proj: Linear projection for patchifying input
+ - adaln_single: AdaLN layer for timestep embedding
+ - caption_projection: Linear projection for caption embedding
+ """
+ self.patchify_proj = self.operations.Linear(
+ self.in_channels, self.inner_dim, bias=True, dtype=dtype, device=device
+ )
+
+ embedding_coefficient = ADALN_CROSS_ATTN_PARAMS_COUNT if self.cross_attention_adaln else ADALN_BASE_PARAMS_COUNT
+ self.adaln_single = AdaLayerNormSingle(
+ self.inner_dim, embedding_coefficient=embedding_coefficient, use_additional_conditions=False, dtype=dtype, device=device, operations=self.operations
+ )
+
+ if self.cross_attention_adaln:
+ self.prompt_adaln_single = AdaLayerNormSingle(
+ self.inner_dim, embedding_coefficient=2, use_additional_conditions=False, dtype=dtype, device=device, operations=self.operations
+ )
+ else:
+ self.prompt_adaln_single = None
+
+ if self.caption_proj_before_connector:
+ if self.caption_projection_first_linear:
+ self.caption_projection = NormSingleLinearTextProjection(
+ in_features=self.caption_channels,
+ hidden_size=self.inner_dim,
+ dtype=dtype,
+ device=device,
+ operations=self.operations,
+ )
+ else:
+ self.caption_projection = lambda a: a
+ else:
+ self.caption_projection = PixArtAlphaTextProjection(
+ in_features=self.caption_channels,
+ hidden_size=self.inner_dim,
+ dtype=dtype,
+ device=device,
+ operations=self.operations,
+ )
+
+ @abstractmethod
+ def _init_model_components(self, device, dtype, **kwargs):
+ """Initialize model-specific components. Must be implemented by subclasses."""
+ pass
+
+ @abstractmethod
+ def _init_transformer_blocks(self, device, dtype, **kwargs):
+ """Initialize transformer blocks. Must be implemented by subclasses."""
+ pass
+
+ @abstractmethod
+ def _init_output_components(self, device, dtype):
+ """Initialize output components. Must be implemented by subclasses."""
+ pass
+
+ @abstractmethod
+ def _process_input(self, x, keyframe_idxs, denoise_mask, **kwargs):
+ """Process input data. Must be implemented by subclasses."""
+ pass
+
+ def _build_guide_self_attention_mask(self, x, transformer_options, merged_args):
+ """Build self-attention mask for per-guide attention attenuation.
+
+ Base implementation returns None (no attenuation). Subclasses that
+ support guide-based attention control should override this.
+ """
+ return None
+
+ @abstractmethod
+ def _process_transformer_blocks(self, x, context, attention_mask, timestep, pe, self_attention_mask=None, **kwargs):
+ """Process transformer blocks. Must be implemented by subclasses."""
+ pass
+
+ @abstractmethod
+ def _process_output(self, x, embedded_timestep, keyframe_idxs, **kwargs):
+ """Process output data. Must be implemented by subclasses."""
+ pass
+
+ def _prepare_timestep(self, timestep, batch_size, hidden_dtype, **kwargs):
+ """Prepare timestep embeddings."""
+ grid_mask = kwargs.get("grid_mask", None)
+ if grid_mask is not None:
+ timestep = timestep[:, grid_mask]
+
+ timestep_scaled = timestep * self.timestep_scale_multiplier
+ timestep, embedded_timestep = self.adaln_single(
+ timestep_scaled.flatten(),
+ {"resolution": None, "aspect_ratio": None},
+ batch_size=batch_size,
+ hidden_dtype=hidden_dtype,
+ )
+
+ # Second dimension is 1 or number of tokens (if timestep_per_token)
+ timestep = timestep.view(batch_size, -1, timestep.shape[-1])
+ embedded_timestep = embedded_timestep.view(batch_size, -1, embedded_timestep.shape[-1])
+
+ prompt_timestep = compute_prompt_timestep(
+ self.prompt_adaln_single, timestep_scaled, batch_size, hidden_dtype
+ )
+
+ return timestep, embedded_timestep, prompt_timestep
+
+ def _prepare_context(self, context, batch_size, x, attention_mask=None):
+ """Prepare context for transformer blocks."""
+ if self.caption_proj_before_connector is False:
+ context = self.caption_projection(context)
+
+ context = context.view(batch_size, -1, x.shape[-1])
+ return context, attention_mask
+
+ def _precompute_freqs_cis(
+ self,
+ indices_grid,
+ dim,
+ out_dtype,
+ theta=10000.0,
+ max_pos=[20, 2048, 2048],
+ use_middle_indices_grid=False,
+ num_attention_heads=32,
+ ):
+ split_mode = self.split_positional_embedding == LTXRopeType.SPLIT
+ indices = self.freq_grid_generator(theta, indices_grid.shape[1], dim, indices_grid.device)
+ freqs = generate_freqs(indices, indices_grid, max_pos, use_middle_indices_grid)
+
+ if split_mode:
+ expected_freqs = dim // 2
+ current_freqs = freqs.shape[-1]
+ pad_size = expected_freqs - current_freqs
+ else:
+ # 2 because of cos and sin by 3 for (t, x, y), 1 for temporal only
+ n_elem = 2 * indices_grid.shape[1]
+ pad_size = dim % n_elem
+ return freqs_cis_matrix(
+ freqs,
+ pad_size,
+ split_mode,
+ num_attention_heads,
+ out_dtype,
+ )
+
+ def _prepare_positional_embeddings(self, pixel_coords, frame_rate, x_dtype):
+ """Prepare positional embeddings."""
+ fractional_coords = pixel_coords.to(torch.float32)
+ fractional_coords[:, 0] = fractional_coords[:, 0] * (1.0 / frame_rate)
+ pe = self._precompute_freqs_cis(
+ fractional_coords,
+ dim=self.inner_dim,
+ out_dtype=x_dtype,
+ max_pos=self.positional_embedding_max_pos,
+ use_middle_indices_grid=self.use_middle_indices_grid,
+ num_attention_heads=self.num_attention_heads,
+ )
+ return pe
+
+ def _prepare_attention_mask(self, attention_mask, x_dtype):
+ """Prepare attention mask."""
+ if attention_mask is not None and not torch.is_floating_point(attention_mask):
+ attention_mask = (attention_mask - 1).to(x_dtype).reshape(
+ (attention_mask.shape[0], 1, -1, attention_mask.shape[-1])
+ ) * torch.finfo(x_dtype).max
+ return attention_mask
+
+ def forward(
+ self, x, timestep, context, attention_mask, frame_rate=25, transformer_options={}, keyframe_idxs=None, denoise_mask=None, **kwargs
+ ):
+ """
+ Forward pass for LTX models.
+
+ Args:
+ x: Input tensor
+ timestep: Timestep tensor
+ context: Context tensor (e.g., text embeddings)
+ attention_mask: Attention mask tensor
+ frame_rate: Frame rate for temporal processing
+ transformer_options: Additional options for transformer blocks
+ keyframe_idxs: Keyframe indices for temporal processing
+ **kwargs: Additional keyword arguments
+
+ Returns:
+ Processed output tensor
+ """
+ return comfy.patcher_extension.WrapperExecutor.new_class_executor(
+ self._forward,
+ self,
+ comfy.patcher_extension.get_all_wrappers(
+ comfy.patcher_extension.WrappersMP.DIFFUSION_MODEL, transformer_options
+ ),
+ ).execute(x, timestep, context, attention_mask, frame_rate, transformer_options, keyframe_idxs, denoise_mask=denoise_mask, **kwargs)
+
+ def _forward(
+ self, x, timestep, context, attention_mask, frame_rate=25, transformer_options={}, keyframe_idxs=None, denoise_mask=None, **kwargs
+ ):
+ """
+ Internal forward pass for LTX models.
+
+ Args:
+ x: Input tensor
+ timestep: Timestep tensor
+ context: Context tensor (e.g., text embeddings)
+ attention_mask: Attention mask tensor
+ frame_rate: Frame rate for temporal processing
+ transformer_options: Additional options for transformer blocks
+ keyframe_idxs: Keyframe indices for temporal processing
+ **kwargs: Additional keyword arguments
+
+ Returns:
+ Processed output tensor
+ """
+ if isinstance(x, list):
+ input_dtype = x[0].dtype
+ batch_size = x[0].shape[0]
+ else:
+ input_dtype = x.dtype
+ batch_size = x.shape[0]
+ # Process input
+ merged_args = {**transformer_options, **kwargs}
+ x, pixel_coords, additional_args = self._process_input(x, keyframe_idxs, denoise_mask, **merged_args)
+ merged_args.update(additional_args)
+
+ # Prepare timestep and context
+ timestep, embedded_timestep, prompt_timestep = self._prepare_timestep(timestep, batch_size, input_dtype, **merged_args)
+ merged_args["prompt_timestep"] = prompt_timestep
+ context, attention_mask = self._prepare_context(context, batch_size, x, attention_mask)
+
+ # Prepare attention mask and positional embeddings
+ attention_mask = self._prepare_attention_mask(attention_mask, input_dtype)
+ pe = self._prepare_positional_embeddings(pixel_coords, frame_rate, input_dtype)
+
+ # Build self-attention mask for per-guide attenuation
+ self_attention_mask = self._build_guide_self_attention_mask(
+ x, transformer_options, merged_args
+ )
+
+ # Process transformer blocks
+ x = self._process_transformer_blocks(
+ x, context, attention_mask, timestep, pe,
+ transformer_options=transformer_options,
+ self_attention_mask=self_attention_mask,
+ **merged_args,
+ )
+
+ # Process output
+ x = self._process_output(x, embedded_timestep, keyframe_idxs, **merged_args)
+ return x
+
+
+class LTXVModel(LTXBaseModel):
+ """LTXV model for video generation."""
+
+ def __init__(
+ self,
+ in_channels=128,
+ cross_attention_dim=2048,
+ attention_head_dim=64,
+ num_attention_heads=32,
+ caption_channels=4096,
+ num_layers=28,
+ positional_embedding_theta=10000.0,
+ positional_embedding_max_pos=[20, 2048, 2048],
+ causal_temporal_positioning=False,
+ vae_scale_factors=(8, 32, 32),
+ use_middle_indices_grid=False,
+ timestep_scale_multiplier=1000.0,
+ caption_proj_before_connector=False,
+ cross_attention_adaln=False,
+ dtype=None,
+ device=None,
+ operations=None,
+ **kwargs,
+ ):
+ super().__init__(
+ in_channels=in_channels,
+ cross_attention_dim=cross_attention_dim,
+ attention_head_dim=attention_head_dim,
+ num_attention_heads=num_attention_heads,
+ caption_channels=caption_channels,
+ num_layers=num_layers,
+ positional_embedding_theta=positional_embedding_theta,
+ positional_embedding_max_pos=positional_embedding_max_pos,
+ causal_temporal_positioning=causal_temporal_positioning,
+ vae_scale_factors=vae_scale_factors,
+ use_middle_indices_grid=use_middle_indices_grid,
+ timestep_scale_multiplier=timestep_scale_multiplier,
+ caption_proj_before_connector=caption_proj_before_connector,
+ cross_attention_adaln=cross_attention_adaln,
+ dtype=dtype,
+ device=device,
+ operations=operations,
+ **kwargs,
+ )
+
+ def _init_model_components(self, device, dtype, **kwargs):
+ """Initialize LTXV-specific components."""
+ pass
+
+ def _init_transformer_blocks(self, device, dtype, **kwargs):
+ """Initialize transformer blocks for LTXV."""
+ self.transformer_blocks = nn.ModuleList(
+ [
+ BasicTransformerBlock(
+ self.inner_dim,
+ self.num_attention_heads,
+ self.attention_head_dim,
+ context_dim=self.cross_attention_dim,
+ cross_attention_adaln=self.cross_attention_adaln,
+ dtype=dtype,
+ device=device,
+ operations=self.operations,
+ )
+ for _ in range(self.num_layers)
+ ]
+ )
+
+ def _init_output_components(self, device, dtype):
+ """Initialize output components for LTXV."""
+ self.scale_shift_table = nn.Parameter(torch.empty(2, self.inner_dim, dtype=dtype, device=device))
+ self.norm_out = self.operations.LayerNorm(
+ self.inner_dim, elementwise_affine=False, eps=1e-6, dtype=dtype, device=device
+ )
+ self.proj_out = self.operations.Linear(self.inner_dim, self.out_channels, dtype=dtype, device=device)
+ self.patchifier = SymmetricPatchifier(1, start_end=True)
+
+ def _process_input(self, x, keyframe_idxs, denoise_mask, **kwargs):
+ """Process input for LTXV."""
+ additional_args = {"orig_shape": list(x.shape)}
+ x, latent_coords = self.patchifier.patchify(x)
+ pixel_coords = latent_to_pixel_coords(
+ latent_coords=latent_coords,
+ scale_factors=self.vae_scale_factors,
+ causal_fix=self.causal_temporal_positioning,
+ )
+
+ grid_mask = None
+ if keyframe_idxs is not None and keyframe_idxs.shape[2] > 0:
+ additional_args.update({ "orig_patchified_shape": list(x.shape)})
+ denoise_mask = self.patchifier.patchify(denoise_mask)[0]
+ grid_mask = ~torch.any(denoise_mask < 0, dim=-1)[0]
+ additional_args.update({"grid_mask": grid_mask})
+ x = x[:, grid_mask, :]
+ pixel_coords = pixel_coords[:, :, grid_mask, ...]
+
+ kf_grid_mask = grid_mask[-keyframe_idxs.shape[2]:]
+
+ # Compute per-guide surviving token counts from guide_attention_entries.
+ # Each entry tracks one guide reference; they are appended in order and
+ # their pre_filter_counts partition the kf_grid_mask.
+ guide_entries = kwargs.get("guide_attention_entries", None)
+ if guide_entries:
+ total_pfc = sum(e["pre_filter_count"] for e in guide_entries)
+ if total_pfc != len(kf_grid_mask):
+ raise ValueError(
+ f"guide pre_filter_counts ({total_pfc}) != "
+ f"keyframe grid mask length ({len(kf_grid_mask)})"
+ )
+ resolved_entries = []
+ offset = 0
+ for entry in guide_entries:
+ pfc = entry["pre_filter_count"]
+ entry_mask = kf_grid_mask[offset:offset + pfc]
+ surviving = int(entry_mask.sum().item())
+ resolved_entries.append({
+ **entry,
+ "surviving_count": surviving,
+ })
+ offset += pfc
+ additional_args["resolved_guide_entries"] = resolved_entries
+
+ keyframe_idxs = keyframe_idxs[..., kf_grid_mask, :]
+
+ if keyframe_idxs.shape[2] > 0: # Guard for the case of no keyframes surviving
+ pixel_coords[:, :, -keyframe_idxs.shape[2]:, :] = keyframe_idxs
+
+ # Total surviving guide tokens (all guides)
+ additional_args["num_guide_tokens"] = keyframe_idxs.shape[2]
+
+ x = self.patchify_proj(x)
+ return x, pixel_coords, additional_args
+
+ def _build_guide_self_attention_mask(self, x, transformer_options, merged_args):
+ """Build self-attention mask for per-guide attention attenuation.
+
+ Reads resolved_guide_entries from merged_args (computed in _process_input)
+ to build a log-space additive bias mask that attenuates noisy ↔ guide
+ attention for each guide reference independently.
+
+ Returns None if no attenuation is needed (all strengths == 1.0 and no
+ spatial masks, or no guide tokens).
+ """
+ if isinstance(x, list):
+ # AV model: x = [vx, ax]; use vx for token count and device
+ total_tokens = x[0].shape[1]
+ device = x[0].device
+ dtype = x[0].dtype
+ else:
+ total_tokens = x.shape[1]
+ device = x.device
+ dtype = x.dtype
+
+ num_guide_tokens = merged_args.get("num_guide_tokens", 0)
+ if num_guide_tokens == 0:
+ return None
+
+ resolved_entries = merged_args.get("resolved_guide_entries", None)
+ if not resolved_entries:
+ return None
+
+ # strength != 1.0 means we want to either attenuate (< 1) or amplify (> 1) guide attention.
+ needs_mask = any(
+ e["strength"] != 1.0 or e.get("pixel_mask") is not None
+ for e in resolved_entries
+ )
+ if not needs_mask:
+ return None
+
+ # Build per-guide-token weights for all tracked guide tokens.
+ # Guides are appended in order at the end of the sequence.
+ guide_start = total_tokens - num_guide_tokens
+ all_weights = []
+ total_tracked = 0
+
+ for entry in resolved_entries:
+ surviving = entry["surviving_count"]
+ if surviving == 0:
+ continue
+
+ strength = entry["strength"]
+ pixel_mask = entry.get("pixel_mask")
+ latent_shape = entry.get("latent_shape")
+
+ if pixel_mask is not None and latent_shape is not None:
+ f_lat, h_lat, w_lat = latent_shape
+ per_token = self._downsample_mask_to_latent(
+ pixel_mask.to(device=device, dtype=dtype),
+ f_lat, h_lat, w_lat,
+ )
+ # per_token shape: (B, f_lat*h_lat*w_lat).
+ # Collapse batch dim — the mask is assumed identical across the
+ # batch; validate and take the first element to get (1, tokens).
+ if per_token.shape[0] > 1:
+ ref = per_token[0]
+ for bi in range(1, per_token.shape[0]):
+ if not torch.equal(ref, per_token[bi]):
+ logger.warning(
+ "pixel_mask differs across batch elements; "
+ "using first element only."
+ )
+ break
+ per_token = per_token[:1]
+ # `surviving` is the post-grid_mask token count.
+ # Clamp to surviving to handle any mismatch safely.
+ n_weights = min(per_token.shape[1], surviving)
+ weights = per_token[:, :n_weights] * strength # (1, n_weights)
+ else:
+ weights = torch.full(
+ (1, surviving), strength, device=device, dtype=dtype
+ )
+
+ all_weights.append(weights)
+ total_tracked += weights.shape[1]
+
+ if not all_weights:
+ return None
+
+ # Concatenate per-token weights for all tracked guides
+ tracked_weights = torch.cat(all_weights, dim=1) # (1, total_tracked)
+
+ # Skip when every weight is exactly 1.0 (additive bias would be 0).
+ if (tracked_weights == 1.0).all():
+ return None
+
+ return GuideAttentionMask(total_tokens, guide_start, total_tracked, tracked_weights)
+
+ @staticmethod
+ def _downsample_mask_to_latent(mask, f_lat, h_lat, w_lat):
+ """Downsample a pixel-space mask to per-token latent weights.
+
+ Args:
+ mask: (B, 1, F_pix, H_pix, W_pix) pixel-space mask with values in [0, 1].
+ f_lat: Number of latent frames (pre-dilation original count).
+ h_lat: Latent height (pre-dilation original height).
+ w_lat: Latent width (pre-dilation original width).
+
+ Returns:
+ (B, F_lat * H_lat * W_lat) flattened per-token weights.
+ """
+ b = mask.shape[0]
+ f_pix = mask.shape[2]
+
+ # Spatial downsampling: area interpolation per frame
+ spatial_down = torch.nn.functional.interpolate(
+ rearrange(mask, "b 1 f h w -> (b f) 1 h w"),
+ size=(h_lat, w_lat),
+ mode="area",
+ )
+ spatial_down = rearrange(spatial_down, "(b f) 1 h w -> b 1 f h w", b=b)
+
+ # Temporal downsampling: first pixel frame maps to first latent frame,
+ # remaining pixel frames are averaged in groups for causal temporal structure.
+ first_frame = spatial_down[:, :, :1, :, :]
+ if f_pix > 1 and f_lat > 1:
+ remaining_pix = f_pix - 1
+ remaining_lat = f_lat - 1
+ t = remaining_pix // remaining_lat
+ if t < 1:
+ # Fewer pixel frames than latent frames — upsample by repeating
+ # the available pixel frames via nearest interpolation.
+ rest_flat = rearrange(
+ spatial_down[:, :, 1:, :, :],
+ "b 1 f h w -> (b h w) 1 f",
+ )
+ rest_up = torch.nn.functional.interpolate(
+ rest_flat, size=remaining_lat, mode="nearest",
+ )
+ rest = rearrange(
+ rest_up, "(b h w) 1 f -> b 1 f h w",
+ b=b, h=h_lat, w=w_lat,
+ )
+ else:
+ # Trim trailing pixel frames that don't fill a complete group
+ usable = remaining_lat * t
+ rest = rearrange(
+ spatial_down[:, :, 1:1 + usable, :, :],
+ "b 1 (f t) h w -> b 1 f t h w",
+ t=t,
+ )
+ rest = rest.mean(dim=3)
+ latent_mask = torch.cat([first_frame, rest], dim=2)
+ elif f_lat > 1:
+ # Single pixel frame but multiple latent frames — repeat the
+ # single frame across all latent frames.
+ latent_mask = first_frame.expand(-1, -1, f_lat, -1, -1)
+ else:
+ latent_mask = first_frame
+
+ return rearrange(latent_mask, "b 1 f h w -> b (f h w)")
+
+ def _process_transformer_blocks(self, x, context, attention_mask, timestep, pe, transformer_options={}, self_attention_mask=None, **kwargs):
+ """Process transformer blocks for LTXV."""
+ patches_replace = transformer_options.get("patches_replace", {})
+ blocks_replace = patches_replace.get("dit", {})
+ prompt_timestep = kwargs.get("prompt_timestep", None)
+
+ for i, block in enumerate(self.transformer_blocks):
+ if ("double_block", i) in blocks_replace:
+
+ def block_wrap(args):
+ out = {}
+ out["img"] = block(args["img"], context=args["txt"], attention_mask=args["attention_mask"], timestep=args["vec"], pe=args["pe"], transformer_options=args["transformer_options"], self_attention_mask=args.get("self_attention_mask"), prompt_timestep=args.get("prompt_timestep"))
+ return out
+
+ out = blocks_replace[("double_block", i)]({"img": x, "txt": context, "attention_mask": attention_mask, "vec": timestep, "pe": pe, "transformer_options": transformer_options, "self_attention_mask": self_attention_mask, "prompt_timestep": prompt_timestep}, {"original_block": block_wrap})
+ x = out["img"]
+ else:
+ x = block(
+ x,
+ context=context,
+ attention_mask=attention_mask,
+ timestep=timestep,
+ pe=pe,
+ transformer_options=transformer_options,
+ self_attention_mask=self_attention_mask,
+ prompt_timestep=prompt_timestep,
+ )
+
+ return x
+
+ def _process_output(self, x, embedded_timestep, keyframe_idxs, **kwargs):
+ """Process output for LTXV."""
+ # Apply scale-shift modulation
+ scale_shift_values = (
+ self.scale_shift_table[None, None].to(device=x.device, dtype=x.dtype) + embedded_timestep[:, :, None]
+ )
+ shift, scale = scale_shift_values[:, :, 0], scale_shift_values[:, :, 1]
+
+ x = self.norm_out(x)
+ x = x * (1 + scale) + shift
+ x = self.proj_out(x)
+
+ if keyframe_idxs is not None and keyframe_idxs.shape[2] > 0:
+ grid_mask = kwargs["grid_mask"]
+ orig_patchified_shape = kwargs["orig_patchified_shape"]
+ full_x = torch.zeros(orig_patchified_shape, dtype=x.dtype, device=x.device)
+ full_x[:, grid_mask, :] = x
+ x = full_x
+ # Unpatchify to restore original dimensions
+ orig_shape = kwargs["orig_shape"]
+ x = self.patchifier.unpatchify(
+ latents=x,
+ output_height=orig_shape[3],
+ output_width=orig_shape[4],
+ output_num_frames=orig_shape[2],
+ out_channels=orig_shape[1] // math.prod(self.patchifier.patch_size),
+ )
+
+ return x
diff --git a/ComfyUI/comfy/ldm/lightricks/symmetric_patchifier.py b/ComfyUI/comfy/ldm/lightricks/symmetric_patchifier.py
new file mode 100644
index 0000000000000000000000000000000000000000..8f9a41186bf773cab756b95223b6fa46bfb940ba
--- /dev/null
+++ b/ComfyUI/comfy/ldm/lightricks/symmetric_patchifier.py
@@ -0,0 +1,190 @@
+from abc import ABC, abstractmethod
+from typing import Tuple
+
+import torch
+from einops import rearrange
+from torch import Tensor
+
+
+def latent_to_pixel_coords(
+ latent_coords: Tensor, scale_factors: Tuple[int, int, int], causal_fix: bool = False
+) -> Tensor:
+ """
+ Converts latent coordinates to pixel coordinates by scaling them according to the VAE's
+ configuration.
+ Args:
+ latent_coords (Tensor): A tensor of shape [batch_size, 3, num_latents]
+ containing the latent corner coordinates of each token.
+ scale_factors (Tuple[int, int, int]): The scale factors of the VAE's latent space.
+ causal_fix (bool): Whether to take into account the different temporal scale
+ of the first frame. Default = False for backwards compatibility.
+ Returns:
+ Tensor: A tensor of pixel coordinates corresponding to the input latent coordinates.
+ """
+ shape = [1] * latent_coords.ndim
+ shape[1] = -1
+ pixel_coords = (
+ latent_coords
+ * torch.tensor(scale_factors, device=latent_coords.device).view(*shape)
+ )
+ if causal_fix:
+ # Fix temporal scale for first frame to 1 due to causality
+ pixel_coords[:, 0, ...] = (pixel_coords[:, 0, ...] + 1 - scale_factors[0]).clamp(min=0)
+ return pixel_coords
+
+
+class Patchifier(ABC):
+ def __init__(self, patch_size: int, start_end: bool=False):
+ super().__init__()
+ self._patch_size = (1, patch_size, patch_size)
+ self.start_end = start_end
+
+ @abstractmethod
+ def patchify(
+ self, latents: Tensor, frame_rates: Tensor, scale_grid: bool
+ ) -> Tuple[Tensor, Tensor]:
+ pass
+
+ @abstractmethod
+ def unpatchify(
+ self,
+ latents: Tensor,
+ output_height: int,
+ output_width: int,
+ output_num_frames: int,
+ out_channels: int,
+ ) -> Tuple[Tensor, Tensor]:
+ pass
+
+ @property
+ def patch_size(self):
+ return self._patch_size
+
+ def get_latent_coords(
+ self, latent_num_frames, latent_height, latent_width, batch_size, device
+ ):
+ """
+ Return a tensor of shape [batch_size, 3, num_patches] containing the
+ top-left corner latent coordinates of each latent patch.
+ The tensor is repeated for each batch element.
+ """
+ latent_sample_coords = torch.meshgrid(
+ torch.arange(0, latent_num_frames, self._patch_size[0], device=device),
+ torch.arange(0, latent_height, self._patch_size[1], device=device),
+ torch.arange(0, latent_width, self._patch_size[2], device=device),
+ indexing="ij",
+ )
+ latent_sample_coords_start = torch.stack(latent_sample_coords, dim=0)
+ delta = torch.tensor(self._patch_size, device=latent_sample_coords_start.device, dtype=latent_sample_coords_start.dtype)[:, None, None, None]
+ latent_sample_coords_end = latent_sample_coords_start + delta
+
+ latent_sample_coords_start = latent_sample_coords_start.unsqueeze(0).repeat(batch_size, 1, 1, 1, 1)
+ latent_sample_coords_start = rearrange(
+ latent_sample_coords_start, "b c f h w -> b c (f h w)", b=batch_size
+ )
+ if self.start_end:
+ latent_sample_coords_end = latent_sample_coords_end.unsqueeze(0).repeat(batch_size, 1, 1, 1, 1)
+ latent_sample_coords_end = rearrange(
+ latent_sample_coords_end, "b c f h w -> b c (f h w)", b=batch_size
+ )
+
+ latent_coords = torch.stack((latent_sample_coords_start, latent_sample_coords_end), dim=-1)
+ else:
+ latent_coords = latent_sample_coords_start
+ return latent_coords
+
+
+class SymmetricPatchifier(Patchifier):
+ def patchify(
+ self,
+ latents: Tensor,
+ ) -> Tuple[Tensor, Tensor]:
+ b, _, f, h, w = latents.shape
+ latent_coords = self.get_latent_coords(f, h, w, b, latents.device)
+ latents = rearrange(
+ latents,
+ "b c (f p1) (h p2) (w p3) -> b (f h w) (c p1 p2 p3)",
+ p1=self._patch_size[0],
+ p2=self._patch_size[1],
+ p3=self._patch_size[2],
+ )
+ return latents, latent_coords
+
+ def unpatchify(
+ self,
+ latents: Tensor,
+ output_height: int,
+ output_width: int,
+ output_num_frames: int,
+ out_channels: int,
+ ) -> Tuple[Tensor, Tensor]:
+ output_height = output_height // self._patch_size[1]
+ output_width = output_width // self._patch_size[2]
+ latents = rearrange(
+ latents,
+ "b (f h w) (c p q) -> b c f (h p) (w q) ",
+ f=output_num_frames,
+ h=output_height,
+ w=output_width,
+ p=self._patch_size[1],
+ q=self._patch_size[2],
+ )
+ return latents
+
+
+class AudioPatchifier(Patchifier):
+ def __init__(self, patch_size: int,
+ sample_rate=16000,
+ hop_length=160,
+ audio_latent_downsample_factor=4,
+ is_causal=True,
+ start_end=False,
+ shift = 0
+ ):
+ super().__init__(patch_size, start_end=start_end)
+ self.hop_length = hop_length
+ self.sample_rate = sample_rate
+ self.audio_latent_downsample_factor = audio_latent_downsample_factor
+ self.is_causal = is_causal
+ self.shift = shift
+
+ def copy_with_shift(self, shift):
+ return AudioPatchifier(
+ self.patch_size, self.sample_rate, self.hop_length, self.audio_latent_downsample_factor,
+ self.is_causal, self.start_end, shift
+ )
+
+ def _get_audio_latent_time_in_sec(self, start_latent, end_latent: int, dtype: torch.dtype, device=torch.device):
+ audio_latent_frame = torch.arange(start_latent, end_latent, dtype=dtype, device=device)
+ audio_mel_frame = audio_latent_frame * self.audio_latent_downsample_factor
+ if self.is_causal:
+ audio_mel_frame = (audio_mel_frame + 1 - self.audio_latent_downsample_factor).clip(min=0)
+ return audio_mel_frame * self.hop_length / self.sample_rate
+
+
+ def patchify(self, audio_latents: torch.Tensor) -> Tuple[torch.Tensor, torch.Tensor]:
+ # audio_latents: (batch, channels, time, freq)
+ b, _, t, _ = audio_latents.shape
+ audio_latents = rearrange(
+ audio_latents,
+ "b c t f -> b t (c f)",
+ )
+
+ audio_latents_start_timings = self._get_audio_latent_time_in_sec(self.shift, t + self.shift, torch.float32, audio_latents.device)
+ audio_latents_start_timings = audio_latents_start_timings.unsqueeze(0).expand(b, -1).unsqueeze(1)
+
+ if self.start_end:
+ audio_latents_end_timings = self._get_audio_latent_time_in_sec(self.shift + 1, t + self.shift + 1, torch.float32, audio_latents.device)
+ audio_latents_end_timings = audio_latents_end_timings.unsqueeze(0).expand(b, -1).unsqueeze(1)
+
+ audio_latents_timings = torch.stack([audio_latents_start_timings, audio_latents_end_timings], dim=-1)
+ else:
+ audio_latents_timings = audio_latents_start_timings
+ return audio_latents, audio_latents_timings
+
+ def unpatchify(self, audio_latents: torch.Tensor, channels: int, freq: int) -> torch.Tensor:
+ # audio_latents: (batch, time, freq * channels)
+ audio_latents = rearrange(
+ audio_latents, "b t (c f) -> b c t f", c=channels, f=freq
+ )
+ return audio_latents
diff --git a/ComfyUI/comfy/ldm/lightricks/vae/__pycache__/audio_vae.cpython-312.pyc b/ComfyUI/comfy/ldm/lightricks/vae/__pycache__/audio_vae.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..7bc9dff766a32304a2a262e4147e6d78d7dfc3f8
Binary files /dev/null and b/ComfyUI/comfy/ldm/lightricks/vae/__pycache__/audio_vae.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/lightricks/vae/__pycache__/causal_audio_autoencoder.cpython-312.pyc b/ComfyUI/comfy/ldm/lightricks/vae/__pycache__/causal_audio_autoencoder.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..4fdfb9c123ae5d96efe61b9d3d37dd0ff1f05be7
Binary files /dev/null and b/ComfyUI/comfy/ldm/lightricks/vae/__pycache__/causal_audio_autoencoder.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/lightricks/vae/__pycache__/causal_conv3d.cpython-312.pyc b/ComfyUI/comfy/ldm/lightricks/vae/__pycache__/causal_conv3d.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..b0cc099a444edbda25bd627aa71f18cb92752674
Binary files /dev/null and b/ComfyUI/comfy/ldm/lightricks/vae/__pycache__/causal_conv3d.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/lightricks/vae/__pycache__/causal_video_autoencoder.cpython-312.pyc b/ComfyUI/comfy/ldm/lightricks/vae/__pycache__/causal_video_autoencoder.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..30dbe73d36c3f99587854eae9d66adfdd6c869b7
Binary files /dev/null and b/ComfyUI/comfy/ldm/lightricks/vae/__pycache__/causal_video_autoencoder.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/lightricks/vae/__pycache__/conv_nd_factory.cpython-312.pyc b/ComfyUI/comfy/ldm/lightricks/vae/__pycache__/conv_nd_factory.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..d7fd689dd08348137c94d17c655495de69b3bfcb
Binary files /dev/null and b/ComfyUI/comfy/ldm/lightricks/vae/__pycache__/conv_nd_factory.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/lightricks/vae/__pycache__/dual_conv3d.cpython-312.pyc b/ComfyUI/comfy/ldm/lightricks/vae/__pycache__/dual_conv3d.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..83688db3a90cc1edc8a94dd1d2a6682765ba2f0f
Binary files /dev/null and b/ComfyUI/comfy/ldm/lightricks/vae/__pycache__/dual_conv3d.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/lightricks/vae/__pycache__/pixel_norm.cpython-312.pyc b/ComfyUI/comfy/ldm/lightricks/vae/__pycache__/pixel_norm.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..e87d4bfa92634a75a550e82cfb39277de060d9ea
Binary files /dev/null and b/ComfyUI/comfy/ldm/lightricks/vae/__pycache__/pixel_norm.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/lightricks/vae/audio_vae.py b/ComfyUI/comfy/ldm/lightricks/vae/audio_vae.py
new file mode 100644
index 0000000000000000000000000000000000000000..b4a8c7524cfd92e13896595a27c3c360f474c96b
--- /dev/null
+++ b/ComfyUI/comfy/ldm/lightricks/vae/audio_vae.py
@@ -0,0 +1,239 @@
+import json
+from dataclasses import dataclass
+import math
+import torch
+import torchaudio
+
+from comfy.ldm.mmaudio.vae.distributions import DiagonalGaussianDistribution
+from comfy.ldm.lightricks.symmetric_patchifier import AudioPatchifier
+from comfy.ldm.lightricks.vae.causal_audio_autoencoder import (
+ CausalityAxis,
+ CausalAudioAutoencoder,
+)
+from comfy.ldm.lightricks.vocoders.vocoder import Vocoder, VocoderWithBWE
+
+LATENT_DOWNSAMPLE_FACTOR = 4
+
+
+@dataclass(frozen=True)
+class AudioVAEComponentConfig:
+ """Container for model component configuration extracted from metadata."""
+
+ autoencoder: dict
+ vocoder: dict
+
+ @classmethod
+ def from_metadata(cls, metadata: dict) -> "AudioVAEComponentConfig":
+ assert metadata is not None and "config" in metadata, "Metadata is required for audio VAE"
+
+ raw_config = metadata["config"]
+ if isinstance(raw_config, str):
+ parsed_config = json.loads(raw_config)
+ else:
+ parsed_config = raw_config
+
+ audio_config = parsed_config.get("audio_vae")
+ vocoder_config = parsed_config.get("vocoder")
+
+ assert audio_config is not None, "Audio VAE config is required for audio VAE"
+ assert vocoder_config is not None, "Vocoder config is required for audio VAE"
+
+ return cls(autoencoder=audio_config, vocoder=vocoder_config)
+
+class AudioLatentNormalizer:
+ """Applies per-channel statistics in patch space and restores original layout."""
+
+ def __init__(self, patchfier: AudioPatchifier, statistics_processor: torch.nn.Module):
+ self.patchifier = patchfier
+ self.statistics = statistics_processor
+
+ def normalize(self, latents: torch.Tensor) -> torch.Tensor:
+ channels = latents.shape[1]
+ freq = latents.shape[3]
+ patched, _ = self.patchifier.patchify(latents)
+ normalized = self.statistics.normalize(patched)
+ return self.patchifier.unpatchify(normalized, channels=channels, freq=freq)
+
+ def denormalize(self, latents: torch.Tensor) -> torch.Tensor:
+ channels = latents.shape[1]
+ freq = latents.shape[3]
+ patched, _ = self.patchifier.patchify(latents)
+ denormalized = self.statistics.un_normalize(patched)
+ return self.patchifier.unpatchify(denormalized, channels=channels, freq=freq)
+
+
+class AudioPreprocessor:
+ """Prepares raw waveforms for the autoencoder by matching training conditions."""
+
+ def __init__(self, target_sample_rate: int, mel_bins: int, mel_hop_length: int, n_fft: int):
+ self.target_sample_rate = target_sample_rate
+ self.mel_bins = mel_bins
+ self.mel_hop_length = mel_hop_length
+ self.n_fft = n_fft
+
+ def resample(self, waveform: torch.Tensor, source_rate: int) -> torch.Tensor:
+ if source_rate == self.target_sample_rate:
+ return waveform
+ return torchaudio.functional.resample(waveform, source_rate, self.target_sample_rate)
+
+ def waveform_to_mel(
+ self, waveform: torch.Tensor, waveform_sample_rate: int, device
+ ) -> torch.Tensor:
+ waveform = self.resample(waveform, waveform_sample_rate)
+
+ mel_transform = torchaudio.transforms.MelSpectrogram(
+ sample_rate=self.target_sample_rate,
+ n_fft=self.n_fft,
+ win_length=self.n_fft,
+ hop_length=self.mel_hop_length,
+ f_min=0.0,
+ f_max=self.target_sample_rate / 2.0,
+ n_mels=self.mel_bins,
+ window_fn=torch.hann_window,
+ center=True,
+ pad_mode="reflect",
+ power=1.0,
+ mel_scale="slaney",
+ norm="slaney",
+ ).to(device)
+
+ mel = mel_transform(waveform)
+ mel = torch.log(torch.clamp(mel, min=1e-5))
+ return mel.permute(0, 1, 3, 2).contiguous()
+
+
+class AudioVAE(torch.nn.Module):
+ """High-level Audio VAE wrapper exposing encode and decode entry points."""
+
+ def __init__(self, metadata: dict):
+ super().__init__()
+
+ component_config = AudioVAEComponentConfig.from_metadata(metadata)
+
+ self.autoencoder = CausalAudioAutoencoder(config=component_config.autoencoder)
+ if "bwe" in component_config.vocoder:
+ self.vocoder = VocoderWithBWE(config=component_config.vocoder)
+ else:
+ self.vocoder = Vocoder(config=component_config.vocoder)
+
+ autoencoder_config = self.autoencoder.get_config()
+ self.normalizer = AudioLatentNormalizer(
+ AudioPatchifier(
+ patch_size=1,
+ audio_latent_downsample_factor=LATENT_DOWNSAMPLE_FACTOR,
+ sample_rate=autoencoder_config["sampling_rate"],
+ hop_length=autoencoder_config["mel_hop_length"],
+ is_causal=autoencoder_config["is_causal"],
+ ),
+ self.autoencoder.per_channel_statistics,
+ )
+
+ self.preprocessor = AudioPreprocessor(
+ target_sample_rate=autoencoder_config["sampling_rate"],
+ mel_bins=autoencoder_config["mel_bins"],
+ mel_hop_length=autoencoder_config["mel_hop_length"],
+ n_fft=autoencoder_config["n_fft"],
+ )
+
+ def encode(self, audio, sample_rate=44100) -> torch.Tensor:
+ """Encode a waveform dictionary into normalized latent tensors."""
+
+ waveform = audio
+ waveform_sample_rate = sample_rate
+ input_device = waveform.device
+ expected_channels = self.autoencoder.encoder.in_channels
+ if waveform.shape[1] != expected_channels:
+ if waveform.shape[1] == 1:
+ waveform = waveform.expand(-1, expected_channels, *waveform.shape[2:])
+ else:
+ raise ValueError(
+ f"Input audio must have {expected_channels} channels, got {waveform.shape[1]}"
+ )
+
+ mel_spec = self.preprocessor.waveform_to_mel(
+ waveform, waveform_sample_rate, device=waveform.device
+ )
+
+ latents = self.autoencoder.encode(mel_spec)
+ posterior = DiagonalGaussianDistribution(latents)
+ latent_mode = posterior.mode()
+
+ normalized = self.normalizer.normalize(latent_mode)
+ return normalized.to(input_device)
+
+ def decode(self, latents: torch.Tensor) -> torch.Tensor:
+ """Decode normalized latent tensors into an audio waveform."""
+ original_shape = latents.shape
+
+ latents = self.normalizer.denormalize(latents)
+
+ target_shape = self.target_shape_from_latents(original_shape)
+ mel_spec = self.autoencoder.decode(latents, target_shape=target_shape)
+
+ waveform = self.run_vocoder(mel_spec)
+ return waveform
+
+ def target_shape_from_latents(self, latents_shape):
+ batch, _, time, _ = latents_shape
+ target_length = time * LATENT_DOWNSAMPLE_FACTOR
+ if self.autoencoder.causality_axis != CausalityAxis.NONE:
+ target_length -= LATENT_DOWNSAMPLE_FACTOR - 1
+ return (
+ batch,
+ self.autoencoder.decoder.out_ch,
+ target_length,
+ self.autoencoder.mel_bins,
+ )
+
+ def num_of_latents_from_frames(self, frames_number: int, frame_rate: float) -> int:
+ return math.ceil((float(frames_number) / frame_rate) * self.latents_per_second)
+
+ def run_vocoder(self, mel_spec: torch.Tensor) -> torch.Tensor:
+ audio_channels = self.autoencoder.decoder.out_ch
+ vocoder_input = mel_spec.transpose(2, 3)
+
+ if audio_channels == 1:
+ vocoder_input = vocoder_input.squeeze(1)
+ elif audio_channels != 2:
+ raise ValueError(f"Unsupported audio_channels: {audio_channels}")
+
+ return self.vocoder(vocoder_input)
+
+ @property
+ def sample_rate(self) -> int:
+ return int(self.autoencoder.sampling_rate)
+
+ @property
+ def mel_hop_length(self) -> int:
+ return int(self.autoencoder.mel_hop_length)
+
+ @property
+ def mel_bins(self) -> int:
+ return int(self.autoencoder.mel_bins)
+
+ @property
+ def latent_channels(self) -> int:
+ return int(self.autoencoder.decoder.z_channels)
+
+ @property
+ def latent_frequency_bins(self) -> int:
+ return int(self.mel_bins // LATENT_DOWNSAMPLE_FACTOR)
+
+ @property
+ def latents_per_second(self) -> float:
+ return self.sample_rate / self.mel_hop_length / LATENT_DOWNSAMPLE_FACTOR
+
+ @property
+ def output_sample_rate(self) -> int:
+ output_rate = getattr(self.vocoder, "output_sample_rate", None)
+ if output_rate is not None:
+ return int(output_rate)
+ upsample_factor = getattr(self.vocoder, "upsample_factor", None)
+ if upsample_factor is None:
+ raise AttributeError(
+ "Vocoder is missing upsample_factor; cannot infer output sample rate"
+ )
+ return int(self.sample_rate * upsample_factor / self.mel_hop_length)
+
+ def memory_required(self, input_shape):
+ return self.device_manager.patcher.model_size()
diff --git a/ComfyUI/comfy/ldm/lightricks/vae/causal_audio_autoencoder.py b/ComfyUI/comfy/ldm/lightricks/vae/causal_audio_autoencoder.py
new file mode 100644
index 0000000000000000000000000000000000000000..58b67d45ab14aee371ed1ee4b8dc31e53547e2ac
--- /dev/null
+++ b/ComfyUI/comfy/ldm/lightricks/vae/causal_audio_autoencoder.py
@@ -0,0 +1,899 @@
+import torch
+from torch import nn
+from torch.nn import functional as F
+from typing import Optional
+from enum import Enum
+from .pixel_norm import PixelNorm
+import comfy.ops
+import logging
+
+ops = comfy.ops.disable_weight_init
+
+
+class StringConvertibleEnum(Enum):
+ """
+ Base enum class that provides string-to-enum conversion functionality.
+
+ This mixin adds a str_to_enum() class method that handles conversion from
+ strings, None, or existing enum instances with case-insensitive matching.
+ """
+
+ @classmethod
+ def str_to_enum(cls, value):
+ """
+ Convert a string, enum instance, or None to the appropriate enum member.
+
+ Args:
+ value: Can be an enum instance of this class, a string, or None
+
+ Returns:
+ Enum member of this class
+
+ Raises:
+ ValueError: If the value cannot be converted to a valid enum member
+ """
+ # Already an enum instance of this class
+ if isinstance(value, cls):
+ return value
+
+ # None maps to NONE member if it exists
+ if value is None:
+ if hasattr(cls, "NONE"):
+ return cls.NONE
+ raise ValueError(f"{cls.__name__} does not have a NONE member to map None to")
+
+ # String conversion (case-insensitive)
+ if isinstance(value, str):
+ value_lower = value.lower()
+
+ # Try to match against enum values
+ for member in cls:
+ # Handle members with None values
+ if member.value is None:
+ if value_lower == "none":
+ return member
+ # Handle members with string values
+ elif isinstance(member.value, str) and member.value.lower() == value_lower:
+ return member
+
+ # Build helpful error message with valid values
+ valid_values = []
+ for member in cls:
+ if member.value is None:
+ valid_values.append("none")
+ elif isinstance(member.value, str):
+ valid_values.append(member.value)
+
+ raise ValueError(f"Invalid {cls.__name__} string: '{value}'. " f"Valid values are: {valid_values}")
+
+ raise ValueError(
+ f"Cannot convert type {type(value).__name__} to {cls.__name__} enum. "
+ f"Expected string, None, or {cls.__name__} instance."
+ )
+
+
+class AttentionType(StringConvertibleEnum):
+ """Enum for specifying the attention mechanism type."""
+
+ VANILLA = "vanilla"
+ LINEAR = "linear"
+ NONE = "none"
+
+
+class CausalityAxis(StringConvertibleEnum):
+ """Enum for specifying the causality axis in causal convolutions."""
+
+ NONE = None
+ WIDTH = "width"
+ HEIGHT = "height"
+ WIDTH_COMPATIBILITY = "width-compatibility"
+
+
+def Normalize(in_channels, *, num_groups=32, normtype="group"):
+ if normtype == "group":
+ return torch.nn.GroupNorm(num_groups=num_groups, num_channels=in_channels, eps=1e-6, affine=True)
+ elif normtype == "pixel":
+ return PixelNorm(dim=1, eps=1e-6)
+ else:
+ raise ValueError(f"Invalid normalization type: {normtype}")
+
+
+class CausalConv2d(nn.Module):
+ """
+ A causal 2D convolution.
+
+ This layer ensures that the output at time `t` only depends on inputs
+ at time `t` and earlier. It achieves this by applying asymmetric padding
+ to the time dimension (width) before the convolution.
+ """
+
+ def __init__(
+ self,
+ in_channels,
+ out_channels,
+ kernel_size,
+ stride=1,
+ dilation=1,
+ groups=1,
+ bias=True,
+ causality_axis: CausalityAxis = CausalityAxis.HEIGHT,
+ ):
+ super().__init__()
+
+ self.causality_axis = causality_axis
+
+ # Ensure kernel_size and dilation are tuples
+ kernel_size = nn.modules.utils._pair(kernel_size)
+ dilation = nn.modules.utils._pair(dilation)
+
+ # Calculate padding dimensions
+ pad_h = (kernel_size[0] - 1) * dilation[0]
+ pad_w = (kernel_size[1] - 1) * dilation[1]
+
+ # The padding tuple for F.pad is (pad_left, pad_right, pad_top, pad_bottom)
+ match self.causality_axis:
+ case CausalityAxis.NONE:
+ self.padding = (pad_w // 2, pad_w - pad_w // 2, pad_h // 2, pad_h - pad_h // 2)
+ case CausalityAxis.WIDTH | CausalityAxis.WIDTH_COMPATIBILITY:
+ self.padding = (pad_w, 0, pad_h // 2, pad_h - pad_h // 2)
+ case CausalityAxis.HEIGHT:
+ self.padding = (pad_w // 2, pad_w - pad_w // 2, pad_h, 0)
+ case _:
+ raise ValueError(f"Invalid causality_axis: {causality_axis}")
+
+ # The internal convolution layer uses no padding, as we handle it manually
+ self.conv = ops.Conv2d(
+ in_channels,
+ out_channels,
+ kernel_size,
+ stride=stride,
+ padding=0,
+ dilation=dilation,
+ groups=groups,
+ bias=bias,
+ )
+
+ def forward(self, x):
+ # Apply causal padding before convolution
+ x = F.pad(x, self.padding)
+ return self.conv(x)
+
+
+def make_conv2d(
+ in_channels,
+ out_channels,
+ kernel_size,
+ stride=1,
+ padding=None,
+ dilation=1,
+ groups=1,
+ bias=True,
+ causality_axis: Optional[CausalityAxis] = None,
+):
+ """
+ Create a 2D convolution layer that can be either causal or non-causal.
+
+ Args:
+ in_channels: Number of input channels
+ out_channels: Number of output channels
+ kernel_size: Size of the convolution kernel
+ stride: Convolution stride
+ padding: Padding (if None, will be calculated based on causal flag)
+ dilation: Dilation rate
+ groups: Number of groups for grouped convolution
+ bias: Whether to use bias
+ causality_axis: Dimension along which to apply causality.
+
+ Returns:
+ Either a regular Conv2d or CausalConv2d layer
+ """
+ if causality_axis is not None:
+ # For causal convolution, padding is handled internally by CausalConv2d
+ return CausalConv2d(in_channels, out_channels, kernel_size, stride, dilation, groups, bias, causality_axis)
+ else:
+ # For non-causal convolution, use symmetric padding if not specified
+ if padding is None:
+ if isinstance(kernel_size, int):
+ padding = kernel_size // 2
+ else:
+ padding = tuple(k // 2 for k in kernel_size)
+ return ops.Conv2d(
+ in_channels,
+ out_channels,
+ kernel_size,
+ stride,
+ padding,
+ dilation,
+ groups,
+ bias,
+ )
+
+
+class Upsample(nn.Module):
+ def __init__(self, in_channels, with_conv, causality_axis: CausalityAxis = CausalityAxis.HEIGHT):
+ super().__init__()
+ self.with_conv = with_conv
+ self.causality_axis = causality_axis
+ if self.with_conv:
+ self.conv = make_conv2d(in_channels, in_channels, kernel_size=3, stride=1, causality_axis=causality_axis)
+
+ def forward(self, x):
+ x = torch.nn.functional.interpolate(x, scale_factor=2.0, mode="nearest")
+ if self.with_conv:
+ x = self.conv(x)
+ # Drop FIRST element in the causal axis to undo encoder's padding, while keeping the length 1 + 2 * n.
+ # For example, if the input is [0, 1, 2], after interpolation, the output is [0, 0, 1, 1, 2, 2].
+ # The causal convolution will pad the first element as [-, -, 0, 0, 1, 1, 2, 2],
+ # So the output elements rely on the following windows:
+ # 0: [-,-,0]
+ # 1: [-,0,0]
+ # 2: [0,0,1]
+ # 3: [0,1,1]
+ # 4: [1,1,2]
+ # 5: [1,2,2]
+ # Notice that the first and second elements in the output rely only on the first element in the input,
+ # while all other elements rely on two elements in the input.
+ # So we can drop the first element to undo the padding (rather than the last element).
+ # This is a no-op for non-causal convolutions.
+ match self.causality_axis:
+ case CausalityAxis.NONE:
+ pass # x remains unchanged
+ case CausalityAxis.HEIGHT:
+ x = x[:, :, 1:, :]
+ case CausalityAxis.WIDTH:
+ x = x[:, :, :, 1:]
+ case CausalityAxis.WIDTH_COMPATIBILITY:
+ pass # x remains unchanged
+ case _:
+ raise ValueError(f"Invalid causality_axis: {self.causality_axis}")
+
+ return x
+
+
+class Downsample(nn.Module):
+ """
+ A downsampling layer that can use either a strided convolution
+ or average pooling. Supports standard and causal padding for the
+ convolutional mode.
+ """
+
+ def __init__(self, in_channels, with_conv, causality_axis: CausalityAxis = CausalityAxis.WIDTH):
+ super().__init__()
+ self.with_conv = with_conv
+ self.causality_axis = causality_axis
+
+ if self.causality_axis != CausalityAxis.NONE and not self.with_conv:
+ raise ValueError("causality is only supported when `with_conv=True`.")
+
+ if self.with_conv:
+ # Do time downsampling here
+ # no asymmetric padding in torch conv, must do it ourselves
+ self.conv = ops.Conv2d(in_channels, in_channels, kernel_size=3, stride=2, padding=0)
+
+ def forward(self, x):
+ if self.with_conv:
+ # (pad_left, pad_right, pad_top, pad_bottom)
+ match self.causality_axis:
+ case CausalityAxis.NONE:
+ pad = (0, 1, 0, 1)
+ case CausalityAxis.WIDTH:
+ pad = (2, 0, 0, 1)
+ case CausalityAxis.HEIGHT:
+ pad = (0, 1, 2, 0)
+ case CausalityAxis.WIDTH_COMPATIBILITY:
+ pad = (1, 0, 0, 1)
+ case _:
+ raise ValueError(f"Invalid causality_axis: {self.causality_axis}")
+
+ x = torch.nn.functional.pad(x, pad, mode="constant", value=0)
+ x = self.conv(x)
+ else:
+ # This branch is only taken if with_conv=False, which implies causality_axis is NONE.
+ x = torch.nn.functional.avg_pool2d(x, kernel_size=2, stride=2)
+
+ return x
+
+
+class ResnetBlock(nn.Module):
+ def __init__(
+ self,
+ *,
+ in_channels,
+ out_channels=None,
+ conv_shortcut=False,
+ dropout,
+ temb_channels=512,
+ norm_type="group",
+ causality_axis: CausalityAxis = CausalityAxis.HEIGHT,
+ ):
+ super().__init__()
+ self.causality_axis = causality_axis
+
+ if self.causality_axis != CausalityAxis.NONE and norm_type == "group":
+ raise ValueError("Causal ResnetBlock with GroupNorm is not supported.")
+ self.in_channels = in_channels
+ out_channels = in_channels if out_channels is None else out_channels
+ self.out_channels = out_channels
+ self.use_conv_shortcut = conv_shortcut
+
+ self.norm1 = Normalize(in_channels, normtype=norm_type)
+ self.non_linearity = nn.SiLU()
+ self.conv1 = make_conv2d(in_channels, out_channels, kernel_size=3, stride=1, causality_axis=causality_axis)
+ if temb_channels > 0:
+ self.temb_proj = ops.Linear(temb_channels, out_channels)
+ self.norm2 = Normalize(out_channels, normtype=norm_type)
+ self.dropout = torch.nn.Dropout(dropout)
+ self.conv2 = make_conv2d(out_channels, out_channels, kernel_size=3, stride=1, causality_axis=causality_axis)
+ if self.in_channels != self.out_channels:
+ if self.use_conv_shortcut:
+ self.conv_shortcut = make_conv2d(
+ in_channels, out_channels, kernel_size=3, stride=1, causality_axis=causality_axis
+ )
+ else:
+ self.nin_shortcut = make_conv2d(
+ in_channels, out_channels, kernel_size=1, stride=1, causality_axis=causality_axis
+ )
+
+ def forward(self, x, temb):
+ h = x
+ h = self.norm1(h)
+ h = self.non_linearity(h)
+ h = self.conv1(h)
+
+ if temb is not None:
+ h = h + self.temb_proj(self.non_linearity(temb))[:, :, None, None]
+
+ h = self.norm2(h)
+ h = self.non_linearity(h)
+ h = self.dropout(h)
+ h = self.conv2(h)
+
+ if self.in_channels != self.out_channels:
+ if self.use_conv_shortcut:
+ x = self.conv_shortcut(x)
+ else:
+ x = self.nin_shortcut(x)
+
+ return x + h
+
+
+class AttnBlock(nn.Module):
+ def __init__(self, in_channels, norm_type="group"):
+ super().__init__()
+ self.in_channels = in_channels
+
+ self.norm = Normalize(in_channels, normtype=norm_type)
+ self.q = ops.Conv2d(in_channels, in_channels, kernel_size=1, stride=1, padding=0)
+ self.k = ops.Conv2d(in_channels, in_channels, kernel_size=1, stride=1, padding=0)
+ self.v = ops.Conv2d(in_channels, in_channels, kernel_size=1, stride=1, padding=0)
+ self.proj_out = ops.Conv2d(in_channels, in_channels, kernel_size=1, stride=1, padding=0)
+
+ def forward(self, x):
+ h_ = x
+ h_ = self.norm(h_)
+ q = self.q(h_)
+ k = self.k(h_)
+ v = self.v(h_)
+
+ # compute attention
+ b, c, h, w = q.shape
+ q = q.reshape(b, c, h * w).contiguous()
+ q = q.permute(0, 2, 1).contiguous() # b,hw,c
+ k = k.reshape(b, c, h * w).contiguous() # b,c,hw
+ w_ = torch.bmm(q, k).contiguous() # b,hw,hw w[b,i,j]=sum_c q[b,i,c]k[b,c,j]
+ w_ = w_ * (int(c) ** (-0.5))
+ w_ = torch.nn.functional.softmax(w_, dim=2)
+
+ # attend to values
+ v = v.reshape(b, c, h * w).contiguous()
+ w_ = w_.permute(0, 2, 1).contiguous() # b,hw,hw (first hw of k, second of q)
+ h_ = torch.bmm(v, w_).contiguous() # b, c,hw (hw of q) h_[b,c,j] = sum_i v[b,c,i] w_[b,i,j]
+ h_ = h_.reshape(b, c, h, w).contiguous()
+
+ h_ = self.proj_out(h_)
+
+ return x + h_
+
+
+def make_attn(in_channels, attn_type="vanilla", norm_type="group"):
+ # Convert string to enum if needed
+ attn_type = AttentionType.str_to_enum(attn_type)
+
+ if attn_type != AttentionType.NONE:
+ logging.info(f"making attention of type '{attn_type.value}' with {in_channels} in_channels")
+ else:
+ logging.info(f"making identity attention with {in_channels} in_channels")
+
+ match attn_type:
+ case AttentionType.VANILLA:
+ return AttnBlock(in_channels, norm_type=norm_type)
+ case AttentionType.NONE:
+ return nn.Identity(in_channels)
+ case AttentionType.LINEAR:
+ raise NotImplementedError(f"Attention type {attn_type.value} is not supported yet.")
+ case _:
+ raise ValueError(f"Unknown attention type: {attn_type}")
+
+
+class Encoder(nn.Module):
+ def __init__(
+ self,
+ *,
+ ch,
+ out_ch,
+ ch_mult=(1, 2, 4, 8),
+ num_res_blocks,
+ attn_resolutions,
+ dropout=0.0,
+ resamp_with_conv=True,
+ in_channels,
+ resolution,
+ z_channels,
+ double_z=True,
+ attn_type="vanilla",
+ mid_block_add_attention=True,
+ norm_type="group",
+ causality_axis=CausalityAxis.WIDTH.value,
+ **ignore_kwargs,
+ ):
+ super().__init__()
+ self.ch = ch
+ self.temb_ch = 0
+ self.num_resolutions = len(ch_mult)
+ self.num_res_blocks = num_res_blocks
+ self.resolution = resolution
+ self.in_channels = in_channels
+ self.z_channels = z_channels
+ self.double_z = double_z
+ self.norm_type = norm_type
+ # Convert string to enum if needed (for config loading)
+ causality_axis = CausalityAxis.str_to_enum(causality_axis)
+ self.attn_type = AttentionType.str_to_enum(attn_type)
+
+ # downsampling
+ self.conv_in = make_conv2d(
+ in_channels,
+ self.ch,
+ kernel_size=3,
+ stride=1,
+ causality_axis=causality_axis,
+ )
+
+ self.non_linearity = nn.SiLU()
+
+ curr_res = resolution
+ in_ch_mult = (1,) + tuple(ch_mult)
+ self.in_ch_mult = in_ch_mult
+ self.down = nn.ModuleList()
+
+ for i_level in range(self.num_resolutions):
+ block = nn.ModuleList()
+ attn = nn.ModuleList()
+ block_in = ch * in_ch_mult[i_level]
+ block_out = ch * ch_mult[i_level]
+
+ for _ in range(self.num_res_blocks):
+ block.append(
+ ResnetBlock(
+ in_channels=block_in,
+ out_channels=block_out,
+ temb_channels=self.temb_ch,
+ dropout=dropout,
+ norm_type=self.norm_type,
+ causality_axis=causality_axis,
+ )
+ )
+ block_in = block_out
+ if curr_res in attn_resolutions:
+ attn.append(make_attn(block_in, attn_type=self.attn_type, norm_type=self.norm_type))
+
+ down = nn.Module()
+ down.block = block
+ down.attn = attn
+ if i_level != self.num_resolutions - 1:
+ down.downsample = Downsample(block_in, resamp_with_conv, causality_axis=causality_axis)
+ curr_res = curr_res // 2
+ self.down.append(down)
+
+ # middle
+ self.mid = nn.Module()
+ self.mid.block_1 = ResnetBlock(
+ in_channels=block_in,
+ out_channels=block_in,
+ temb_channels=self.temb_ch,
+ dropout=dropout,
+ norm_type=self.norm_type,
+ causality_axis=causality_axis,
+ )
+ if mid_block_add_attention:
+ self.mid.attn_1 = make_attn(block_in, attn_type=self.attn_type, norm_type=self.norm_type)
+ else:
+ self.mid.attn_1 = nn.Identity()
+ self.mid.block_2 = ResnetBlock(
+ in_channels=block_in,
+ out_channels=block_in,
+ temb_channels=self.temb_ch,
+ dropout=dropout,
+ norm_type=self.norm_type,
+ causality_axis=causality_axis,
+ )
+
+ # end
+ self.norm_out = Normalize(block_in, normtype=self.norm_type)
+ self.conv_out = make_conv2d(
+ block_in,
+ 2 * z_channels if double_z else z_channels,
+ kernel_size=3,
+ stride=1,
+ causality_axis=causality_axis,
+ )
+
+ def forward(self, x):
+ """
+ Forward pass through the encoder.
+
+ Args:
+ x: Input tensor of shape [batch, channels, time, n_mels]
+
+ Returns:
+ Encoded latent representation
+ """
+ feature_maps = [self.conv_in(x)]
+
+ # Process each resolution level (from high to low resolution)
+ for resolution_level in range(self.num_resolutions):
+ # Apply residual blocks at current resolution level
+ for block_idx in range(self.num_res_blocks):
+ # Apply ResNet block with optional timestep embedding
+ current_features = self.down[resolution_level].block[block_idx](feature_maps[-1], temb=None)
+
+ # Apply attention if configured for this resolution level
+ if len(self.down[resolution_level].attn) > 0:
+ current_features = self.down[resolution_level].attn[block_idx](current_features)
+
+ # Store processed features
+ feature_maps.append(current_features)
+
+ # Downsample spatial dimensions (except at the final resolution level)
+ if resolution_level != self.num_resolutions - 1:
+ downsampled_features = self.down[resolution_level].downsample(feature_maps[-1])
+ feature_maps.append(downsampled_features)
+
+ # === MIDDLE PROCESSING PHASE ===
+ # Take the lowest resolution features for middle processing
+ bottleneck_features = feature_maps[-1]
+
+ # Apply first middle ResNet block
+ bottleneck_features = self.mid.block_1(bottleneck_features, temb=None)
+
+ # Apply middle attention block
+ bottleneck_features = self.mid.attn_1(bottleneck_features)
+
+ # Apply second middle ResNet block
+ bottleneck_features = self.mid.block_2(bottleneck_features, temb=None)
+
+ # === OUTPUT PHASE ===
+ # Normalize the bottleneck features
+ output_features = self.norm_out(bottleneck_features)
+
+ # Apply non-linearity (SiLU activation)
+ output_features = self.non_linearity(output_features)
+
+ # Final convolution to produce latent representation
+ # [batch, channels, time, n_mels] -> [batch, 2 * z_channels if double_z else z_channels, time, n_mels]
+ return self.conv_out(output_features)
+
+
+class Decoder(nn.Module):
+ def __init__(
+ self,
+ *,
+ ch,
+ out_ch,
+ ch_mult=(1, 2, 4, 8),
+ num_res_blocks,
+ attn_resolutions,
+ dropout=0.0,
+ resamp_with_conv=True,
+ in_channels,
+ resolution,
+ z_channels,
+ give_pre_end=False,
+ tanh_out=False,
+ attn_type="vanilla",
+ mid_block_add_attention=True,
+ norm_type="group",
+ causality_axis=CausalityAxis.WIDTH.value,
+ **ignorekwargs,
+ ):
+ super().__init__()
+ self.ch = ch
+ self.temb_ch = 0
+ self.num_resolutions = len(ch_mult)
+ self.num_res_blocks = num_res_blocks
+ self.resolution = resolution
+ self.in_channels = in_channels
+ self.out_ch = out_ch
+ self.give_pre_end = give_pre_end
+ self.tanh_out = tanh_out
+ self.norm_type = norm_type
+ self.z_channels = z_channels
+ # Convert string to enum if needed (for config loading)
+ causality_axis = CausalityAxis.str_to_enum(causality_axis)
+ self.attn_type = AttentionType.str_to_enum(attn_type)
+
+ # compute block_in and curr_res at lowest res
+ block_in = ch * ch_mult[self.num_resolutions - 1]
+ curr_res = resolution // 2 ** (self.num_resolutions - 1)
+ self.z_shape = (1, z_channels, curr_res, curr_res)
+
+ # z to block_in
+ self.conv_in = make_conv2d(z_channels, block_in, kernel_size=3, stride=1, causality_axis=causality_axis)
+
+ self.non_linearity = nn.SiLU()
+
+ # middle
+ self.mid = nn.Module()
+ self.mid.block_1 = ResnetBlock(
+ in_channels=block_in,
+ out_channels=block_in,
+ temb_channels=self.temb_ch,
+ dropout=dropout,
+ norm_type=self.norm_type,
+ causality_axis=causality_axis,
+ )
+ if mid_block_add_attention:
+ self.mid.attn_1 = make_attn(block_in, attn_type=self.attn_type, norm_type=self.norm_type)
+ else:
+ self.mid.attn_1 = nn.Identity()
+ self.mid.block_2 = ResnetBlock(
+ in_channels=block_in,
+ out_channels=block_in,
+ temb_channels=self.temb_ch,
+ dropout=dropout,
+ norm_type=self.norm_type,
+ causality_axis=causality_axis,
+ )
+
+ # upsampling
+ self.up = nn.ModuleList()
+ for i_level in reversed(range(self.num_resolutions)):
+ block = nn.ModuleList()
+ attn = nn.ModuleList()
+ block_out = ch * ch_mult[i_level]
+ for _ in range(self.num_res_blocks + 1):
+ block.append(
+ ResnetBlock(
+ in_channels=block_in,
+ out_channels=block_out,
+ temb_channels=self.temb_ch,
+ dropout=dropout,
+ norm_type=self.norm_type,
+ causality_axis=causality_axis,
+ )
+ )
+ block_in = block_out
+ if curr_res in attn_resolutions:
+ attn.append(make_attn(block_in, attn_type=self.attn_type, norm_type=self.norm_type))
+ up = nn.Module()
+ up.block = block
+ up.attn = attn
+ if i_level != 0:
+ up.upsample = Upsample(block_in, resamp_with_conv, causality_axis=causality_axis)
+ curr_res = curr_res * 2
+ self.up.insert(0, up) # prepend to get consistent order
+
+ # end
+ self.norm_out = Normalize(block_in, normtype=self.norm_type)
+ self.conv_out = make_conv2d(block_in, out_ch, kernel_size=3, stride=1, causality_axis=causality_axis)
+
+ def _adjust_output_shape(self, decoded_output, target_shape):
+ """
+ Adjust output shape to match target dimensions for variable-length audio.
+
+ This function handles the common case where decoded audio spectrograms need to be
+ resized to match a specific target shape.
+
+ Args:
+ decoded_output: Tensor of shape (batch, channels, time, frequency)
+ target_shape: Target shape tuple (batch, channels, time, frequency)
+
+ Returns:
+ Tensor adjusted to match target_shape exactly
+ """
+ # Current output shape: (batch, channels, time, frequency)
+ _, _, current_time, current_freq = decoded_output.shape
+ _, target_channels, target_time, target_freq = target_shape
+
+ # Step 1: Crop first to avoid exceeding target dimensions
+ decoded_output = decoded_output[
+ :, :target_channels, : min(current_time, target_time), : min(current_freq, target_freq)
+ ]
+
+ # Step 2: Calculate padding needed for time and frequency dimensions
+ time_padding_needed = target_time - decoded_output.shape[2]
+ freq_padding_needed = target_freq - decoded_output.shape[3]
+
+ # Step 3: Apply padding if needed
+ if time_padding_needed > 0 or freq_padding_needed > 0:
+ # PyTorch padding format: (pad_left, pad_right, pad_top, pad_bottom)
+ # For audio: pad_left/right = frequency, pad_top/bottom = time
+ padding = (
+ 0,
+ max(freq_padding_needed, 0), # frequency padding (left, right)
+ 0,
+ max(time_padding_needed, 0), # time padding (top, bottom)
+ )
+ decoded_output = F.pad(decoded_output, padding)
+
+ # Step 4: Final safety crop to ensure exact target shape
+ decoded_output = decoded_output[:, :target_channels, :target_time, :target_freq]
+
+ return decoded_output
+
+ def get_config(self):
+ return {
+ "ch": self.ch,
+ "out_ch": self.out_ch,
+ "ch_mult": self.ch_mult,
+ "num_res_blocks": self.num_res_blocks,
+ "in_channels": self.in_channels,
+ "resolution": self.resolution,
+ "z_channels": self.z_channels,
+ }
+
+ def forward(self, latent_features, target_shape=None):
+ """
+ Decode latent features back to audio spectrograms.
+
+ Args:
+ latent_features: Encoded latent representation of shape (batch, channels, height, width)
+ target_shape: Optional target output shape (batch, channels, time, frequency)
+ If provided, output will be cropped/padded to match this shape
+
+ Returns:
+ Reconstructed audio spectrogram of shape (batch, channels, time, frequency)
+ """
+ assert target_shape is not None, "Target shape is required for CausalAudioAutoencoder Decoder"
+
+ # Transform latent features to decoder's internal feature dimension
+ hidden_features = self.conv_in(latent_features)
+
+ # Middle processing
+ hidden_features = self.mid.block_1(hidden_features, temb=None)
+ hidden_features = self.mid.attn_1(hidden_features)
+ hidden_features = self.mid.block_2(hidden_features, temb=None)
+
+ # Upsampling
+ # Progressively increase spatial resolution from lowest to highest
+ for resolution_level in reversed(range(self.num_resolutions)):
+ # Apply residual blocks at current resolution level
+ for block_index in range(self.num_res_blocks + 1):
+ hidden_features = self.up[resolution_level].block[block_index](hidden_features, temb=None)
+
+ if len(self.up[resolution_level].attn) > 0:
+ hidden_features = self.up[resolution_level].attn[block_index](hidden_features)
+
+ if resolution_level != 0:
+ hidden_features = self.up[resolution_level].upsample(hidden_features)
+
+ # Output
+ if self.give_pre_end:
+ # Return intermediate features before final processing (for debugging/analysis)
+ decoded_output = hidden_features
+ else:
+ # Standard output path: normalize, activate, and convert to output channels
+ # Final normalization layer
+ hidden_features = self.norm_out(hidden_features)
+
+ # Apply SiLU (Swish) activation function
+ hidden_features = self.non_linearity(hidden_features)
+
+ # Final convolution to map to output channels (typically 2 for stereo audio)
+ decoded_output = self.conv_out(hidden_features)
+
+ # Optional tanh activation to bound output values to [-1, 1] range
+ if self.tanh_out:
+ decoded_output = torch.tanh(decoded_output)
+
+ # Adjust shape for audio data
+ if target_shape is not None:
+ decoded_output = self._adjust_output_shape(decoded_output, target_shape)
+
+ return decoded_output
+
+
+class processor(nn.Module):
+ def __init__(self):
+ super().__init__()
+ self.register_buffer("std-of-means", torch.empty(128))
+ self.register_buffer("mean-of-means", torch.empty(128))
+
+ def un_normalize(self, x):
+ return (x * self.get_buffer("std-of-means").to(x)) + self.get_buffer("mean-of-means").to(x)
+
+ def normalize(self, x):
+ return (x - self.get_buffer("mean-of-means").to(x)) / self.get_buffer("std-of-means").to(x)
+
+
+class CausalAudioAutoencoder(nn.Module):
+ def __init__(self, config=None):
+ super().__init__()
+
+ if config is None:
+ config = self.get_default_config()
+
+ model_config = config.get("model", {}).get("params", {})
+
+ self.sampling_rate = model_config.get(
+ "sampling_rate", config.get("sampling_rate", 16000)
+ )
+ encoder_config = model_config.get("encoder", model_config.get("ddconfig", {}))
+ decoder_config = model_config.get("decoder", encoder_config)
+
+ # Load mel spectrogram parameters
+ self.mel_bins = encoder_config.get("mel_bins", 64)
+ self.mel_hop_length = config.get("preprocessing", {}).get("stft", {}).get("hop_length", 160)
+ self.n_fft = config.get("preprocessing", {}).get("stft", {}).get("filter_length", 1024)
+
+ # Store causality configuration at VAE level (not just in encoder internals)
+ causality_axis_value = encoder_config.get("causality_axis", CausalityAxis.HEIGHT.value)
+ self.causality_axis = CausalityAxis.str_to_enum(causality_axis_value)
+ self.is_causal = self.causality_axis == CausalityAxis.HEIGHT
+
+ self.encoder = Encoder(**encoder_config)
+ self.decoder = Decoder(**decoder_config)
+
+ self.per_channel_statistics = processor()
+
+ def get_default_config(self):
+ ddconfig = {
+ "double_z": True,
+ "mel_bins": 64,
+ "z_channels": 8,
+ "resolution": 256,
+ "downsample_time": False,
+ "in_channels": 2,
+ "out_ch": 2,
+ "ch": 128,
+ "ch_mult": [1, 2, 4],
+ "num_res_blocks": 2,
+ "attn_resolutions": [],
+ "dropout": 0.0,
+ "mid_block_add_attention": False,
+ "norm_type": "pixel",
+ "causality_axis": "height",
+ }
+
+ config = {
+ "model": {
+ "params": {
+ "ddconfig": ddconfig,
+ "sampling_rate": 16000,
+ }
+ },
+ "preprocessing": {
+ "stft": {
+ "filter_length": 1024,
+ "hop_length": 160,
+ },
+ },
+ }
+
+ return config
+
+ def get_config(self):
+ return {
+ "sampling_rate": self.sampling_rate,
+ "mel_bins": self.mel_bins,
+ "mel_hop_length": self.mel_hop_length,
+ "n_fft": self.n_fft,
+ "causality_axis": self.causality_axis.value,
+ "is_causal": self.is_causal,
+ }
+
+ def encode(self, x):
+ return self.encoder(x)
+
+ def decode(self, x, target_shape=None):
+ return self.decoder(x, target_shape=target_shape)
diff --git a/ComfyUI/comfy/ldm/lightricks/vae/causal_conv3d.py b/ComfyUI/comfy/ldm/lightricks/vae/causal_conv3d.py
new file mode 100644
index 0000000000000000000000000000000000000000..bb1803f129f3f226ab7fc920e502e727e05b476e
--- /dev/null
+++ b/ComfyUI/comfy/ldm/lightricks/vae/causal_conv3d.py
@@ -0,0 +1,96 @@
+from typing import Tuple, Union
+
+import threading
+import torch
+import torch.nn as nn
+import comfy.ops
+ops = comfy.ops.disable_weight_init
+
+class CausalConv3d(nn.Module):
+ def __init__(
+ self,
+ in_channels,
+ out_channels,
+ kernel_size: int = 3,
+ stride: Union[int, Tuple[int]] = 1,
+ dilation: int = 1,
+ groups: int = 1,
+ spatial_padding_mode: str = "zeros",
+ **kwargs,
+ ):
+ super().__init__()
+
+ self.in_channels = in_channels
+ self.out_channels = out_channels
+
+ if isinstance(stride, int):
+ self.time_stride = stride
+ else:
+ self.time_stride = stride[0]
+
+ kernel_size = (kernel_size, kernel_size, kernel_size)
+ self.time_kernel_size = kernel_size[0]
+
+ dilation = (dilation, 1, 1)
+
+ height_pad = kernel_size[1] // 2
+ width_pad = kernel_size[2] // 2
+ padding = (0, height_pad, width_pad)
+
+ self.conv = ops.Conv3d(
+ in_channels,
+ out_channels,
+ kernel_size,
+ stride=stride,
+ dilation=dilation,
+ padding=padding,
+ padding_mode=spatial_padding_mode,
+ groups=groups,
+ )
+ self.temporal_cache_state={}
+
+ def _empty_output(self, x):
+ # empty (0 frame) outputs must still have the conv's output channels and spatial dims
+ h = (x.shape[3] + 2 * self.conv.padding[1] - self.conv.kernel_size[1]) // self.conv.stride[1] + 1
+ w = (x.shape[4] + 2 * self.conv.padding[2] - self.conv.kernel_size[2]) // self.conv.stride[2] + 1
+ return x.new_empty((x.shape[0], self.out_channels, 0, h, w))
+
+ def forward(self, x, causal: bool = True):
+ tid = threading.get_ident()
+
+ cached, is_end = self.temporal_cache_state.get(tid, (None, False))
+ if cached is None:
+ padding_length = self.time_kernel_size - 1
+ if not causal:
+ padding_length = padding_length // 2
+ if x.shape[2] == 0:
+ return self._empty_output(x)
+ cached = x[:, :, :1, :, :].repeat((1, 1, padding_length, 1, 1))
+ pieces = [ cached, x ]
+ if is_end and not causal:
+ pieces.append(x[:, :, -1:, :, :].repeat((1, 1, (self.time_kernel_size - 1) // 2, 1, 1)))
+ input_length = sum([piece.shape[2] for piece in pieces])
+ cache_length = (self.time_kernel_size - self.time_stride) + ((input_length - self.time_kernel_size) % self.time_stride)
+
+ needs_caching = not is_end
+ if needs_caching and cache_length == 0:
+ self.temporal_cache_state[tid] = (x[:, :, :0, :, :], False)
+ needs_caching = False
+ if needs_caching and x.shape[2] >= cache_length:
+ needs_caching = False
+ self.temporal_cache_state[tid] = (x[:, :, -cache_length:, :, :], False)
+
+ x = torch.cat(pieces, dim=2)
+ del pieces
+ del cached
+
+ if needs_caching:
+ self.temporal_cache_state[tid] = (x[:, :, -cache_length:, :, :], False)
+ elif is_end:
+ self.temporal_cache_state[tid] = (None, True)
+
+ return self.conv(x) if x.shape[2] >= self.time_kernel_size else self._empty_output(x)
+
+ @property
+ def weight(self):
+ return self.conv.weight
diff --git a/ComfyUI/comfy/ldm/lightricks/vae/causal_video_autoencoder.py b/ComfyUI/comfy/ldm/lightricks/vae/causal_video_autoencoder.py
new file mode 100644
index 0000000000000000000000000000000000000000..5d0eec5b85e21d357098a9b087e751d5c3c80f31
--- /dev/null
+++ b/ComfyUI/comfy/ldm/lightricks/vae/causal_video_autoencoder.py
@@ -0,0 +1,1307 @@
+import threading
+import torch
+from torch import nn
+from functools import partial
+import math
+from einops import rearrange
+from typing import List, Optional, Tuple, Union
+from .conv_nd_factory import make_conv_nd, make_linear_nd
+from .causal_conv3d import CausalConv3d
+from .pixel_norm import PixelNorm
+from ..model import PixArtAlphaCombinedTimestepSizeEmbeddings
+import comfy.ops
+import comfy.model_management
+from comfy.ldm.modules.diffusionmodules.model import torch_cat_if_needed
+
+ops = comfy.ops.disable_weight_init
+
+def in_meta_context():
+ return torch.device("meta") == torch.empty(0).device
+
+def mark_conv3d_ended(module):
+ tid = threading.get_ident()
+ for _, m in module.named_modules():
+ if isinstance(m, CausalConv3d):
+ current = m.temporal_cache_state.get(tid, (None, False))
+ m.temporal_cache_state[tid] = (current[0], True)
+
+def split2(tensor, split_point, dim=2):
+ return torch.split(tensor, [split_point, tensor.shape[dim] - split_point], dim=dim)
+
+def add_exchange_cache(dest, cache_in, new_input, dim=2):
+ if dest is not None:
+ if cache_in is not None:
+ cache_to_dest = min(dest.shape[dim], cache_in.shape[dim])
+ lead_in_dest, dest = split2(dest, cache_to_dest, dim=dim)
+ lead_in_source, cache_in = split2(cache_in, cache_to_dest, dim=dim)
+ lead_in_dest.add_(lead_in_source)
+ body, new_input = split2(new_input, dest.shape[dim], dim)
+ dest.add_(body)
+ return torch_cat_if_needed([cache_in, new_input], dim=dim)
+
+class Encoder(nn.Module):
+ r"""
+ The `Encoder` layer of a variational autoencoder that encodes its input into a latent representation.
+
+ Args:
+ dims (`int` or `Tuple[int, int]`, *optional*, defaults to 3):
+ The number of dimensions to use in convolutions.
+ in_channels (`int`, *optional*, defaults to 3):
+ The number of input channels.
+ out_channels (`int`, *optional*, defaults to 3):
+ The number of output channels.
+ blocks (`List[Tuple[str, int]]`, *optional*, defaults to `[("res_x", 1)]`):
+ The blocks to use. Each block is a tuple of the block name and the number of layers.
+ base_channels (`int`, *optional*, defaults to 128):
+ The number of output channels for the first convolutional layer.
+ norm_num_groups (`int`, *optional*, defaults to 32):
+ The number of groups for normalization.
+ patch_size (`int`, *optional*, defaults to 1):
+ The patch size to use. Should be a power of 2.
+ norm_layer (`str`, *optional*, defaults to `group_norm`):
+ The normalization layer to use. Can be either `group_norm` or `pixel_norm`.
+ latent_log_var (`str`, *optional*, defaults to `per_channel`):
+ The number of channels for the log variance. Can be either `per_channel`, `uniform`, `constant` or `none`.
+ """
+
+ def __init__(
+ self,
+ dims: Union[int, Tuple[int, int]] = 3,
+ in_channels: int = 3,
+ out_channels: int = 3,
+ blocks: List[Tuple[str, int | dict]] = [("res_x", 1)],
+ base_channels: int = 128,
+ norm_num_groups: int = 32,
+ patch_size: Union[int, Tuple[int]] = 1,
+ norm_layer: str = "group_norm", # group_norm, pixel_norm
+ latent_log_var: str = "per_channel",
+ spatial_padding_mode: str = "zeros",
+ ):
+ super().__init__()
+ self.patch_size = patch_size
+ self.norm_layer = norm_layer
+ self.latent_channels = out_channels
+ self.latent_log_var = latent_log_var
+ self.blocks_desc = blocks
+
+ in_channels = in_channels * patch_size**2
+ output_channel = base_channels
+
+ self.conv_in = make_conv_nd(
+ dims=dims,
+ in_channels=in_channels,
+ out_channels=output_channel,
+ kernel_size=3,
+ stride=1,
+ padding=1,
+ causal=True,
+ spatial_padding_mode=spatial_padding_mode,
+ )
+
+ self.down_blocks = nn.ModuleList([])
+
+ for block_name, block_params in blocks:
+ input_channel = output_channel
+ if isinstance(block_params, int):
+ block_params = {"num_layers": block_params}
+
+ if block_name == "res_x":
+ block = UNetMidBlock3D(
+ dims=dims,
+ in_channels=input_channel,
+ num_layers=block_params["num_layers"],
+ resnet_eps=1e-6,
+ resnet_groups=norm_num_groups,
+ norm_layer=norm_layer,
+ spatial_padding_mode=spatial_padding_mode,
+ )
+ elif block_name == "res_x_y":
+ output_channel = block_params.get("multiplier", 2) * output_channel
+ block = ResnetBlock3D(
+ dims=dims,
+ in_channels=input_channel,
+ out_channels=output_channel,
+ eps=1e-6,
+ groups=norm_num_groups,
+ norm_layer=norm_layer,
+ spatial_padding_mode=spatial_padding_mode,
+ )
+ elif block_name == "compress_time":
+ block = make_conv_nd(
+ dims=dims,
+ in_channels=input_channel,
+ out_channels=output_channel,
+ kernel_size=3,
+ stride=(2, 1, 1),
+ causal=True,
+ spatial_padding_mode=spatial_padding_mode,
+ )
+ elif block_name == "compress_space":
+ block = make_conv_nd(
+ dims=dims,
+ in_channels=input_channel,
+ out_channels=output_channel,
+ kernel_size=3,
+ stride=(1, 2, 2),
+ causal=True,
+ spatial_padding_mode=spatial_padding_mode,
+ )
+ elif block_name == "compress_all":
+ block = make_conv_nd(
+ dims=dims,
+ in_channels=input_channel,
+ out_channels=output_channel,
+ kernel_size=3,
+ stride=(2, 2, 2),
+ causal=True,
+ spatial_padding_mode=spatial_padding_mode,
+ )
+ elif block_name == "compress_all_x_y":
+ output_channel = block_params.get("multiplier", 2) * output_channel
+ block = make_conv_nd(
+ dims=dims,
+ in_channels=input_channel,
+ out_channels=output_channel,
+ kernel_size=3,
+ stride=(2, 2, 2),
+ causal=True,
+ spatial_padding_mode=spatial_padding_mode,
+ )
+ elif block_name == "compress_all_res":
+ output_channel = block_params.get("multiplier", 2) * output_channel
+ block = SpaceToDepthDownsample(
+ dims=dims,
+ in_channels=input_channel,
+ out_channels=output_channel,
+ stride=(2, 2, 2),
+ spatial_padding_mode=spatial_padding_mode,
+ )
+ elif block_name == "compress_space_res":
+ output_channel = block_params.get("multiplier", 2) * output_channel
+ block = SpaceToDepthDownsample(
+ dims=dims,
+ in_channels=input_channel,
+ out_channels=output_channel,
+ stride=(1, 2, 2),
+ spatial_padding_mode=spatial_padding_mode,
+ )
+ elif block_name == "compress_time_res":
+ output_channel = block_params.get("multiplier", 2) * output_channel
+ block = SpaceToDepthDownsample(
+ dims=dims,
+ in_channels=input_channel,
+ out_channels=output_channel,
+ stride=(2, 1, 1),
+ spatial_padding_mode=spatial_padding_mode,
+ )
+ else:
+ raise ValueError(f"unknown block: {block_name}")
+
+ self.down_blocks.append(block)
+
+ # out
+ if norm_layer == "group_norm":
+ self.conv_norm_out = nn.GroupNorm(
+ num_channels=output_channel, num_groups=norm_num_groups, eps=1e-6
+ )
+ elif norm_layer == "pixel_norm":
+ self.conv_norm_out = PixelNorm()
+ elif norm_layer == "layer_norm":
+ self.conv_norm_out = LayerNorm(output_channel, eps=1e-6)
+
+ self.conv_act = nn.SiLU()
+
+ conv_out_channels = out_channels
+ if latent_log_var == "per_channel":
+ conv_out_channels *= 2
+ elif latent_log_var == "uniform":
+ conv_out_channels += 1
+ elif latent_log_var == "constant":
+ conv_out_channels += 1
+ elif latent_log_var != "none":
+ raise ValueError(f"Invalid latent_log_var: {latent_log_var}")
+ self.conv_out = make_conv_nd(
+ dims,
+ output_channel,
+ conv_out_channels,
+ 3,
+ padding=1,
+ causal=True,
+ spatial_padding_mode=spatial_padding_mode,
+ )
+
+ self.gradient_checkpointing = False
+
+ def _forward_chunk(self, sample: torch.FloatTensor) -> Optional[torch.FloatTensor]:
+ sample = self.conv_in(sample)
+
+ checkpoint_fn = (
+ partial(torch.utils.checkpoint.checkpoint, use_reentrant=False)
+ if self.gradient_checkpointing and self.training
+ else lambda x: x
+ )
+
+ for down_block in self.down_blocks:
+ sample = checkpoint_fn(down_block)(sample)
+ if sample is None or sample.shape[2] == 0:
+ return None
+
+ sample = self.conv_norm_out(sample)
+ sample = self.conv_act(sample)
+ sample = self.conv_out(sample)
+ if sample is None or sample.shape[2] == 0:
+ return None
+
+ if self.latent_log_var == "uniform":
+ last_channel = sample[:, -1:, ...]
+ num_dims = sample.dim()
+
+ if num_dims == 4:
+ # For shape (B, C, H, W)
+ repeated_last_channel = last_channel.repeat(
+ 1, sample.shape[1] - 2, 1, 1
+ )
+ sample = torch.cat([sample, repeated_last_channel], dim=1)
+ elif num_dims == 5:
+ # For shape (B, C, F, H, W)
+ repeated_last_channel = last_channel.repeat(
+ 1, sample.shape[1] - 2, 1, 1, 1
+ )
+ sample = torch.cat([sample, repeated_last_channel], dim=1)
+ else:
+ raise ValueError(f"Invalid input shape: {sample.shape}")
+ elif self.latent_log_var == "constant":
+ sample = sample[:, :-1, ...]
+ approx_ln_0 = (
+ -30
+ ) # this is the minimal clamp value in DiagonalGaussianDistribution objects
+ sample = torch.cat(
+ [sample, torch.ones_like(sample, device=sample.device) * approx_ln_0],
+ dim=1,
+ )
+
+ return sample
+
+ def forward_orig(self, sample: torch.FloatTensor, device=None) -> torch.FloatTensor:
+ r"""The forward method of the `Encoder` class."""
+
+ max_chunk_size = get_max_chunk_size(sample.device if device is None else device) * 2 # encoder is more memory-efficient than decoder
+ frame_size = sample[:, :, :1, :, :].numel() * sample.element_size()
+ frame_size = int(frame_size * (self.conv_in.out_channels / self.conv_in.in_channels))
+
+ outputs = []
+ samples = [sample[:, :, :1, :, :]]
+ if sample.shape[2] > 1:
+ chunk_t = max(2, max_chunk_size // frame_size)
+ if chunk_t < 4:
+ chunk_t = 2
+ elif chunk_t < 8:
+ chunk_t = 4
+ else:
+ chunk_t = (chunk_t // 8) * 8
+ samples += list(torch.split(sample[:, :, 1:, :, :], chunk_t, dim=2))
+ for chunk_idx, chunk in enumerate(samples):
+ if chunk_idx == len(samples) - 1:
+ mark_conv3d_ended(self)
+ chunk = patchify(chunk, patch_size_hw=self.patch_size, patch_size_t=1).to(device=device)
+ output = self._forward_chunk(chunk)
+ if output is not None:
+ outputs.append(output)
+
+ return torch_cat_if_needed(outputs, dim=2)
+
+ def forward(self, *args, **kwargs):
+ try:
+ return self.forward_orig(*args, **kwargs)
+ finally:
+ tid = threading.get_ident()
+ for _, module in self.named_modules():
+ # ComfyUI doesn't thread this kind of stuff today, but just in case
+ # we key on the thread to make it thread safe.
+ tid = threading.get_ident()
+ if hasattr(module, "temporal_cache_state"):
+ module.temporal_cache_state.pop(tid, None)
+
+
+MIN_VRAM_FOR_CHUNK_SCALING = 6 * 1024 ** 3
+MAX_VRAM_FOR_CHUNK_SCALING = 24 * 1024 ** 3
+MIN_CHUNK_SIZE = 32 * 1024 ** 2
+MAX_CHUNK_SIZE = 128 * 1024 ** 2
+
+def get_max_chunk_size(device: torch.device) -> int:
+ total_memory = comfy.model_management.get_total_memory(dev=device)
+
+ if total_memory <= MIN_VRAM_FOR_CHUNK_SCALING:
+ return MIN_CHUNK_SIZE
+ if total_memory >= MAX_VRAM_FOR_CHUNK_SCALING:
+ return MAX_CHUNK_SIZE
+
+ interp = (total_memory - MIN_VRAM_FOR_CHUNK_SCALING) / (
+ MAX_VRAM_FOR_CHUNK_SCALING - MIN_VRAM_FOR_CHUNK_SCALING
+ )
+ return int(MIN_CHUNK_SIZE + interp * (MAX_CHUNK_SIZE - MIN_CHUNK_SIZE))
+
+class Decoder(nn.Module):
+ r"""
+ The `Decoder` layer of a variational autoencoder that decodes its latent representation into an output sample.
+
+ Args:
+ dims (`int` or `Tuple[int, int]`, *optional*, defaults to 3):
+ The number of dimensions to use in convolutions.
+ in_channels (`int`, *optional*, defaults to 3):
+ The number of input channels.
+ out_channels (`int`, *optional*, defaults to 3):
+ The number of output channels.
+ blocks (`List[Tuple[str, int]]`, *optional*, defaults to `[("res_x", 1)]`):
+ The blocks to use. Each block is a tuple of the block name and the number of layers.
+ base_channels (`int`, *optional*, defaults to 128):
+ The number of output channels for the first convolutional layer.
+ norm_num_groups (`int`, *optional*, defaults to 32):
+ The number of groups for normalization.
+ patch_size (`int`, *optional*, defaults to 1):
+ The patch size to use. Should be a power of 2.
+ norm_layer (`str`, *optional*, defaults to `group_norm`):
+ The normalization layer to use. Can be either `group_norm` or `pixel_norm`.
+ causal (`bool`, *optional*, defaults to `True`):
+ Whether to use causal convolutions or not.
+ """
+
+ def __init__(
+ self,
+ dims,
+ in_channels: int = 3,
+ out_channels: int = 3,
+ blocks: List[Tuple[str, int | dict]] = [("res_x", 1)],
+ base_channels: int = 128,
+ layers_per_block: int = 2,
+ norm_num_groups: int = 32,
+ patch_size: int = 1,
+ norm_layer: str = "group_norm",
+ causal: bool = True,
+ timestep_conditioning: bool = False,
+ spatial_padding_mode: str = "zeros",
+ ):
+ super().__init__()
+ self.patch_size = patch_size
+ self.layers_per_block = layers_per_block
+ out_channels = out_channels * patch_size**2
+ self.causal = causal
+ self.blocks_desc = blocks
+
+ # Compute output channel to be product of all channel-multiplier blocks
+ output_channel = base_channels
+ for block_name, block_params in blocks:
+ block_params = block_params if isinstance(block_params, dict) else {}
+ if block_name == "res_x_y":
+ output_channel = block_params.get("in_channels", output_channel * block_params.get("multiplier", 2))
+ if block_name == "compress_all":
+ output_channel = output_channel * block_params.get("multiplier", 1)
+ if block_name == "compress_space":
+ output_channel = output_channel * block_params.get("multiplier", 1)
+ if block_name == "compress_time":
+ output_channel = output_channel * block_params.get("multiplier", 1)
+
+ self.conv_in = make_conv_nd(
+ dims,
+ in_channels,
+ output_channel,
+ kernel_size=3,
+ stride=1,
+ padding=1,
+ causal=True,
+ spatial_padding_mode=spatial_padding_mode,
+ )
+
+ self.up_blocks = nn.ModuleList([])
+
+ for block_name, block_params in list(reversed(blocks)):
+ input_channel = output_channel
+ if isinstance(block_params, int):
+ block_params = {"num_layers": block_params}
+
+ if block_name == "res_x":
+ block = UNetMidBlock3D(
+ dims=dims,
+ in_channels=input_channel,
+ num_layers=block_params["num_layers"],
+ resnet_eps=1e-6,
+ resnet_groups=norm_num_groups,
+ norm_layer=norm_layer,
+ inject_noise=block_params.get("inject_noise", False),
+ timestep_conditioning=timestep_conditioning,
+ spatial_padding_mode=spatial_padding_mode,
+ )
+ elif block_name == "res_x_y":
+ output_channel = block_params.get("out_channels", output_channel // block_params.get("multiplier", 2))
+ block = ResnetBlock3D(
+ dims=dims,
+ in_channels=input_channel,
+ out_channels=output_channel,
+ eps=1e-6,
+ groups=norm_num_groups,
+ norm_layer=norm_layer,
+ inject_noise=block_params.get("inject_noise", False),
+ timestep_conditioning=False,
+ spatial_padding_mode=spatial_padding_mode,
+ )
+ elif block_name == "compress_time":
+ output_channel = output_channel // block_params.get("multiplier", 1)
+ block = DepthToSpaceUpsample(
+ dims=dims,
+ in_channels=input_channel,
+ stride=(2, 1, 1),
+ out_channels_reduction_factor=block_params.get("multiplier", 1),
+ spatial_padding_mode=spatial_padding_mode,
+ )
+ elif block_name == "compress_space":
+ output_channel = output_channel // block_params.get("multiplier", 1)
+ block = DepthToSpaceUpsample(
+ dims=dims,
+ in_channels=input_channel,
+ stride=(1, 2, 2),
+ out_channels_reduction_factor=block_params.get("multiplier", 1),
+ spatial_padding_mode=spatial_padding_mode,
+ )
+ elif block_name == "compress_all":
+ output_channel = output_channel // block_params.get("multiplier", 1)
+ block = DepthToSpaceUpsample(
+ dims=dims,
+ in_channels=input_channel,
+ stride=(2, 2, 2),
+ residual=block_params.get("residual", False),
+ out_channels_reduction_factor=block_params.get("multiplier", 1),
+ spatial_padding_mode=spatial_padding_mode,
+ )
+ else:
+ raise ValueError(f"unknown layer: {block_name}")
+
+ self.up_blocks.append(block)
+
+ if norm_layer == "group_norm":
+ self.conv_norm_out = nn.GroupNorm(
+ num_channels=output_channel, num_groups=norm_num_groups, eps=1e-6
+ )
+ elif norm_layer == "pixel_norm":
+ self.conv_norm_out = PixelNorm()
+ elif norm_layer == "layer_norm":
+ self.conv_norm_out = LayerNorm(output_channel, eps=1e-6)
+
+ self.conv_act = nn.SiLU()
+ self.conv_out = make_conv_nd(
+ dims,
+ output_channel,
+ out_channels,
+ 3,
+ padding=1,
+ causal=True,
+ spatial_padding_mode=spatial_padding_mode,
+ )
+
+ self.gradient_checkpointing = False
+
+ # Precompute output scale factors: (channels, (t_scale, h_scale, w_scale), t_offset)
+ ts, hs, ws, to = 1, 1, 1, 0
+ for block in self.up_blocks:
+ if isinstance(block, DepthToSpaceUpsample):
+ ts *= block.stride[0]
+ hs *= block.stride[1]
+ ws *= block.stride[2]
+ if block.stride[0] > 1:
+ to = to * block.stride[0] + 1
+ self._output_scale = (out_channels // (patch_size ** 2), (ts, hs * patch_size, ws * patch_size), to)
+
+ self.timestep_conditioning = timestep_conditioning
+
+ if timestep_conditioning:
+ self.timestep_scale_multiplier = nn.Parameter(
+ torch.tensor(1000.0, dtype=torch.float32)
+ )
+ self.last_time_embedder = PixArtAlphaCombinedTimestepSizeEmbeddings(
+ output_channel * 2, 0, operations=ops,
+ )
+ self.last_scale_shift_table = nn.Parameter(torch.empty(2, output_channel))
+ else:
+ self.register_buffer(
+ "last_scale_shift_table",
+ torch.tensor(
+ [0.0, 0.0],
+ device="cpu" if in_meta_context() else None
+ ).unsqueeze(1).expand(2, output_channel),
+ persistent=False,
+ )
+
+
+ def decode_output_shape(self, input_shape):
+ c, (ts, hs, ws), to = self._output_scale
+ return (input_shape[0], c, input_shape[2] * ts - to, input_shape[3] * hs, input_shape[4] * ws)
+
+ def run_up(self, idx, sample_ref, ended, timestep_shift_scale, scaled_timestep, checkpoint_fn, output_buffer, output_offset, max_chunk_size):
+ sample = sample_ref[0]
+ sample_ref[0] = None
+ if idx >= len(self.up_blocks):
+ sample = self.conv_norm_out(sample)
+ if timestep_shift_scale is not None:
+ shift, scale = timestep_shift_scale
+ sample = sample * (1 + scale) + shift
+ sample = self.conv_act(sample)
+ if ended:
+ mark_conv3d_ended(self.conv_out)
+ sample = self.conv_out(sample, causal=self.causal)
+ if sample is not None and sample.shape[2] > 0:
+ sample = unpatchify(sample, patch_size_hw=self.patch_size, patch_size_t=1)
+ t = sample.shape[2]
+ output_buffer[:, :, output_offset[0]:output_offset[0] + t].copy_(sample)
+ output_offset[0] += t
+ return
+
+ up_block = self.up_blocks[idx]
+ if ended:
+ mark_conv3d_ended(up_block)
+ if self.timestep_conditioning and isinstance(up_block, UNetMidBlock3D):
+ sample = checkpoint_fn(up_block)(
+ sample, causal=self.causal, timestep=scaled_timestep
+ )
+ else:
+ sample = checkpoint_fn(up_block)(sample, causal=self.causal)
+
+ if sample is None or sample.shape[2] == 0:
+ return
+
+ total_bytes = sample.numel() * sample.element_size()
+ num_chunks = (total_bytes + max_chunk_size - 1) // max_chunk_size
+
+ if num_chunks == 1:
+ # when we are not chunking, detach our x so the callee can free it as soon as they are done
+ next_sample_ref = [sample]
+ del sample
+ self.run_up(idx + 1, next_sample_ref, ended, timestep_shift_scale, scaled_timestep, checkpoint_fn, output_buffer, output_offset, max_chunk_size)
+ return
+ else:
+ samples = torch.chunk(sample, chunks=num_chunks, dim=2)
+
+ for chunk_idx, sample1 in enumerate(samples):
+ self.run_up(idx + 1, [sample1], ended and chunk_idx == len(samples) - 1, timestep_shift_scale, scaled_timestep, checkpoint_fn, output_buffer, output_offset, max_chunk_size)
+
+ def forward_orig(
+ self,
+ sample: torch.FloatTensor,
+ timestep: Optional[torch.Tensor] = None,
+ output_buffer: Optional[torch.Tensor] = None,
+ ) -> torch.FloatTensor:
+ r"""The forward method of the `Decoder` class."""
+ batch_size = sample.shape[0]
+
+ mark_conv3d_ended(self.conv_in)
+ sample = self.conv_in(sample, causal=self.causal)
+
+ checkpoint_fn = (
+ partial(torch.utils.checkpoint.checkpoint, use_reentrant=False)
+ if self.gradient_checkpointing and self.training
+ else lambda x: x
+ )
+
+ timestep_shift_scale = None
+ scaled_timestep = None
+ if self.timestep_conditioning:
+ assert (
+ timestep is not None
+ ), "should pass timestep with timestep_conditioning=True"
+ scaled_timestep = timestep * self.timestep_scale_multiplier.to(dtype=sample.dtype, device=sample.device)
+ embedded_timestep = self.last_time_embedder(
+ timestep=scaled_timestep.flatten(),
+ resolution=None,
+ aspect_ratio=None,
+ batch_size=sample.shape[0],
+ hidden_dtype=sample.dtype,
+ )
+ embedded_timestep = embedded_timestep.view(
+ batch_size, embedded_timestep.shape[-1], 1, 1, 1
+ )
+ ada_values = self.last_scale_shift_table[
+ None, ..., None, None, None
+ ].to(device=sample.device, dtype=sample.dtype) + embedded_timestep.reshape(
+ batch_size,
+ 2,
+ -1,
+ embedded_timestep.shape[-3],
+ embedded_timestep.shape[-2],
+ embedded_timestep.shape[-1],
+ )
+ timestep_shift_scale = ada_values.unbind(dim=1)
+
+ if output_buffer is None:
+ output_buffer = torch.empty(
+ self.decode_output_shape(sample.shape),
+ dtype=sample.dtype, device=comfy.model_management.intermediate_device(),
+ )
+ output_offset = [0]
+
+ max_chunk_size = get_max_chunk_size(sample.device)
+
+ self.run_up(0, [sample], True, timestep_shift_scale, scaled_timestep, checkpoint_fn, output_buffer, output_offset, max_chunk_size)
+
+ return output_buffer
+
+ def forward(self, *args, **kwargs):
+ try:
+ return self.forward_orig(*args, **kwargs)
+ finally:
+ for _, module in self.named_modules():
+ #ComfyUI doesn't thread this kind of stuff today, but just incase
+ #we key on the thread to make it thread safe.
+ tid = threading.get_ident()
+ if hasattr(module, "temporal_cache_state"):
+ module.temporal_cache_state.pop(tid, None)
+
+
+class UNetMidBlock3D(nn.Module):
+ """
+ A 3D UNet mid-block [`UNetMidBlock3D`] with multiple residual blocks.
+
+ Args:
+ in_channels (`int`): The number of input channels.
+ dropout (`float`, *optional*, defaults to 0.0): The dropout rate.
+ num_layers (`int`, *optional*, defaults to 1): The number of residual blocks.
+ resnet_eps (`float`, *optional*, 1e-6 ): The epsilon value for the resnet blocks.
+ resnet_groups (`int`, *optional*, defaults to 32):
+ The number of groups to use in the group normalization layers of the resnet blocks.
+ norm_layer (`str`, *optional*, defaults to `group_norm`):
+ The normalization layer to use. Can be either `group_norm` or `pixel_norm`.
+ inject_noise (`bool`, *optional*, defaults to `False`):
+ Whether to inject noise into the hidden states.
+ timestep_conditioning (`bool`, *optional*, defaults to `False`):
+ Whether to condition the hidden states on the timestep.
+
+ Returns:
+ `torch.FloatTensor`: The output of the last residual block, which is a tensor of shape `(batch_size,
+ in_channels, height, width)`.
+
+ """
+
+ def __init__(
+ self,
+ dims: Union[int, Tuple[int, int]],
+ in_channels: int,
+ dropout: float = 0.0,
+ num_layers: int = 1,
+ resnet_eps: float = 1e-6,
+ resnet_groups: int = 32,
+ norm_layer: str = "group_norm",
+ inject_noise: bool = False,
+ timestep_conditioning: bool = False,
+ spatial_padding_mode: str = "zeros",
+ ):
+ super().__init__()
+ resnet_groups = (
+ resnet_groups if resnet_groups is not None else min(in_channels // 4, 32)
+ )
+
+ self.timestep_conditioning = timestep_conditioning
+
+ if timestep_conditioning:
+ self.time_embedder = PixArtAlphaCombinedTimestepSizeEmbeddings(
+ in_channels * 4, 0, operations=ops,
+ )
+
+ self.res_blocks = nn.ModuleList(
+ [
+ ResnetBlock3D(
+ dims=dims,
+ in_channels=in_channels,
+ out_channels=in_channels,
+ eps=resnet_eps,
+ groups=resnet_groups,
+ dropout=dropout,
+ norm_layer=norm_layer,
+ inject_noise=inject_noise,
+ timestep_conditioning=timestep_conditioning,
+ spatial_padding_mode=spatial_padding_mode,
+ )
+ for _ in range(num_layers)
+ ]
+ )
+
+ def forward(
+ self,
+ hidden_states: torch.FloatTensor,
+ causal: bool = True,
+ timestep: Optional[torch.Tensor] = None,
+ ) -> torch.FloatTensor:
+ timestep_embed = None
+ if self.timestep_conditioning:
+ assert (
+ timestep is not None
+ ), "should pass timestep with timestep_conditioning=True"
+ batch_size = hidden_states.shape[0]
+ timestep_embed = self.time_embedder(
+ timestep=timestep.flatten(),
+ resolution=None,
+ aspect_ratio=None,
+ batch_size=batch_size,
+ hidden_dtype=hidden_states.dtype,
+ )
+ timestep_embed = timestep_embed.view(
+ batch_size, timestep_embed.shape[-1], 1, 1, 1
+ )
+
+ for resnet in self.res_blocks:
+ hidden_states = resnet(hidden_states, causal=causal, timestep=timestep_embed)
+
+ return hidden_states
+
+
+class SpaceToDepthDownsample(nn.Module):
+ def __init__(self, dims, in_channels, out_channels, stride, spatial_padding_mode):
+ super().__init__()
+ self.stride = stride
+ self.group_size = in_channels * math.prod(stride) // out_channels
+ self.conv = make_conv_nd(
+ dims=dims,
+ in_channels=in_channels,
+ out_channels=out_channels // math.prod(stride),
+ kernel_size=3,
+ stride=1,
+ causal=True,
+ spatial_padding_mode=spatial_padding_mode,
+ )
+ self.temporal_cache_state = {}
+
+ def forward(self, x, causal: bool = True):
+ tid = threading.get_ident()
+ cached, pad_first, cached_x, cached_input = self.temporal_cache_state.get(tid, (None, True, None, None))
+ if cached_input is not None:
+ x = torch_cat_if_needed([cached_input, x], dim=2)
+ cached_input = None
+
+ if self.stride[0] == 2 and pad_first:
+ x = torch.cat(
+ [x[:, :, :1, :, :], x], dim=2
+ ) # duplicate first frames for padding
+ pad_first = False
+
+ if x.shape[2] < self.stride[0]:
+ cached_input = x
+ self.temporal_cache_state[tid] = (cached, pad_first, cached_x, cached_input)
+ return None
+
+ # skip connection
+ x_in = rearrange(
+ x,
+ "b c (d p1) (h p2) (w p3) -> b (c p1 p2 p3) d h w",
+ p1=self.stride[0],
+ p2=self.stride[1],
+ p3=self.stride[2],
+ )
+ x_in = rearrange(x_in, "b (c g) d h w -> b c g d h w", g=self.group_size)
+ x_in = x_in.mean(dim=2)
+
+ # conv
+ x = self.conv(x, causal=causal)
+ if self.stride[0] == 2 and x.shape[2] == 1:
+ if cached_x is not None:
+ x = torch_cat_if_needed([cached_x, x], dim=2)
+ cached_x = None
+ else:
+ cached_x = x
+ x = None
+
+ if x is not None:
+ x = rearrange(
+ x,
+ "b c (d p1) (h p2) (w p3) -> b (c p1 p2 p3) d h w",
+ p1=self.stride[0],
+ p2=self.stride[1],
+ p3=self.stride[2],
+ )
+
+ cached = add_exchange_cache(x, cached, x_in, dim=2)
+
+ self.temporal_cache_state[tid] = (cached, pad_first, cached_x, cached_input)
+
+ return x
+
+
+class DepthToSpaceUpsample(nn.Module):
+ def __init__(
+ self,
+ dims,
+ in_channels,
+ stride,
+ residual=False,
+ out_channels_reduction_factor=1,
+ spatial_padding_mode="zeros",
+ ):
+ super().__init__()
+ self.stride = stride
+ self.out_channels = (
+ math.prod(stride) * in_channels // out_channels_reduction_factor
+ )
+ self.conv = make_conv_nd(
+ dims=dims,
+ in_channels=in_channels,
+ out_channels=self.out_channels,
+ kernel_size=3,
+ stride=1,
+ causal=True,
+ spatial_padding_mode=spatial_padding_mode,
+ )
+ self.residual = residual
+ self.out_channels_reduction_factor = out_channels_reduction_factor
+ self.temporal_cache_state = {}
+
+ def forward(self, x, causal: bool = True, timestep: Optional[torch.Tensor] = None):
+ tid = threading.get_ident()
+ cached, drop_first_conv, drop_first_res = self.temporal_cache_state.get(tid, (None, True, True))
+ y = self.conv(x, causal=causal)
+ y = rearrange(
+ y,
+ "b (c p1 p2 p3) d h w -> b c (d p1) (h p2) (w p3)",
+ p1=self.stride[0],
+ p2=self.stride[1],
+ p3=self.stride[2],
+ )
+ if self.stride[0] == 2 and y.shape[2] > 0 and drop_first_conv:
+ y = y[:, :, 1:, :, :]
+ drop_first_conv = False
+ if self.residual:
+ # Reshape and duplicate the input to match the output shape
+ x_in = rearrange(
+ x,
+ "b (c p1 p2 p3) d h w -> b c (d p1) (h p2) (w p3)",
+ p1=self.stride[0],
+ p2=self.stride[1],
+ p3=self.stride[2],
+ )
+ num_repeat = math.prod(self.stride) // self.out_channels_reduction_factor
+ x_in = x_in.repeat(1, num_repeat, 1, 1, 1)
+ if self.stride[0] == 2 and x_in.shape[2] > 0 and drop_first_res:
+ x_in = x_in[:, :, 1:, :, :]
+ drop_first_res = False
+
+ if y.shape[2] == 0:
+ y = None
+
+ cached = add_exchange_cache(y, cached, x_in, dim=2)
+ self.temporal_cache_state[tid] = (cached, drop_first_conv, drop_first_res)
+
+ else:
+ self.temporal_cache_state[tid] = (None, drop_first_conv, False)
+
+ return y
+
+class LayerNorm(nn.Module):
+ def __init__(self, dim, eps, elementwise_affine=True) -> None:
+ super().__init__()
+ self.norm = ops.LayerNorm(dim, eps=eps, elementwise_affine=elementwise_affine)
+
+ def forward(self, x):
+ x = rearrange(x, "b c d h w -> b d h w c")
+ x = self.norm(x)
+ x = rearrange(x, "b d h w c -> b c d h w")
+ return x
+
+
+class ResnetBlock3D(nn.Module):
+ r"""
+ A Resnet block.
+
+ Parameters:
+ in_channels (`int`): The number of channels in the input.
+ out_channels (`int`, *optional*, default to be `None`):
+ The number of output channels for the first conv layer. If None, same as `in_channels`.
+ dropout (`float`, *optional*, defaults to `0.0`): The dropout probability to use.
+ groups (`int`, *optional*, default to `32`): The number of groups to use for the first normalization layer.
+ eps (`float`, *optional*, defaults to `1e-6`): The epsilon to use for the normalization.
+ """
+
+ def __init__(
+ self,
+ dims: Union[int, Tuple[int, int]],
+ in_channels: int,
+ out_channels: Optional[int] = None,
+ dropout: float = 0.0,
+ groups: int = 32,
+ eps: float = 1e-6,
+ norm_layer: str = "group_norm",
+ inject_noise: bool = False,
+ timestep_conditioning: bool = False,
+ spatial_padding_mode: str = "zeros",
+ ):
+ super().__init__()
+ self.in_channels = in_channels
+ out_channels = in_channels if out_channels is None else out_channels
+ self.out_channels = out_channels
+ self.inject_noise = inject_noise
+
+ if norm_layer == "group_norm":
+ self.norm1 = nn.GroupNorm(
+ num_groups=groups, num_channels=in_channels, eps=eps, affine=True
+ )
+ elif norm_layer == "pixel_norm":
+ self.norm1 = PixelNorm()
+ elif norm_layer == "layer_norm":
+ self.norm1 = LayerNorm(in_channels, eps=eps, elementwise_affine=True)
+
+ self.non_linearity = nn.SiLU()
+
+ self.conv1 = make_conv_nd(
+ dims,
+ in_channels,
+ out_channels,
+ kernel_size=3,
+ stride=1,
+ padding=1,
+ causal=True,
+ spatial_padding_mode=spatial_padding_mode,
+ )
+
+ if inject_noise:
+ self.per_channel_scale1 = nn.Parameter(torch.zeros((in_channels, 1, 1)))
+
+ if norm_layer == "group_norm":
+ self.norm2 = nn.GroupNorm(
+ num_groups=groups, num_channels=out_channels, eps=eps, affine=True
+ )
+ elif norm_layer == "pixel_norm":
+ self.norm2 = PixelNorm()
+ elif norm_layer == "layer_norm":
+ self.norm2 = LayerNorm(out_channels, eps=eps, elementwise_affine=True)
+
+ self.dropout = torch.nn.Dropout(dropout)
+
+ self.conv2 = make_conv_nd(
+ dims,
+ out_channels,
+ out_channels,
+ kernel_size=3,
+ stride=1,
+ padding=1,
+ causal=True,
+ spatial_padding_mode=spatial_padding_mode,
+ )
+
+ if inject_noise:
+ self.per_channel_scale2 = nn.Parameter(torch.zeros((in_channels, 1, 1)))
+
+ self.conv_shortcut = (
+ make_linear_nd(
+ dims=dims, in_channels=in_channels, out_channels=out_channels
+ )
+ if in_channels != out_channels
+ else nn.Identity()
+ )
+
+ self.norm3 = (
+ LayerNorm(in_channels, eps=eps, elementwise_affine=True)
+ if in_channels != out_channels
+ else nn.Identity()
+ )
+
+ self.timestep_conditioning = timestep_conditioning
+
+ if timestep_conditioning:
+ self.scale_shift_table = nn.Parameter(
+ torch.randn(4, in_channels) / in_channels**0.5
+ )
+ else:
+ self.register_buffer(
+ "scale_shift_table",
+ torch.tensor(
+ [0.0, 0.0, 0.0, 0.0],
+ device="cpu" if in_meta_context() else None
+ ).unsqueeze(1).expand(4, in_channels),
+ persistent=False,
+ )
+
+ self.temporal_cache_state={}
+
+ def _feed_spatial_noise(
+ self, hidden_states: torch.FloatTensor, per_channel_scale: torch.FloatTensor
+ ) -> torch.FloatTensor:
+ spatial_shape = hidden_states.shape[-2:]
+ device = hidden_states.device
+ dtype = hidden_states.dtype
+
+ # similar to the "explicit noise inputs" method in style-gan
+ spatial_noise = torch.randn(spatial_shape, device=device, dtype=dtype)[None]
+ scaled_noise = (spatial_noise * per_channel_scale)[None, :, None, ...]
+ hidden_states = hidden_states + scaled_noise
+
+ return hidden_states
+
+ def forward(
+ self,
+ input_tensor: torch.FloatTensor,
+ causal: bool = True,
+ timestep: Optional[torch.Tensor] = None,
+ ) -> torch.FloatTensor:
+ hidden_states = input_tensor
+ batch_size = hidden_states.shape[0]
+
+ hidden_states = self.norm1(hidden_states)
+ if self.timestep_conditioning:
+ assert (
+ timestep is not None
+ ), "should pass timestep with timestep_conditioning=True"
+ ada_values = self.scale_shift_table[
+ None, ..., None, None, None
+ ].to(device=hidden_states.device, dtype=hidden_states.dtype) + timestep.reshape(
+ batch_size,
+ 4,
+ -1,
+ timestep.shape[-3],
+ timestep.shape[-2],
+ timestep.shape[-1],
+ )
+ shift1, scale1, shift2, scale2 = ada_values.unbind(dim=1)
+
+ hidden_states = hidden_states * (1 + scale1) + shift1
+
+ hidden_states = self.non_linearity(hidden_states)
+
+ hidden_states = self.conv1(hidden_states, causal=causal)
+
+ if self.inject_noise:
+ hidden_states = self._feed_spatial_noise(
+ hidden_states, self.per_channel_scale1.to(device=hidden_states.device, dtype=hidden_states.dtype)
+ )
+
+ hidden_states = self.norm2(hidden_states)
+
+ if self.timestep_conditioning:
+ hidden_states = hidden_states * (1 + scale2) + shift2
+
+ hidden_states = self.non_linearity(hidden_states)
+
+ hidden_states = self.dropout(hidden_states)
+
+ hidden_states = self.conv2(hidden_states, causal=causal)
+
+ if self.inject_noise:
+ hidden_states = self._feed_spatial_noise(
+ hidden_states, self.per_channel_scale2.to(device=hidden_states.device, dtype=hidden_states.dtype)
+ )
+
+ input_tensor = self.norm3(input_tensor)
+
+ batch_size = input_tensor.shape[0]
+
+ input_tensor = self.conv_shortcut(input_tensor)
+
+ tid = threading.get_ident()
+ cached = self.temporal_cache_state.get(tid, None)
+ cached = add_exchange_cache(hidden_states, cached, input_tensor, dim=2)
+ self.temporal_cache_state[tid] = cached
+
+ return hidden_states
+
+
+def patchify(x, patch_size_hw, patch_size_t=1):
+ if patch_size_hw == 1 and patch_size_t == 1:
+ return x
+ if x.dim() == 4:
+ x = rearrange(
+ x, "b c (h q) (w r) -> b (c r q) h w", q=patch_size_hw, r=patch_size_hw
+ )
+ elif x.dim() == 5:
+ x = rearrange(
+ x,
+ "b c (f p) (h q) (w r) -> b (c p r q) f h w",
+ p=patch_size_t,
+ q=patch_size_hw,
+ r=patch_size_hw,
+ )
+ else:
+ raise ValueError(f"Invalid input shape: {x.shape}")
+
+ return x
+
+
+def unpatchify(x, patch_size_hw, patch_size_t=1):
+ if patch_size_hw == 1 and patch_size_t == 1:
+ return x
+
+ if x.dim() == 4:
+ x = rearrange(
+ x, "b (c r q) h w -> b c (h q) (w r)", q=patch_size_hw, r=patch_size_hw
+ )
+ elif x.dim() == 5:
+ x = rearrange(
+ x,
+ "b (c p r q) f h w -> b c (f p) (h q) (w r)",
+ p=patch_size_t,
+ q=patch_size_hw,
+ r=patch_size_hw,
+ )
+
+ return x
+
+class processor(nn.Module):
+ def __init__(self):
+ super().__init__()
+ self.register_buffer("std-of-means", torch.empty(128))
+ self.register_buffer("mean-of-means", torch.empty(128))
+
+ def un_normalize(self, x):
+ return (x * self.get_buffer("std-of-means").view(1, -1, 1, 1, 1).to(x)) + self.get_buffer("mean-of-means").view(1, -1, 1, 1, 1).to(x)
+
+ def normalize(self, x):
+ return (x - self.get_buffer("mean-of-means").view(1, -1, 1, 1, 1).to(x)) / self.get_buffer("std-of-means").view(1, -1, 1, 1, 1).to(x)
+
+class VideoVAE(nn.Module):
+ comfy_has_chunked_io = True
+
+ def __init__(self, version=0, config=None):
+ super().__init__()
+
+ if config is None:
+ config = self.get_default_config(version)
+
+ self.config = config
+ self.timestep_conditioning = config.get("timestep_conditioning", False)
+ self.decode_noise_scale = config.get("decode_noise_scale", 0.025)
+ self.decode_timestep = config.get("decode_timestep", 0.05)
+ double_z = config.get("double_z", True)
+ latent_log_var = config.get(
+ "latent_log_var", "per_channel" if double_z else "none"
+ )
+
+ self.encoder = Encoder(
+ dims=config["dims"],
+ in_channels=config.get("in_channels", 3),
+ out_channels=config["latent_channels"],
+ blocks=config.get("encoder_blocks", config.get("encoder_blocks", config.get("blocks"))),
+ patch_size=config.get("patch_size", 1),
+ latent_log_var=latent_log_var,
+ norm_layer=config.get("norm_layer", "group_norm"),
+ spatial_padding_mode=config.get("spatial_padding_mode", "zeros"),
+ base_channels=config.get("encoder_base_channels", 128),
+ )
+
+ self.decoder = Decoder(
+ dims=config["dims"],
+ in_channels=config["latent_channels"],
+ out_channels=config.get("out_channels", 3),
+ blocks=config.get("decoder_blocks", config.get("decoder_blocks", config.get("blocks"))),
+ base_channels=config.get("decoder_base_channels", 128),
+ patch_size=config.get("patch_size", 1),
+ norm_layer=config.get("norm_layer", "group_norm"),
+ causal=config.get("causal_decoder", False),
+ timestep_conditioning=self.timestep_conditioning,
+ spatial_padding_mode=config.get("spatial_padding_mode", "reflect"),
+ )
+
+ self.per_channel_statistics = processor()
+
+ def get_default_config(self, version):
+ if version == 0:
+ config = {
+ "_class_name": "CausalVideoAutoencoder",
+ "dims": 3,
+ "in_channels": 3,
+ "out_channels": 3,
+ "latent_channels": 128,
+ "blocks": [
+ ["res_x", 4],
+ ["compress_all", 1],
+ ["res_x_y", 1],
+ ["res_x", 3],
+ ["compress_all", 1],
+ ["res_x_y", 1],
+ ["res_x", 3],
+ ["compress_all", 1],
+ ["res_x", 3],
+ ["res_x", 4],
+ ],
+ "scaling_factor": 1.0,
+ "norm_layer": "pixel_norm",
+ "patch_size": 4,
+ "latent_log_var": "uniform",
+ "use_quant_conv": False,
+ "causal_decoder": False,
+ }
+ elif version == 1:
+ config = {
+ "_class_name": "CausalVideoAutoencoder",
+ "dims": 3,
+ "in_channels": 3,
+ "out_channels": 3,
+ "latent_channels": 128,
+ "decoder_blocks": [
+ ["res_x", {"num_layers": 5, "inject_noise": True}],
+ ["compress_all", {"residual": True, "multiplier": 2}],
+ ["res_x", {"num_layers": 6, "inject_noise": True}],
+ ["compress_all", {"residual": True, "multiplier": 2}],
+ ["res_x", {"num_layers": 7, "inject_noise": True}],
+ ["compress_all", {"residual": True, "multiplier": 2}],
+ ["res_x", {"num_layers": 8, "inject_noise": False}]
+ ],
+ "encoder_blocks": [
+ ["res_x", {"num_layers": 4}],
+ ["compress_all", {}],
+ ["res_x_y", 1],
+ ["res_x", {"num_layers": 3}],
+ ["compress_all", {}],
+ ["res_x_y", 1],
+ ["res_x", {"num_layers": 3}],
+ ["compress_all", {}],
+ ["res_x", {"num_layers": 3}],
+ ["res_x", {"num_layers": 4}]
+ ],
+ "scaling_factor": 1.0,
+ "norm_layer": "pixel_norm",
+ "patch_size": 4,
+ "latent_log_var": "uniform",
+ "use_quant_conv": False,
+ "causal_decoder": False,
+ "timestep_conditioning": True,
+ }
+ else:
+ config = {
+ "_class_name": "CausalVideoAutoencoder",
+ "dims": 3,
+ "in_channels": 3,
+ "out_channels": 3,
+ "latent_channels": 128,
+ "encoder_blocks": [
+ ["res_x", {"num_layers": 4}],
+ ["compress_space_res", {"multiplier": 2}],
+ ["res_x", {"num_layers": 6}],
+ ["compress_time_res", {"multiplier": 2}],
+ ["res_x", {"num_layers": 6}],
+ ["compress_all_res", {"multiplier": 2}],
+ ["res_x", {"num_layers": 2}],
+ ["compress_all_res", {"multiplier": 2}],
+ ["res_x", {"num_layers": 2}]
+ ],
+ "decoder_blocks": [
+ ["res_x", {"num_layers": 5, "inject_noise": False}],
+ ["compress_all", {"residual": True, "multiplier": 2}],
+ ["res_x", {"num_layers": 5, "inject_noise": False}],
+ ["compress_all", {"residual": True, "multiplier": 2}],
+ ["res_x", {"num_layers": 5, "inject_noise": False}],
+ ["compress_all", {"residual": True, "multiplier": 2}],
+ ["res_x", {"num_layers": 5, "inject_noise": False}]
+ ],
+ "scaling_factor": 1.0,
+ "norm_layer": "pixel_norm",
+ "patch_size": 4,
+ "latent_log_var": "uniform",
+ "use_quant_conv": False,
+ "causal_decoder": False,
+ "timestep_conditioning": True
+ }
+ return config
+
+ def encode(self, x, device=None):
+ x = x[:, :, :max(1, 1 + ((x.shape[2] - 1) // 8) * 8), :, :]
+ means, logvar = torch.chunk(self.encoder(x, device=device), 2, dim=1)
+ return self.per_channel_statistics.normalize(means)
+
+ def decode_output_shape(self, input_shape):
+ return self.decoder.decode_output_shape(input_shape)
+
+ def decode(self, x, output_buffer=None):
+ if self.timestep_conditioning: #TODO: seed
+ x = torch.randn_like(x) * self.decode_noise_scale + (1.0 - self.decode_noise_scale) * x
+ return self.decoder(self.per_channel_statistics.un_normalize(x), timestep=self.decode_timestep, output_buffer=output_buffer)
diff --git a/ComfyUI/comfy/ldm/lightricks/vae/conv_nd_factory.py b/ComfyUI/comfy/ldm/lightricks/vae/conv_nd_factory.py
new file mode 100644
index 0000000000000000000000000000000000000000..b4026b14fae386850459b18fb06e8b5d7f79ab94
--- /dev/null
+++ b/ComfyUI/comfy/ldm/lightricks/vae/conv_nd_factory.py
@@ -0,0 +1,90 @@
+from typing import Tuple, Union
+
+
+from .dual_conv3d import DualConv3d
+from .causal_conv3d import CausalConv3d
+import comfy.ops
+ops = comfy.ops.disable_weight_init
+
+def make_conv_nd(
+ dims: Union[int, Tuple[int, int]],
+ in_channels: int,
+ out_channels: int,
+ kernel_size: int,
+ stride=1,
+ padding=0,
+ dilation=1,
+ groups=1,
+ bias=True,
+ causal=False,
+ spatial_padding_mode="zeros",
+ temporal_padding_mode="zeros",
+):
+ if not (spatial_padding_mode == temporal_padding_mode or causal):
+ raise NotImplementedError("spatial and temporal padding modes must be equal")
+ if dims == 2:
+ return ops.Conv2d(
+ in_channels=in_channels,
+ out_channels=out_channels,
+ kernel_size=kernel_size,
+ stride=stride,
+ padding=padding,
+ dilation=dilation,
+ groups=groups,
+ bias=bias,
+ padding_mode=spatial_padding_mode,
+ )
+ elif dims == 3:
+ if causal:
+ return CausalConv3d(
+ in_channels=in_channels,
+ out_channels=out_channels,
+ kernel_size=kernel_size,
+ stride=stride,
+ padding=padding,
+ dilation=dilation,
+ groups=groups,
+ bias=bias,
+ spatial_padding_mode=spatial_padding_mode,
+ )
+ return ops.Conv3d(
+ in_channels=in_channels,
+ out_channels=out_channels,
+ kernel_size=kernel_size,
+ stride=stride,
+ padding=padding,
+ dilation=dilation,
+ groups=groups,
+ bias=bias,
+ padding_mode=spatial_padding_mode,
+ )
+ elif dims == (2, 1):
+ return DualConv3d(
+ in_channels=in_channels,
+ out_channels=out_channels,
+ kernel_size=kernel_size,
+ stride=stride,
+ padding=padding,
+ bias=bias,
+ padding_mode=spatial_padding_mode,
+ )
+ else:
+ raise ValueError(f"unsupported dimensions: {dims}")
+
+
+def make_linear_nd(
+ dims: int,
+ in_channels: int,
+ out_channels: int,
+ bias=True,
+):
+ if dims == 2:
+ return ops.Conv2d(
+ in_channels=in_channels, out_channels=out_channels, kernel_size=1, bias=bias
+ )
+ elif dims == 3 or dims == (2, 1):
+ return ops.Conv3d(
+ in_channels=in_channels, out_channels=out_channels, kernel_size=1, bias=bias
+ )
+ else:
+ raise ValueError(f"unsupported dimensions: {dims}")
diff --git a/ComfyUI/comfy/ldm/lightricks/vae/dual_conv3d.py b/ComfyUI/comfy/ldm/lightricks/vae/dual_conv3d.py
new file mode 100644
index 0000000000000000000000000000000000000000..dcf889296750d3d7e553af37ecf77d1b10245af3
--- /dev/null
+++ b/ComfyUI/comfy/ldm/lightricks/vae/dual_conv3d.py
@@ -0,0 +1,217 @@
+import math
+from typing import Tuple, Union
+
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+from einops import rearrange
+
+
+class DualConv3d(nn.Module):
+ def __init__(
+ self,
+ in_channels,
+ out_channels,
+ kernel_size,
+ stride: Union[int, Tuple[int, int, int]] = 1,
+ padding: Union[int, Tuple[int, int, int]] = 0,
+ dilation: Union[int, Tuple[int, int, int]] = 1,
+ groups=1,
+ bias=True,
+ padding_mode="zeros",
+ ):
+ super(DualConv3d, self).__init__()
+
+ self.in_channels = in_channels
+ self.out_channels = out_channels
+ self.padding_mode = padding_mode
+ # Ensure kernel_size, stride, padding, and dilation are tuples of length 3
+ if isinstance(kernel_size, int):
+ kernel_size = (kernel_size, kernel_size, kernel_size)
+ if kernel_size == (1, 1, 1):
+ raise ValueError(
+ "kernel_size must be greater than 1. Use make_linear_nd instead."
+ )
+ if isinstance(stride, int):
+ stride = (stride, stride, stride)
+ if isinstance(padding, int):
+ padding = (padding, padding, padding)
+ if isinstance(dilation, int):
+ dilation = (dilation, dilation, dilation)
+
+ # Set parameters for convolutions
+ self.groups = groups
+ self.bias = bias
+
+ # Define the size of the channels after the first convolution
+ intermediate_channels = (
+ out_channels if in_channels < out_channels else in_channels
+ )
+
+ # Define parameters for the first convolution
+ self.weight1 = nn.Parameter(
+ torch.Tensor(
+ intermediate_channels,
+ in_channels // groups,
+ 1,
+ kernel_size[1],
+ kernel_size[2],
+ )
+ )
+ self.stride1 = (1, stride[1], stride[2])
+ self.padding1 = (0, padding[1], padding[2])
+ self.dilation1 = (1, dilation[1], dilation[2])
+ if bias:
+ self.bias1 = nn.Parameter(torch.Tensor(intermediate_channels))
+ else:
+ self.register_parameter("bias1", None)
+
+ # Define parameters for the second convolution
+ self.weight2 = nn.Parameter(
+ torch.Tensor(
+ out_channels, intermediate_channels // groups, kernel_size[0], 1, 1
+ )
+ )
+ self.stride2 = (stride[0], 1, 1)
+ self.padding2 = (padding[0], 0, 0)
+ self.dilation2 = (dilation[0], 1, 1)
+ if bias:
+ self.bias2 = nn.Parameter(torch.Tensor(out_channels))
+ else:
+ self.register_parameter("bias2", None)
+
+ # Initialize weights and biases
+ self.reset_parameters()
+
+ def reset_parameters(self):
+ nn.init.kaiming_uniform_(self.weight1, a=math.sqrt(5))
+ nn.init.kaiming_uniform_(self.weight2, a=math.sqrt(5))
+ if self.bias:
+ fan_in1, _ = nn.init._calculate_fan_in_and_fan_out(self.weight1)
+ bound1 = 1 / math.sqrt(fan_in1)
+ nn.init.uniform_(self.bias1, -bound1, bound1)
+ fan_in2, _ = nn.init._calculate_fan_in_and_fan_out(self.weight2)
+ bound2 = 1 / math.sqrt(fan_in2)
+ nn.init.uniform_(self.bias2, -bound2, bound2)
+
+ def forward(self, x, use_conv3d=False, skip_time_conv=False):
+ if use_conv3d:
+ return self.forward_with_3d(x=x, skip_time_conv=skip_time_conv)
+ else:
+ return self.forward_with_2d(x=x, skip_time_conv=skip_time_conv)
+
+ def forward_with_3d(self, x, skip_time_conv):
+ # First convolution
+ x = F.conv3d(
+ x,
+ self.weight1,
+ self.bias1,
+ self.stride1,
+ self.padding1,
+ self.dilation1,
+ self.groups,
+ padding_mode=self.padding_mode,
+ )
+
+ if skip_time_conv:
+ return x
+
+ # Second convolution
+ x = F.conv3d(
+ x,
+ self.weight2,
+ self.bias2,
+ self.stride2,
+ self.padding2,
+ self.dilation2,
+ self.groups,
+ padding_mode=self.padding_mode,
+ )
+
+ return x
+
+ def forward_with_2d(self, x, skip_time_conv):
+ b, c, d, h, w = x.shape
+
+ # First 2D convolution
+ x = rearrange(x, "b c d h w -> (b d) c h w")
+ # Squeeze the depth dimension out of weight1 since it's 1
+ weight1 = self.weight1.squeeze(2)
+ # Select stride, padding, and dilation for the 2D convolution
+ stride1 = (self.stride1[1], self.stride1[2])
+ padding1 = (self.padding1[1], self.padding1[2])
+ dilation1 = (self.dilation1[1], self.dilation1[2])
+ x = F.conv2d(
+ x,
+ weight1,
+ self.bias1,
+ stride1,
+ padding1,
+ dilation1,
+ self.groups,
+ padding_mode=self.padding_mode,
+ )
+
+ _, _, h, w = x.shape
+
+ if skip_time_conv:
+ x = rearrange(x, "(b d) c h w -> b c d h w", b=b)
+ return x
+
+ # Second convolution which is essentially treated as a 1D convolution across the 'd' dimension
+ x = rearrange(x, "(b d) c h w -> (b h w) c d", b=b)
+
+ # Reshape weight2 to match the expected dimensions for conv1d
+ weight2 = self.weight2.squeeze(-1).squeeze(-1)
+ # Use only the relevant dimension for stride, padding, and dilation for the 1D convolution
+ stride2 = self.stride2[0]
+ padding2 = self.padding2[0]
+ dilation2 = self.dilation2[0]
+ x = F.conv1d(
+ x,
+ weight2,
+ self.bias2,
+ stride2,
+ padding2,
+ dilation2,
+ self.groups,
+ padding_mode=self.padding_mode,
+ )
+ x = rearrange(x, "(b h w) c d -> b c d h w", b=b, h=h, w=w)
+
+ return x
+
+ @property
+ def weight(self):
+ return self.weight2
+
+
+def test_dual_conv3d_consistency():
+ # Initialize parameters
+ in_channels = 3
+ out_channels = 5
+ kernel_size = (3, 3, 3)
+ stride = (2, 2, 2)
+ padding = (1, 1, 1)
+
+ # Create an instance of the DualConv3d class
+ dual_conv3d = DualConv3d(
+ in_channels=in_channels,
+ out_channels=out_channels,
+ kernel_size=kernel_size,
+ stride=stride,
+ padding=padding,
+ bias=True,
+ )
+
+ # Example input tensor
+ test_input = torch.randn(1, 3, 10, 10, 10)
+
+ # Perform forward passes with both 3D and 2D settings
+ output_conv3d = dual_conv3d(test_input, use_conv3d=True)
+ output_2d = dual_conv3d(test_input, use_conv3d=False)
+
+ # Assert that the outputs from both methods are sufficiently close
+ assert torch.allclose(
+ output_conv3d, output_2d, atol=1e-6
+ ), "Outputs are not consistent between 3D and 2D convolutions."
diff --git a/ComfyUI/comfy/ldm/lightricks/vae/pixel_norm.py b/ComfyUI/comfy/ldm/lightricks/vae/pixel_norm.py
new file mode 100644
index 0000000000000000000000000000000000000000..9bc3ea60e8a6453e7e12a7fb5aca4de3958a2567
--- /dev/null
+++ b/ComfyUI/comfy/ldm/lightricks/vae/pixel_norm.py
@@ -0,0 +1,12 @@
+import torch
+from torch import nn
+
+
+class PixelNorm(nn.Module):
+ def __init__(self, dim=1, eps=1e-8):
+ super(PixelNorm, self).__init__()
+ self.dim = dim
+ self.eps = eps
+
+ def forward(self, x):
+ return x / torch.sqrt(torch.mean(x**2, dim=self.dim, keepdim=True) + self.eps)
diff --git a/ComfyUI/comfy/ldm/lightricks/vocoders/__pycache__/vocoder.cpython-312.pyc b/ComfyUI/comfy/ldm/lightricks/vocoders/__pycache__/vocoder.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..846118f24ef2c0879b954bc0a5976864f6eb628d
Binary files /dev/null and b/ComfyUI/comfy/ldm/lightricks/vocoders/__pycache__/vocoder.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/lightricks/vocoders/vocoder.py b/ComfyUI/comfy/ldm/lightricks/vocoders/vocoder.py
new file mode 100644
index 0000000000000000000000000000000000000000..2481d8bdd37301dd8eb34505e1753199ba1c7d27
--- /dev/null
+++ b/ComfyUI/comfy/ldm/lightricks/vocoders/vocoder.py
@@ -0,0 +1,713 @@
+import torch
+import torch.nn.functional as F
+import torch.nn as nn
+import comfy.ops
+import comfy.model_management
+import numpy as np
+import math
+
+ops = comfy.ops.disable_weight_init
+
+LRELU_SLOPE = 0.1
+
+def get_padding(kernel_size, dilation=1):
+ return int((kernel_size * dilation - dilation) / 2)
+
+
+# ---------------------------------------------------------------------------
+# Anti-aliased resampling helpers (kaiser-sinc filters) for BigVGAN v2
+# Adopted from https://github.com/NVIDIA/BigVGAN
+# ---------------------------------------------------------------------------
+
+
+def _sinc(x: torch.Tensor):
+ return torch.where(
+ x == 0,
+ torch.tensor(1.0, device=x.device, dtype=x.dtype),
+ torch.sin(math.pi * x) / math.pi / x,
+ )
+
+
+def kaiser_sinc_filter1d(cutoff, half_width, kernel_size):
+ even = kernel_size % 2 == 0
+ half_size = kernel_size // 2
+ delta_f = 4 * half_width
+ A = 2.285 * (half_size - 1) * math.pi * delta_f + 7.95
+ if A > 50.0:
+ beta = 0.1102 * (A - 8.7)
+ elif A >= 21.0:
+ beta = 0.5842 * (A - 21) ** 0.4 + 0.07886 * (A - 21.0)
+ else:
+ beta = 0.0
+ window = torch.kaiser_window(kernel_size, beta=beta, periodic=False)
+ if even:
+ time = torch.arange(-half_size, half_size) + 0.5
+ else:
+ time = torch.arange(kernel_size) - half_size
+ if cutoff == 0:
+ filter_ = torch.zeros_like(time)
+ else:
+ filter_ = 2 * cutoff * window * _sinc(2 * cutoff * time)
+ filter_ /= filter_.sum()
+ filter = filter_.view(1, 1, kernel_size)
+ return filter
+
+
+class LowPassFilter1d(nn.Module):
+ def __init__(
+ self,
+ cutoff=0.5,
+ half_width=0.6,
+ stride=1,
+ padding=True,
+ padding_mode="replicate",
+ kernel_size=12,
+ ):
+ super().__init__()
+ if cutoff < -0.0:
+ raise ValueError("Minimum cutoff must be larger than zero.")
+ if cutoff > 0.5:
+ raise ValueError("A cutoff above 0.5 does not make sense.")
+ self.kernel_size = kernel_size
+ self.even = kernel_size % 2 == 0
+ self.pad_left = kernel_size // 2 - int(self.even)
+ self.pad_right = kernel_size // 2
+ self.stride = stride
+ self.padding = padding
+ self.padding_mode = padding_mode
+ filter = kaiser_sinc_filter1d(cutoff, half_width, kernel_size)
+ self.register_buffer("filter", filter)
+
+ def forward(self, x):
+ _, C, _ = x.shape
+ if self.padding:
+ x = F.pad(x, (self.pad_left, self.pad_right), mode=self.padding_mode)
+ return F.conv1d(x, comfy.model_management.cast_to(self.filter.expand(C, -1, -1), dtype=x.dtype, device=x.device), stride=self.stride, groups=C)
+
+
+class UpSample1d(nn.Module):
+ def __init__(self, ratio=2, kernel_size=None, persistent=True, window_type="kaiser"):
+ super().__init__()
+ self.ratio = ratio
+ self.stride = ratio
+
+ if window_type == "hann":
+ # Hann-windowed sinc filter — identical to torchaudio.functional.resample
+ # with its default parameters (rolloff=0.99, lowpass_filter_width=6).
+ # Uses replicate boundary padding, matching the reference resampler exactly.
+ rolloff = 0.99
+ lowpass_filter_width = 6
+ width = math.ceil(lowpass_filter_width / rolloff)
+ self.kernel_size = 2 * width * ratio + 1
+ self.pad = width
+ self.pad_left = 2 * width * ratio
+ self.pad_right = self.kernel_size - ratio
+ t = (torch.arange(self.kernel_size) / ratio - width) * rolloff
+ t_clamped = t.clamp(-lowpass_filter_width, lowpass_filter_width)
+ window = torch.cos(t_clamped * math.pi / lowpass_filter_width / 2) ** 2
+ filter = (torch.sinc(t) * window * rolloff / ratio).view(1, 1, -1)
+ else:
+ # Kaiser-windowed sinc filter (BigVGAN default).
+ self.kernel_size = (
+ int(6 * ratio // 2) * 2 if kernel_size is None else kernel_size
+ )
+ self.pad = self.kernel_size // ratio - 1
+ self.pad_left = self.pad * self.stride + (self.kernel_size - self.stride) // 2
+ self.pad_right = (
+ self.pad * self.stride + (self.kernel_size - self.stride + 1) // 2
+ )
+ filter = kaiser_sinc_filter1d(
+ cutoff=0.5 / ratio, half_width=0.6 / ratio, kernel_size=self.kernel_size
+ )
+
+ self.register_buffer("filter", filter, persistent=persistent)
+
+ def forward(self, x):
+ _, C, _ = x.shape
+ x = F.pad(x, (self.pad, self.pad), mode="replicate")
+ x = self.ratio * F.conv_transpose1d(
+ x, comfy.model_management.cast_to(self.filter.expand(C, -1, -1), dtype=x.dtype, device=x.device), stride=self.stride, groups=C
+ )
+ x = x[..., self.pad_left : -self.pad_right]
+ return x
+
+
+class DownSample1d(nn.Module):
+ def __init__(self, ratio=2, kernel_size=None):
+ super().__init__()
+ self.ratio = ratio
+ self.kernel_size = (
+ int(6 * ratio // 2) * 2 if kernel_size is None else kernel_size
+ )
+ self.lowpass = LowPassFilter1d(
+ cutoff=0.5 / ratio,
+ half_width=0.6 / ratio,
+ stride=ratio,
+ kernel_size=self.kernel_size,
+ )
+
+ def forward(self, x):
+ return self.lowpass(x)
+
+
+class Activation1d(nn.Module):
+ def __init__(
+ self,
+ activation,
+ up_ratio=2,
+ down_ratio=2,
+ up_kernel_size=12,
+ down_kernel_size=12,
+ ):
+ super().__init__()
+ self.act = activation
+ self.upsample = UpSample1d(up_ratio, up_kernel_size)
+ self.downsample = DownSample1d(down_ratio, down_kernel_size)
+
+ def forward(self, x):
+ x = self.upsample(x)
+ x = self.act(x)
+ x = self.downsample(x)
+ return x
+
+
+# ---------------------------------------------------------------------------
+# BigVGAN v2 activations (Snake / SnakeBeta)
+# ---------------------------------------------------------------------------
+
+
+class Snake(nn.Module):
+ def __init__(
+ self, in_features, alpha=1.0, alpha_trainable=True, alpha_logscale=True
+ ):
+ super().__init__()
+ self.alpha_logscale = alpha_logscale
+ self.alpha = nn.Parameter(
+ torch.zeros(in_features)
+ if alpha_logscale
+ else torch.ones(in_features) * alpha
+ )
+ self.alpha.requires_grad = alpha_trainable
+ self.eps = 1e-9
+
+ def forward(self, x):
+ a = comfy.model_management.cast_to(self.alpha.unsqueeze(0).unsqueeze(-1), dtype=x.dtype, device=x.device)
+ if self.alpha_logscale:
+ a = torch.exp(a)
+ return x + (1.0 / (a + self.eps)) * torch.sin(x * a).pow(2)
+
+
+class SnakeBeta(nn.Module):
+ def __init__(
+ self, in_features, alpha=1.0, alpha_trainable=True, alpha_logscale=True
+ ):
+ super().__init__()
+ self.alpha_logscale = alpha_logscale
+ self.alpha = nn.Parameter(
+ torch.zeros(in_features)
+ if alpha_logscale
+ else torch.ones(in_features) * alpha
+ )
+ self.alpha.requires_grad = alpha_trainable
+ self.beta = nn.Parameter(
+ torch.zeros(in_features)
+ if alpha_logscale
+ else torch.ones(in_features) * alpha
+ )
+ self.beta.requires_grad = alpha_trainable
+ self.eps = 1e-9
+
+ def forward(self, x):
+ a = comfy.model_management.cast_to(self.alpha.unsqueeze(0).unsqueeze(-1), dtype=x.dtype, device=x.device)
+ b = comfy.model_management.cast_to(self.beta.unsqueeze(0).unsqueeze(-1), dtype=x.dtype, device=x.device)
+ if self.alpha_logscale:
+ a = torch.exp(a)
+ b = torch.exp(b)
+ return x + (1.0 / (b + self.eps)) * torch.sin(x * a).pow(2)
+
+
+# ---------------------------------------------------------------------------
+# BigVGAN v2 AMPBlock (Anti-aliased Multi-Periodicity)
+# ---------------------------------------------------------------------------
+
+
+class AMPBlock1(torch.nn.Module):
+ def __init__(self, channels, kernel_size=3, dilation=(1, 3, 5), activation="snake"):
+ super().__init__()
+ act_cls = SnakeBeta if activation == "snakebeta" else Snake
+ self.convs1 = nn.ModuleList(
+ [
+ ops.Conv1d(
+ channels,
+ channels,
+ kernel_size,
+ 1,
+ dilation=dilation[0],
+ padding=get_padding(kernel_size, dilation[0]),
+ ),
+ ops.Conv1d(
+ channels,
+ channels,
+ kernel_size,
+ 1,
+ dilation=dilation[1],
+ padding=get_padding(kernel_size, dilation[1]),
+ ),
+ ops.Conv1d(
+ channels,
+ channels,
+ kernel_size,
+ 1,
+ dilation=dilation[2],
+ padding=get_padding(kernel_size, dilation[2]),
+ ),
+ ]
+ )
+
+ self.convs2 = nn.ModuleList(
+ [
+ ops.Conv1d(
+ channels,
+ channels,
+ kernel_size,
+ 1,
+ dilation=1,
+ padding=get_padding(kernel_size, 1),
+ ),
+ ops.Conv1d(
+ channels,
+ channels,
+ kernel_size,
+ 1,
+ dilation=1,
+ padding=get_padding(kernel_size, 1),
+ ),
+ ops.Conv1d(
+ channels,
+ channels,
+ kernel_size,
+ 1,
+ dilation=1,
+ padding=get_padding(kernel_size, 1),
+ ),
+ ]
+ )
+
+ self.acts1 = nn.ModuleList(
+ [Activation1d(act_cls(channels)) for _ in range(len(self.convs1))]
+ )
+ self.acts2 = nn.ModuleList(
+ [Activation1d(act_cls(channels)) for _ in range(len(self.convs2))]
+ )
+
+ def forward(self, x):
+ for c1, c2, a1, a2 in zip(self.convs1, self.convs2, self.acts1, self.acts2):
+ xt = a1(x)
+ xt = c1(xt)
+ xt = a2(xt)
+ xt = c2(xt)
+ x = x + xt
+ return x
+
+
+# ---------------------------------------------------------------------------
+# HiFi-GAN residual blocks
+# ---------------------------------------------------------------------------
+
+
+class ResBlock1(torch.nn.Module):
+ def __init__(self, channels, kernel_size=3, dilation=(1, 3, 5)):
+ super(ResBlock1, self).__init__()
+ self.convs1 = nn.ModuleList(
+ [
+ ops.Conv1d(
+ channels,
+ channels,
+ kernel_size,
+ 1,
+ dilation=dilation[0],
+ padding=get_padding(kernel_size, dilation[0]),
+ ),
+ ops.Conv1d(
+ channels,
+ channels,
+ kernel_size,
+ 1,
+ dilation=dilation[1],
+ padding=get_padding(kernel_size, dilation[1]),
+ ),
+ ops.Conv1d(
+ channels,
+ channels,
+ kernel_size,
+ 1,
+ dilation=dilation[2],
+ padding=get_padding(kernel_size, dilation[2]),
+ ),
+ ]
+ )
+
+ self.convs2 = nn.ModuleList(
+ [
+ ops.Conv1d(
+ channels,
+ channels,
+ kernel_size,
+ 1,
+ dilation=1,
+ padding=get_padding(kernel_size, 1),
+ ),
+ ops.Conv1d(
+ channels,
+ channels,
+ kernel_size,
+ 1,
+ dilation=1,
+ padding=get_padding(kernel_size, 1),
+ ),
+ ops.Conv1d(
+ channels,
+ channels,
+ kernel_size,
+ 1,
+ dilation=1,
+ padding=get_padding(kernel_size, 1),
+ ),
+ ]
+ )
+
+ def forward(self, x):
+ for c1, c2 in zip(self.convs1, self.convs2):
+ xt = F.leaky_relu(x, LRELU_SLOPE)
+ xt = c1(xt)
+ xt = F.leaky_relu(xt, LRELU_SLOPE)
+ xt = c2(xt)
+ x = xt + x
+ return x
+
+
+class ResBlock2(torch.nn.Module):
+ def __init__(self, channels, kernel_size=3, dilation=(1, 3)):
+ super(ResBlock2, self).__init__()
+ self.convs = nn.ModuleList(
+ [
+ ops.Conv1d(
+ channels,
+ channels,
+ kernel_size,
+ 1,
+ dilation=dilation[0],
+ padding=get_padding(kernel_size, dilation[0]),
+ ),
+ ops.Conv1d(
+ channels,
+ channels,
+ kernel_size,
+ 1,
+ dilation=dilation[1],
+ padding=get_padding(kernel_size, dilation[1]),
+ ),
+ ]
+ )
+
+ def forward(self, x):
+ for c in self.convs:
+ xt = F.leaky_relu(x, LRELU_SLOPE)
+ xt = c(xt)
+ x = xt + x
+ return x
+
+
+class Vocoder(torch.nn.Module):
+ """
+ Vocoder model for synthesizing audio from spectrograms, based on: https://github.com/jik876/hifi-gan.
+
+ Supports both HiFi-GAN (resblock "1"/"2") and BigVGAN v2 (resblock "AMP1").
+ """
+
+ def __init__(self, config=None):
+ super(Vocoder, self).__init__()
+
+ if config is None:
+ config = self.get_default_config()
+
+ resblock_kernel_sizes = config.get("resblock_kernel_sizes", [3, 7, 11])
+ upsample_rates = config.get("upsample_rates", [5, 4, 2, 2, 2])
+ upsample_kernel_sizes = config.get("upsample_kernel_sizes", [16, 16, 8, 4, 4])
+ resblock_dilation_sizes = config.get("resblock_dilation_sizes", [[1, 3, 5], [1, 3, 5], [1, 3, 5]])
+ upsample_initial_channel = config.get("upsample_initial_channel", 1024)
+ stereo = config.get("stereo", True)
+ activation = config.get("activation", "snake")
+ use_bias_at_final = config.get("use_bias_at_final", True)
+
+
+ # "output_sample_rate" is not present in recent checkpoint configs.
+ # When absent (None), AudioVAE.output_sample_rate computes it as:
+ # sample_rate * vocoder.upsample_factor / mel_hop_length
+ # where upsample_factor = product of all upsample stride lengths,
+ # and mel_hop_length is loaded from the autoencoder config at
+ # preprocessing.stft.hop_length (see CausalAudioAutoencoder).
+ self.output_sample_rate = config.get("output_sample_rate")
+ self.resblock = config.get("resblock", "1")
+ self.use_tanh_at_final = config.get("use_tanh_at_final", True)
+ self.apply_final_activation = config.get("apply_final_activation", True)
+ self.num_kernels = len(resblock_kernel_sizes)
+ self.num_upsamples = len(upsample_rates)
+
+ in_channels = 128 if stereo else 64
+ self.conv_pre = ops.Conv1d(in_channels, upsample_initial_channel, 7, 1, padding=3)
+
+ if self.resblock == "1":
+ resblock_cls = ResBlock1
+ elif self.resblock == "2":
+ resblock_cls = ResBlock2
+ elif self.resblock == "AMP1":
+ resblock_cls = AMPBlock1
+ else:
+ raise ValueError(f"Unknown resblock type: {self.resblock}")
+
+ self.ups = nn.ModuleList()
+ for i, (u, k) in enumerate(zip(upsample_rates, upsample_kernel_sizes)):
+ self.ups.append(
+ ops.ConvTranspose1d(
+ upsample_initial_channel // (2**i),
+ upsample_initial_channel // (2 ** (i + 1)),
+ k,
+ u,
+ padding=(k - u) // 2,
+ )
+ )
+
+ self.resblocks = nn.ModuleList()
+ for i in range(len(self.ups)):
+ ch = upsample_initial_channel // (2 ** (i + 1))
+ for k, d in zip(resblock_kernel_sizes, resblock_dilation_sizes):
+ if self.resblock == "AMP1":
+ self.resblocks.append(resblock_cls(ch, k, d, activation=activation))
+ else:
+ self.resblocks.append(resblock_cls(ch, k, d))
+
+ out_channels = 2 if stereo else 1
+ if self.resblock == "AMP1":
+ act_cls = SnakeBeta if activation == "snakebeta" else Snake
+ self.act_post = Activation1d(act_cls(ch))
+ else:
+ self.act_post = nn.LeakyReLU()
+
+ self.conv_post = ops.Conv1d(
+ ch, out_channels, 7, 1, padding=3, bias=use_bias_at_final
+ )
+
+ self.upsample_factor = np.prod([self.ups[i].stride[0] for i in range(len(self.ups))])
+
+
+ def get_default_config(self):
+ """Generate default configuration for the vocoder."""
+
+ config = {
+ "resblock_kernel_sizes": [3, 7, 11],
+ "upsample_rates": [5, 4, 2, 2, 2],
+ "upsample_kernel_sizes": [16, 16, 8, 4, 4],
+ "resblock_dilation_sizes": [[1, 3, 5], [1, 3, 5], [1, 3, 5]],
+ "upsample_initial_channel": 1024,
+ "stereo": True,
+ "resblock": "1",
+ "activation": "snake",
+ "use_bias_at_final": True,
+ "use_tanh_at_final": True,
+ }
+
+ return config
+
+ def forward(self, x):
+ """
+ Forward pass of the vocoder.
+
+ Args:
+ x: Input spectrogram tensor. Can be:
+ - 3D: (batch_size, channels, time_steps) for mono
+ - 4D: (batch_size, 2, channels, time_steps) for stereo
+
+ Returns:
+ Audio tensor of shape (batch_size, out_channels, audio_length)
+ """
+ if x.dim() == 4: # stereo
+ assert x.shape[1] == 2, "Input must have 2 channels for stereo"
+ x = torch.cat((x[:, 0, :, :], x[:, 1, :, :]), dim=1)
+ x = self.conv_pre(x)
+
+ for i in range(self.num_upsamples):
+ if self.resblock != "AMP1":
+ x = F.leaky_relu(x, LRELU_SLOPE)
+ x = self.ups[i](x)
+ xs = None
+ for j in range(self.num_kernels):
+ if xs is None:
+ xs = self.resblocks[i * self.num_kernels + j](x)
+ else:
+ xs += self.resblocks[i * self.num_kernels + j](x)
+ x = xs / self.num_kernels
+
+ x = self.act_post(x)
+ x = self.conv_post(x)
+
+ if self.apply_final_activation:
+ if self.use_tanh_at_final:
+ x = torch.tanh(x)
+ else:
+ x = torch.clamp(x, -1, 1)
+
+ return x
+
+
+class _STFTFn(nn.Module):
+ """Implements STFT as a convolution with precomputed DFT × Hann-window bases.
+
+ The DFT basis rows (real and imaginary parts interleaved) multiplied by the causal
+ Hann window are stored as buffers and loaded from the checkpoint. Using the exact
+ bfloat16 bases from training ensures the mel values fed to the BWE generator are
+ bit-identical to what it was trained on.
+ """
+
+ def __init__(self, filter_length: int, hop_length: int, win_length: int):
+ super().__init__()
+ self.hop_length = hop_length
+ self.win_length = win_length
+ n_freqs = filter_length // 2 + 1
+ self.register_buffer("forward_basis", torch.zeros(n_freqs * 2, 1, filter_length))
+ self.register_buffer("inverse_basis", torch.zeros(n_freqs * 2, 1, filter_length))
+
+ def forward(self, y: torch.Tensor) -> tuple[torch.Tensor, torch.Tensor]:
+ """Compute magnitude and phase spectrogram from a batch of waveforms.
+
+ Applies causal (left-only) padding of win_length - hop_length samples so that
+ each output frame depends only on past and present input — no lookahead.
+ The STFT is computed by convolving the padded signal with forward_basis.
+
+ Args:
+ y: Waveform tensor of shape (B, T).
+
+ Returns:
+ magnitude: Linear amplitude spectrogram, shape (B, n_freqs, T_frames).
+ phase: Phase spectrogram in radians, shape (B, n_freqs, T_frames).
+ Computed in float32 for numerical stability, then cast back to
+ the input dtype.
+ """
+ if y.dim() == 2:
+ y = y.unsqueeze(1) # (B, 1, T)
+ left_pad = max(0, self.win_length - self.hop_length) # causal: left-only
+ y = F.pad(y, (left_pad, 0))
+ spec = F.conv1d(y, comfy.model_management.cast_to(self.forward_basis, dtype=y.dtype, device=y.device), stride=self.hop_length, padding=0)
+ n_freqs = spec.shape[1] // 2
+ real, imag = spec[:, :n_freqs], spec[:, n_freqs:]
+ magnitude = torch.sqrt(real ** 2 + imag ** 2)
+ phase = torch.atan2(imag.float(), real.float()).to(real.dtype)
+ return magnitude, phase
+
+
+class MelSTFT(nn.Module):
+ """Causal log-mel spectrogram module whose buffers are loaded from the checkpoint.
+
+ Computes a log-mel spectrogram by running the causal STFT (_STFTFn) on the input
+ waveform and projecting the linear magnitude spectrum onto the mel filterbank.
+
+ The module's state dict layout matches the 'mel_stft.*' keys stored in the checkpoint
+ (mel_basis, stft_fn.forward_basis, stft_fn.inverse_basis).
+ """
+
+ def __init__(
+ self,
+ filter_length: int,
+ hop_length: int,
+ win_length: int,
+ n_mel_channels: int,
+ sampling_rate: int,
+ mel_fmin: float,
+ mel_fmax: float,
+ ):
+ super().__init__()
+ self.stft_fn = _STFTFn(filter_length, hop_length, win_length)
+
+ n_freqs = filter_length // 2 + 1
+ self.register_buffer("mel_basis", torch.zeros(n_mel_channels, n_freqs))
+
+ def mel_spectrogram(
+ self, y: torch.Tensor
+ ) -> tuple[torch.Tensor, torch.Tensor, torch.Tensor, torch.Tensor]:
+ """Compute log-mel spectrogram and auxiliary spectral quantities.
+
+ Args:
+ y: Waveform tensor of shape (B, T).
+
+ Returns:
+ log_mel: Log-compressed mel spectrogram, shape (B, n_mel_channels, T_frames).
+ Computed as log(clamp(mel_basis @ magnitude, min=1e-5)).
+ magnitude: Linear amplitude spectrogram, shape (B, n_freqs, T_frames).
+ phase: Phase spectrogram in radians, shape (B, n_freqs, T_frames).
+ energy: Per-frame energy (L2 norm over frequency), shape (B, T_frames).
+ """
+ magnitude, phase = self.stft_fn(y)
+ energy = torch.norm(magnitude, dim=1)
+ mel = torch.matmul(comfy.model_management.cast_to(self.mel_basis, dtype=magnitude.dtype, device=y.device), magnitude)
+ log_mel = torch.log(torch.clamp(mel, min=1e-5))
+ return log_mel, magnitude, phase, energy
+
+
+class VocoderWithBWE(torch.nn.Module):
+ """Vocoder with bandwidth extension (BWE) for higher sample rate output.
+
+ Chains a base vocoder (mel → low-rate waveform) with a BWE stage that upsamples
+ to a higher rate. The BWE computes a mel spectrogram from the low-rate waveform.
+ """
+
+ def __init__(self, config):
+ super().__init__()
+ vocoder_config = config["vocoder"]
+ bwe_config = config["bwe"]
+
+ self.vocoder = Vocoder(config=vocoder_config)
+ self.bwe_generator = Vocoder(
+ config={**bwe_config, "apply_final_activation": False}
+ )
+
+ self.input_sample_rate = bwe_config["input_sampling_rate"]
+ self.output_sample_rate = bwe_config["output_sampling_rate"]
+ self.hop_length = bwe_config["hop_length"]
+
+ self.mel_stft = MelSTFT(
+ filter_length=bwe_config["n_fft"],
+ hop_length=bwe_config["hop_length"],
+ win_length=bwe_config["n_fft"],
+ n_mel_channels=bwe_config["num_mels"],
+ sampling_rate=bwe_config["input_sampling_rate"],
+ mel_fmin=0.0,
+ mel_fmax=bwe_config["input_sampling_rate"] / 2.0,
+ )
+ self.resampler = UpSample1d(
+ ratio=bwe_config["output_sampling_rate"] // bwe_config["input_sampling_rate"],
+ persistent=False,
+ window_type="hann",
+ )
+
+ def _compute_mel(self, audio):
+ """Compute log-mel spectrogram from waveform using causal STFT bases."""
+ B, C, T = audio.shape
+ flat = audio.reshape(B * C, -1) # (B*C, T)
+ mel, _, _, _ = self.mel_stft.mel_spectrogram(flat) # (B*C, n_mels, T_frames)
+ return mel.reshape(B, C, mel.shape[1], mel.shape[2]) # (B, C, n_mels, T_frames)
+
+ def forward(self, mel_spec):
+ x = self.vocoder(mel_spec)
+ _, _, T_low = x.shape
+ T_out = T_low * self.output_sample_rate // self.input_sample_rate
+
+ remainder = T_low % self.hop_length
+ if remainder != 0:
+ x = F.pad(x, (0, self.hop_length - remainder))
+
+ mel = self._compute_mel(x)
+ residual = self.bwe_generator(mel)
+ skip = self.resampler(x)
+ assert residual.shape == skip.shape, f"residual {residual.shape} != skip {skip.shape}"
+
+ return torch.clamp(residual + skip, -1, 1)[..., :T_out]
diff --git a/ComfyUI/comfy/ldm/lumina/__pycache__/controlnet.cpython-312.pyc b/ComfyUI/comfy/ldm/lumina/__pycache__/controlnet.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..895a0d77c5eb8b2c928f4664565c0b400fec25fd
Binary files /dev/null and b/ComfyUI/comfy/ldm/lumina/__pycache__/controlnet.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/lumina/__pycache__/model.cpython-312.pyc b/ComfyUI/comfy/ldm/lumina/__pycache__/model.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..cc90483fca4d0c84db875d70af3ff5dc66992716
Binary files /dev/null and b/ComfyUI/comfy/ldm/lumina/__pycache__/model.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/lumina/controlnet.py b/ComfyUI/comfy/ldm/lumina/controlnet.py
new file mode 100644
index 0000000000000000000000000000000000000000..8e2de7977536daf9779e27d6e019cdea40049e0c
--- /dev/null
+++ b/ComfyUI/comfy/ldm/lumina/controlnet.py
@@ -0,0 +1,160 @@
+import torch
+from torch import nn
+
+from .model import JointTransformerBlock
+
+class ZImageControlTransformerBlock(JointTransformerBlock):
+ def __init__(
+ self,
+ layer_id: int,
+ dim: int,
+ n_heads: int,
+ n_kv_heads: int,
+ multiple_of: int,
+ ffn_dim_multiplier: float,
+ norm_eps: float,
+ qk_norm: bool,
+ modulation=True,
+ block_id=0,
+ operation_settings=None,
+ ):
+ super().__init__(layer_id, dim, n_heads, n_kv_heads, multiple_of, ffn_dim_multiplier, norm_eps, qk_norm, modulation, z_image_modulation=True, operation_settings=operation_settings)
+ self.block_id = block_id
+ if block_id == 0:
+ self.before_proj = operation_settings.get("operations").Linear(self.dim, self.dim, device=operation_settings.get("device"), dtype=operation_settings.get("dtype"))
+ self.after_proj = operation_settings.get("operations").Linear(self.dim, self.dim, device=operation_settings.get("device"), dtype=operation_settings.get("dtype"))
+
+ def forward(self, c, x, **kwargs):
+ if self.block_id == 0:
+ c = self.before_proj(c) + x
+ c = super().forward(c, **kwargs)
+ c_skip = self.after_proj(c)
+ return c_skip, c
+
+class ZImage_Control(torch.nn.Module):
+ def __init__(
+ self,
+ dim: int = 3840,
+ n_heads: int = 30,
+ n_kv_heads: int = 30,
+ multiple_of: int = 256,
+ ffn_dim_multiplier: float = (8.0 / 3.0),
+ norm_eps: float = 1e-5,
+ qk_norm: bool = True,
+ n_control_layers=6,
+ control_in_dim=16,
+ additional_in_dim=0,
+ broken=False,
+ refiner_control=False,
+ dtype=None,
+ device=None,
+ operations=None,
+ **kwargs
+ ):
+ super().__init__()
+ operation_settings = {"operations": operations, "device": device, "dtype": dtype}
+
+ self.broken = broken
+ self.additional_in_dim = additional_in_dim
+ self.control_in_dim = control_in_dim
+ n_refiner_layers = 2
+ self.n_control_layers = n_control_layers
+ self.control_layers = nn.ModuleList(
+ [
+ ZImageControlTransformerBlock(
+ i,
+ dim,
+ n_heads,
+ n_kv_heads,
+ multiple_of,
+ ffn_dim_multiplier,
+ norm_eps,
+ qk_norm,
+ block_id=i,
+ operation_settings=operation_settings,
+ )
+ for i in range(self.n_control_layers)
+ ]
+ )
+
+ all_x_embedder = {}
+ patch_size = 2
+ f_patch_size = 1
+ x_embedder = operations.Linear(f_patch_size * patch_size * patch_size * (self.control_in_dim + self.additional_in_dim), dim, bias=True, device=device, dtype=dtype)
+ all_x_embedder[f"{patch_size}-{f_patch_size}"] = x_embedder
+
+ self.refiner_control = refiner_control
+
+ self.control_all_x_embedder = nn.ModuleDict(all_x_embedder)
+ if self.refiner_control:
+ self.control_noise_refiner = nn.ModuleList(
+ [
+ ZImageControlTransformerBlock(
+ layer_id,
+ dim,
+ n_heads,
+ n_kv_heads,
+ multiple_of,
+ ffn_dim_multiplier,
+ norm_eps,
+ qk_norm,
+ block_id=layer_id,
+ operation_settings=operation_settings,
+ )
+ for layer_id in range(n_refiner_layers)
+ ]
+ )
+ else:
+ self.control_noise_refiner = nn.ModuleList(
+ [
+ JointTransformerBlock(
+ layer_id,
+ dim,
+ n_heads,
+ n_kv_heads,
+ multiple_of,
+ ffn_dim_multiplier,
+ norm_eps,
+ qk_norm,
+ modulation=True,
+ z_image_modulation=True,
+ operation_settings=operation_settings,
+ )
+ for layer_id in range(n_refiner_layers)
+ ]
+ )
+
+ def forward(self, cap_feats, control_context, x_freqs_cis, adaln_input):
+ patch_size = 2
+ f_patch_size = 1
+ pH = pW = patch_size
+ B, C, H, W = control_context.shape
+ control_context = self.control_all_x_embedder[f"{patch_size}-{f_patch_size}"](control_context.view(B, C, H // pH, pH, W // pW, pW).permute(0, 2, 4, 3, 5, 1).flatten(3).flatten(1, 2))
+
+ x_attn_mask = None
+ if not self.refiner_control:
+ for layer in self.control_noise_refiner:
+ control_context = layer(control_context, x_attn_mask, x_freqs_cis[:control_context.shape[0], :control_context.shape[1]], adaln_input)
+
+ return control_context
+
+ def forward_noise_refiner_block(self, layer_id, control_context, x, x_attn_mask, x_freqs_cis, adaln_input):
+ if self.refiner_control:
+ if self.broken:
+ if layer_id == 0:
+ return self.control_layers[layer_id](control_context, x, x_mask=x_attn_mask, freqs_cis=x_freqs_cis[:control_context.shape[0], :control_context.shape[1]], adaln_input=adaln_input)
+ if layer_id > 0:
+ out = None
+ for i in range(1, len(self.control_layers)):
+ o, control_context = self.control_layers[i](control_context, x, x_mask=x_attn_mask, freqs_cis=x_freqs_cis[:control_context.shape[0], :control_context.shape[1]], adaln_input=adaln_input)
+ if out is None:
+ out = o
+
+ return (out, control_context)
+ else:
+ return self.control_noise_refiner[layer_id](control_context, x, x_mask=x_attn_mask, freqs_cis=x_freqs_cis[:control_context.shape[0], :control_context.shape[1]], adaln_input=adaln_input)
+ else:
+ return (None, control_context)
+
+ def forward_control_block(self, layer_id, control_context, x, x_attn_mask, x_freqs_cis, adaln_input):
+ return self.control_layers[layer_id](control_context, x, x_mask=x_attn_mask, freqs_cis=x_freqs_cis[:control_context.shape[0], :control_context.shape[1]], adaln_input=adaln_input)
diff --git a/ComfyUI/comfy/ldm/lumina/model.py b/ComfyUI/comfy/ldm/lumina/model.py
new file mode 100644
index 0000000000000000000000000000000000000000..cdf03b2b5e3a09d1c33194fc45ecaab3fb108c68
--- /dev/null
+++ b/ComfyUI/comfy/ldm/lumina/model.py
@@ -0,0 +1,1139 @@
+# Code from: https://github.com/Alpha-VLLM/Lumina-Image-2.0/blob/main/models/model.py
+
+from typing import List, Optional, Tuple
+
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+import comfy.ldm.common_dit
+import comfy.model_management
+import comfy.ops
+import comfy.quant_ops
+
+from comfy.ldm.modules.diffusionmodules.mmdit import TimestepEmbedder
+from comfy.ldm.modules.attention import optimized_attention_masked
+from comfy.ldm.flux.layers import EmbedND
+from comfy.ldm.flux.math import apply_rope
+import comfy.patcher_extension
+import comfy.utils
+from comfy.ldm.chroma_radiance.layers import NerfEmbedder
+
+
+def invert_slices(slices, length):
+ sorted_slices = sorted(slices)
+ result = []
+ current = 0
+
+ for start, end in sorted_slices:
+ if current < start:
+ result.append((current, start))
+ current = max(current, end)
+
+ if current < length:
+ result.append((current, length))
+
+ return result
+
+
+def modulate(x, scale, timestep_zero_index=None):
+ if timestep_zero_index is None:
+ return x * (1 + scale.unsqueeze(1))
+ else:
+ scale = (1 + scale.unsqueeze(1))
+ actual_batch = scale.size(0) // 2
+ slices = timestep_zero_index
+ invert = invert_slices(timestep_zero_index, x.shape[1])
+ for s in slices:
+ x[:, s[0]:s[1]] *= scale[actual_batch:]
+ for s in invert:
+ x[:, s[0]:s[1]] *= scale[:actual_batch]
+ return x
+
+
+def apply_gate(gate, x, timestep_zero_index=None):
+ if timestep_zero_index is None:
+ return gate * x
+ else:
+ actual_batch = gate.size(0) // 2
+
+ slices = timestep_zero_index
+ invert = invert_slices(timestep_zero_index, x.shape[1])
+ for s in slices:
+ x[:, s[0]:s[1]] *= gate[actual_batch:]
+ for s in invert:
+ x[:, s[0]:s[1]] *= gate[:actual_batch]
+ return x
+
+#############################################################################
+# Core NextDiT Model #
+#############################################################################
+
+def clamp_fp16(x):
+ if x.dtype == torch.float16:
+ return torch.nan_to_num(x, nan=0.0, posinf=65504, neginf=-65504)
+ return x
+
+class JointAttention(nn.Module):
+ """Multi-head attention module."""
+
+ def __init__(
+ self,
+ dim: int,
+ n_heads: int,
+ n_kv_heads: Optional[int],
+ qk_norm: bool,
+ out_bias: bool = False,
+ operation_settings={},
+ ):
+ """
+ Initialize the Attention module.
+
+ Args:
+ dim (int): Number of input dimensions.
+ n_heads (int): Number of heads.
+ n_kv_heads (Optional[int]): Number of kv heads, if using GQA.
+
+ """
+ super().__init__()
+ self.n_kv_heads = n_heads if n_kv_heads is None else n_kv_heads
+ self.n_local_heads = n_heads
+ self.n_local_kv_heads = self.n_kv_heads
+ self.n_rep = self.n_local_heads // self.n_local_kv_heads
+ self.head_dim = dim // n_heads
+ self.qk_norm = qk_norm
+
+ self.qkv = operation_settings.get("operations").Linear(
+ dim,
+ (n_heads + self.n_kv_heads + self.n_kv_heads) * self.head_dim,
+ bias=False,
+ device=operation_settings.get("device"),
+ dtype=operation_settings.get("dtype"),
+ )
+ self.out = operation_settings.get("operations").Linear(
+ n_heads * self.head_dim,
+ dim,
+ bias=out_bias,
+ device=operation_settings.get("device"),
+ dtype=operation_settings.get("dtype"),
+ )
+
+ if qk_norm:
+ self.q_norm = operation_settings.get("operations").RMSNorm(self.head_dim, elementwise_affine=True, device=operation_settings.get("device"), dtype=operation_settings.get("dtype"))
+ self.k_norm = operation_settings.get("operations").RMSNorm(self.head_dim, elementwise_affine=True, device=operation_settings.get("device"), dtype=operation_settings.get("dtype"))
+ else:
+ self.q_norm = self.k_norm = nn.Identity()
+
+ def forward(
+ self,
+ x: torch.Tensor,
+ x_mask: torch.Tensor,
+ freqs_cis: torch.Tensor,
+ transformer_options={},
+ ) -> torch.Tensor:
+ """
+
+ Args:
+ x:
+ x_mask:
+ freqs_cis:
+
+ Returns:
+
+ """
+ bsz, seqlen, _ = x.shape
+
+ xq, xk, xv = torch.split(
+ self.qkv(x),
+ [
+ self.n_local_heads * self.head_dim,
+ self.n_local_kv_heads * self.head_dim,
+ self.n_local_kv_heads * self.head_dim,
+ ],
+ dim=-1,
+ )
+ xq = xq.view(bsz, seqlen, self.n_local_heads, self.head_dim)
+ xk = xk.view(bsz, seqlen, self.n_local_kv_heads, self.head_dim)
+ xv = xv.view(bsz, seqlen, self.n_local_kv_heads, self.head_dim)
+
+ if self.qk_norm and not comfy.model_management.in_training:
+ q_scale, _, q_offload_stream = comfy.ops.cast_bias_weight(self.q_norm, xq, offloadable=True)
+ k_scale, _, k_offload_stream = comfy.ops.cast_bias_weight(self.k_norm, xk, offloadable=True)
+ epsilon = self.q_norm.eps if self.q_norm.eps is not None else torch.finfo(torch.float32).eps
+ if self.n_local_heads == self.n_local_kv_heads:
+ xq, xk = comfy.quant_ops.ck.rms_rope(xq, xk, freqs_cis, q_scale, k_scale, epsilon)
+ else:
+ xq = comfy.quant_ops.ck.rms_rope1(xq, freqs_cis, q_scale, epsilon)
+ xk = comfy.quant_ops.ck.rms_rope1(xk, freqs_cis, k_scale, epsilon)
+ comfy.ops.uncast_bias_weight(self.q_norm, q_scale, None, q_offload_stream)
+ comfy.ops.uncast_bias_weight(self.k_norm, k_scale, None, k_offload_stream)
+ else:
+ xq = self.q_norm(xq)
+ xk = self.k_norm(xk)
+ xq, xk = apply_rope(xq, xk, freqs_cis)
+
+ n_rep = self.n_local_heads // self.n_local_kv_heads
+ if n_rep >= 1:
+ xk = xk.unsqueeze(3).repeat(1, 1, 1, n_rep, 1).flatten(2, 3)
+ xv = xv.unsqueeze(3).repeat(1, 1, 1, n_rep, 1).flatten(2, 3)
+ output = optimized_attention_masked(xq.movedim(1, 2), xk.movedim(1, 2), xv.movedim(1, 2), self.n_local_heads, x_mask, skip_reshape=True, transformer_options=transformer_options)
+
+ return self.out(output)
+
+
+class FeedForward(nn.Module):
+ def __init__(
+ self,
+ dim: int,
+ hidden_dim: int,
+ multiple_of: int,
+ ffn_dim_multiplier: Optional[float],
+ operation_settings={},
+ ):
+ """
+ Initialize the FeedForward module.
+
+ Args:
+ dim (int): Input dimension.
+ hidden_dim (int): Hidden dimension of the feedforward layer.
+ multiple_of (int): Value to ensure hidden dimension is a multiple
+ of this value.
+ ffn_dim_multiplier (float, optional): Custom multiplier for hidden
+ dimension. Defaults to None.
+
+ """
+ super().__init__()
+ # custom dim factor multiplier
+ if ffn_dim_multiplier is not None:
+ hidden_dim = int(ffn_dim_multiplier * hidden_dim)
+ hidden_dim = multiple_of * ((hidden_dim + multiple_of - 1) // multiple_of)
+
+ self.w1 = operation_settings.get("operations").Linear(
+ dim,
+ hidden_dim,
+ bias=False,
+ device=operation_settings.get("device"),
+ dtype=operation_settings.get("dtype"),
+ )
+ self.w2 = operation_settings.get("operations").Linear(
+ hidden_dim,
+ dim,
+ bias=False,
+ device=operation_settings.get("device"),
+ dtype=operation_settings.get("dtype"),
+ )
+ self.w3 = operation_settings.get("operations").Linear(
+ dim,
+ hidden_dim,
+ bias=False,
+ device=operation_settings.get("device"),
+ dtype=operation_settings.get("dtype"),
+ )
+
+ # @torch.compile
+ def _forward_silu_gating(self, x1, x3):
+ return clamp_fp16(F.silu(x1) * x3)
+
+ def forward(self, x):
+ return self.w2(self._forward_silu_gating(self.w1(x), self.w3(x)))
+
+
+class JointTransformerBlock(nn.Module):
+ def __init__(
+ self,
+ layer_id: int,
+ dim: int,
+ n_heads: int,
+ n_kv_heads: int,
+ multiple_of: int,
+ ffn_dim_multiplier: float,
+ norm_eps: float,
+ qk_norm: bool,
+ modulation=True,
+ z_image_modulation=False,
+ attn_out_bias=False,
+ operation_settings={},
+ ) -> None:
+ """
+ Initialize a TransformerBlock.
+
+ Args:
+ layer_id (int): Identifier for the layer.
+ dim (int): Embedding dimension of the input features.
+ n_heads (int): Number of attention heads.
+ n_kv_heads (Optional[int]): Number of attention heads in key and
+ value features (if using GQA), or set to None for the same as
+ query.
+ multiple_of (int):
+ ffn_dim_multiplier (float):
+ norm_eps (float):
+
+ """
+ super().__init__()
+ self.dim = dim
+ self.head_dim = dim // n_heads
+ self.attention = JointAttention(dim, n_heads, n_kv_heads, qk_norm, out_bias=attn_out_bias, operation_settings=operation_settings)
+ self.feed_forward = FeedForward(
+ dim=dim,
+ hidden_dim=dim,
+ multiple_of=multiple_of,
+ ffn_dim_multiplier=ffn_dim_multiplier,
+ operation_settings=operation_settings,
+ )
+ self.layer_id = layer_id
+ self.attention_norm1 = operation_settings.get("operations").RMSNorm(dim, eps=norm_eps, elementwise_affine=True, device=operation_settings.get("device"), dtype=operation_settings.get("dtype"))
+ self.ffn_norm1 = operation_settings.get("operations").RMSNorm(dim, eps=norm_eps, elementwise_affine=True, device=operation_settings.get("device"), dtype=operation_settings.get("dtype"))
+
+ self.attention_norm2 = operation_settings.get("operations").RMSNorm(dim, eps=norm_eps, elementwise_affine=True, device=operation_settings.get("device"), dtype=operation_settings.get("dtype"))
+ self.ffn_norm2 = operation_settings.get("operations").RMSNorm(dim, eps=norm_eps, elementwise_affine=True, device=operation_settings.get("device"), dtype=operation_settings.get("dtype"))
+
+ self.modulation = modulation
+ if modulation:
+ if z_image_modulation:
+ self.adaLN_modulation = nn.Sequential(
+ operation_settings.get("operations").Linear(
+ min(dim, 256),
+ 4 * dim,
+ bias=True,
+ device=operation_settings.get("device"),
+ dtype=operation_settings.get("dtype"),
+ ),
+ )
+ else:
+ self.adaLN_modulation = nn.Sequential(
+ nn.SiLU(),
+ operation_settings.get("operations").Linear(
+ min(dim, 1024),
+ 4 * dim,
+ bias=True,
+ device=operation_settings.get("device"),
+ dtype=operation_settings.get("dtype"),
+ ),
+ )
+
+ def forward(
+ self,
+ x: torch.Tensor,
+ x_mask: torch.Tensor,
+ freqs_cis: torch.Tensor,
+ adaln_input: Optional[torch.Tensor]=None,
+ timestep_zero_index=None,
+ transformer_options={},
+ ):
+ """
+ Perform a forward pass through the TransformerBlock.
+
+ Args:
+ x (torch.Tensor): Input tensor.
+ freqs_cis (torch.Tensor): Precomputed cosine and sine frequencies.
+
+ Returns:
+ torch.Tensor: Output tensor after applying attention and
+ feedforward layers.
+
+ """
+ if self.modulation:
+ assert adaln_input is not None
+ scale_msa, gate_msa, scale_mlp, gate_mlp = self.adaLN_modulation(adaln_input).chunk(4, dim=1)
+
+ x = x + apply_gate(gate_msa.unsqueeze(1).tanh(), self.attention_norm2(
+ clamp_fp16(self.attention(
+ modulate(self.attention_norm1(x), scale_msa, timestep_zero_index=timestep_zero_index),
+ x_mask,
+ freqs_cis,
+ transformer_options=transformer_options,
+ ))), timestep_zero_index=timestep_zero_index
+ )
+ x = x + apply_gate(gate_mlp.unsqueeze(1).tanh(), self.ffn_norm2(
+ clamp_fp16(self.feed_forward(
+ modulate(self.ffn_norm1(x), scale_mlp, timestep_zero_index=timestep_zero_index),
+ ))), timestep_zero_index=timestep_zero_index
+ )
+ else:
+ assert adaln_input is None
+ x = x + self.attention_norm2(
+ clamp_fp16(self.attention(
+ self.attention_norm1(x),
+ x_mask,
+ freqs_cis,
+ transformer_options=transformer_options,
+ ))
+ )
+ x = x + self.ffn_norm2(
+ self.feed_forward(
+ self.ffn_norm1(x),
+ )
+ )
+ return x
+
+
+class FinalLayer(nn.Module):
+ """
+ The final layer of NextDiT.
+ """
+
+ def __init__(self, hidden_size, patch_size, out_channels, z_image_modulation=False, operation_settings={}):
+ super().__init__()
+ self.norm_final = operation_settings.get("operations").LayerNorm(
+ hidden_size,
+ elementwise_affine=False,
+ eps=1e-6,
+ device=operation_settings.get("device"),
+ dtype=operation_settings.get("dtype"),
+ )
+ self.linear = operation_settings.get("operations").Linear(
+ hidden_size,
+ patch_size * patch_size * out_channels,
+ bias=True,
+ device=operation_settings.get("device"),
+ dtype=operation_settings.get("dtype"),
+ )
+
+ if z_image_modulation:
+ min_mod = 256
+ else:
+ min_mod = 1024
+
+ self.adaLN_modulation = nn.Sequential(
+ nn.SiLU(),
+ operation_settings.get("operations").Linear(
+ min(hidden_size, min_mod),
+ hidden_size,
+ bias=True,
+ device=operation_settings.get("device"),
+ dtype=operation_settings.get("dtype"),
+ ),
+ )
+
+ def forward(self, x, c, timestep_zero_index=None):
+ scale = self.adaLN_modulation(c)
+ x = modulate(self.norm_final(x), scale, timestep_zero_index=timestep_zero_index)
+ x = self.linear(x)
+ return x
+
+
+def pad_zimage(feats, pad_token, pad_tokens_multiple):
+ pad_extra = (-feats.shape[1]) % pad_tokens_multiple
+ return torch.cat((feats, pad_token.to(device=feats.device, dtype=feats.dtype, copy=True).unsqueeze(0).repeat(feats.shape[0], pad_extra, 1)), dim=1), pad_extra
+
+
+def pos_ids_x(start_t, H_tokens, W_tokens, batch_size, device, transformer_options={}):
+ rope_options = transformer_options.get("rope_options", None)
+ h_scale = 1.0
+ w_scale = 1.0
+ h_start = 0
+ w_start = 0
+ if rope_options is not None:
+ h_scale = rope_options.get("scale_y", 1.0)
+ w_scale = rope_options.get("scale_x", 1.0)
+
+ h_start = rope_options.get("shift_y", 0.0)
+ w_start = rope_options.get("shift_x", 0.0)
+ x_pos_ids = torch.zeros((batch_size, H_tokens * W_tokens, 3), dtype=torch.float32, device=device)
+ x_pos_ids[:, :, 0] = start_t
+ x_pos_ids[:, :, 1] = (torch.arange(H_tokens, dtype=torch.float32, device=device) * h_scale + h_start).view(-1, 1).repeat(1, W_tokens).flatten()
+ x_pos_ids[:, :, 2] = (torch.arange(W_tokens, dtype=torch.float32, device=device) * w_scale + w_start).view(1, -1).repeat(H_tokens, 1).flatten()
+ return x_pos_ids
+
+
+class NextDiT(nn.Module):
+ """
+ Diffusion model with a Transformer backbone.
+ """
+
+ def __init__(
+ self,
+ patch_size: int = 2,
+ in_channels: int = 4,
+ dim: int = 4096,
+ n_layers: int = 32,
+ n_refiner_layers: int = 2,
+ n_heads: int = 32,
+ n_kv_heads: Optional[int] = None,
+ multiple_of: int = 256,
+ ffn_dim_multiplier: float = 4.0,
+ norm_eps: float = 1e-5,
+ qk_norm: bool = False,
+ cap_feat_dim: int = 5120,
+ axes_dims: List[int] = (16, 56, 56),
+ axes_lens: List[int] = (1, 512, 512),
+ rope_theta=10000.0,
+ z_image_modulation=False,
+ time_scale=1.0,
+ pad_tokens_multiple=None,
+ clip_text_dim=None,
+ siglip_feat_dim=None,
+ image_model=None,
+ device=None,
+ dtype=None,
+ operations=None,
+ **kwargs,
+ ) -> None:
+ super().__init__()
+ self.dtype = dtype
+ operation_settings = {"operations": operations, "device": device, "dtype": dtype}
+ self.in_channels = in_channels
+ self.out_channels = in_channels
+ self.patch_size = patch_size
+ self.time_scale = time_scale
+ self.pad_tokens_multiple = pad_tokens_multiple
+
+ self.x_embedder = operation_settings.get("operations").Linear(
+ in_features=patch_size * patch_size * in_channels,
+ out_features=dim,
+ bias=True,
+ device=operation_settings.get("device"),
+ dtype=operation_settings.get("dtype"),
+ )
+
+ self.noise_refiner = nn.ModuleList(
+ [
+ JointTransformerBlock(
+ layer_id,
+ dim,
+ n_heads,
+ n_kv_heads,
+ multiple_of,
+ ffn_dim_multiplier,
+ norm_eps,
+ qk_norm,
+ modulation=True,
+ z_image_modulation=z_image_modulation,
+ operation_settings=operation_settings,
+ )
+ for layer_id in range(n_refiner_layers)
+ ]
+ )
+ self.context_refiner = nn.ModuleList(
+ [
+ JointTransformerBlock(
+ layer_id,
+ dim,
+ n_heads,
+ n_kv_heads,
+ multiple_of,
+ ffn_dim_multiplier,
+ norm_eps,
+ qk_norm,
+ modulation=False,
+ operation_settings=operation_settings,
+ )
+ for layer_id in range(n_refiner_layers)
+ ]
+ )
+
+ self.t_embedder = TimestepEmbedder(min(dim, 1024), output_size=256 if z_image_modulation else None, **operation_settings)
+ self.cap_embedder = nn.Sequential(
+ operation_settings.get("operations").RMSNorm(cap_feat_dim, eps=norm_eps, elementwise_affine=True, device=operation_settings.get("device"), dtype=operation_settings.get("dtype")),
+ operation_settings.get("operations").Linear(
+ cap_feat_dim,
+ dim,
+ bias=True,
+ device=operation_settings.get("device"),
+ dtype=operation_settings.get("dtype"),
+ ),
+ )
+
+ self.clip_text_pooled_proj = None
+
+ if clip_text_dim is not None:
+ self.clip_text_dim = clip_text_dim
+ self.clip_text_pooled_proj = nn.Sequential(
+ operation_settings.get("operations").RMSNorm(clip_text_dim, eps=norm_eps, elementwise_affine=True, device=operation_settings.get("device"), dtype=operation_settings.get("dtype")),
+ operation_settings.get("operations").Linear(
+ clip_text_dim,
+ clip_text_dim,
+ bias=True,
+ device=operation_settings.get("device"),
+ dtype=operation_settings.get("dtype"),
+ ),
+ )
+ self.time_text_embed = nn.Sequential(
+ nn.SiLU(),
+ operation_settings.get("operations").Linear(
+ min(dim, 1024) + clip_text_dim,
+ min(dim, 1024),
+ bias=True,
+ device=operation_settings.get("device"),
+ dtype=operation_settings.get("dtype"),
+ ),
+ )
+
+ self.layers = nn.ModuleList(
+ [
+ JointTransformerBlock(
+ layer_id,
+ dim,
+ n_heads,
+ n_kv_heads,
+ multiple_of,
+ ffn_dim_multiplier,
+ norm_eps,
+ qk_norm,
+ z_image_modulation=z_image_modulation,
+ attn_out_bias=False,
+ operation_settings=operation_settings,
+ )
+ for layer_id in range(n_layers)
+ ]
+ )
+
+ if siglip_feat_dim is not None:
+ self.siglip_embedder = nn.Sequential(
+ operation_settings.get("operations").RMSNorm(siglip_feat_dim, eps=norm_eps, elementwise_affine=True, device=operation_settings.get("device"), dtype=operation_settings.get("dtype")),
+ operation_settings.get("operations").Linear(
+ siglip_feat_dim,
+ dim,
+ bias=True,
+ device=operation_settings.get("device"),
+ dtype=operation_settings.get("dtype"),
+ ),
+ )
+ self.siglip_refiner = nn.ModuleList(
+ [
+ JointTransformerBlock(
+ layer_id,
+ dim,
+ n_heads,
+ n_kv_heads,
+ multiple_of,
+ ffn_dim_multiplier,
+ norm_eps,
+ qk_norm,
+ modulation=False,
+ operation_settings=operation_settings,
+ )
+ for layer_id in range(n_refiner_layers)
+ ]
+ )
+ self.siglip_pad_token = nn.Parameter(torch.empty((1, dim), device=device, dtype=dtype))
+ else:
+ self.siglip_embedder = None
+ self.siglip_refiner = None
+ self.siglip_pad_token = None
+
+ # This norm final is in the lumina 2.0 code but isn't actually used for anything.
+ # self.norm_final = operation_settings.get("operations").RMSNorm(dim, eps=norm_eps, elementwise_affine=True, device=operation_settings.get("device"), dtype=operation_settings.get("dtype"))
+ self.final_layer = FinalLayer(dim, patch_size, self.out_channels, z_image_modulation=z_image_modulation, operation_settings=operation_settings)
+
+ if self.pad_tokens_multiple is not None:
+ self.x_pad_token = nn.Parameter(torch.empty((1, dim), device=device, dtype=dtype))
+ self.cap_pad_token = nn.Parameter(torch.empty((1, dim), device=device, dtype=dtype))
+
+ assert (dim // n_heads) == sum(axes_dims)
+ self.axes_dims = axes_dims
+ self.axes_lens = axes_lens
+ self.rope_embedder = EmbedND(dim=dim // n_heads, theta=rope_theta, axes_dim=axes_dims)
+ self.dim = dim
+ self.n_heads = n_heads
+
+ def unpatchify(
+ self, x: torch.Tensor, img_size: List[Tuple[int, int]], cap_size: List[int], return_tensor=False
+ ) -> List[torch.Tensor]:
+ """
+ x: (N, T, patch_size**2 * C)
+ imgs: (N, H, W, C)
+ """
+ pH = pW = self.patch_size
+ imgs = []
+ for i in range(x.size(0)):
+ H, W = img_size[i]
+ begin = cap_size[i]
+ end = begin + (H // pH) * (W // pW)
+ imgs.append(
+ x[i][begin:end]
+ .view(H // pH, W // pW, pH, pW, self.out_channels)
+ .permute(4, 0, 2, 1, 3)
+ .flatten(3, 4)
+ .flatten(1, 2)
+ )
+
+ if return_tensor:
+ imgs = torch.stack(imgs, dim=0)
+ return imgs
+
+ def embed_cap(self, cap_feats=None, offset=0, bsz=1, device=None, dtype=None):
+ if cap_feats is not None:
+ cap_feats = self.cap_embedder(cap_feats)
+ cap_feats_len = cap_feats.shape[1]
+ if self.pad_tokens_multiple is not None:
+ cap_feats, _ = pad_zimage(cap_feats, self.cap_pad_token, self.pad_tokens_multiple)
+ else:
+ cap_feats_len = 0
+ cap_feats = self.cap_pad_token.to(device=device, dtype=dtype, copy=True).unsqueeze(0).repeat(bsz, self.pad_tokens_multiple, 1)
+
+ cap_pos_ids = torch.zeros(bsz, cap_feats.shape[1], 3, dtype=torch.float32, device=device)
+ cap_pos_ids[:, :, 0] = torch.arange(cap_feats.shape[1], dtype=torch.float32, device=device) + 1.0 + offset
+ embeds = (cap_feats,)
+ freqs_cis = (self.rope_embedder(cap_pos_ids).movedim(1, 2),)
+ return embeds, freqs_cis, cap_feats_len
+
+ def embed_all(self, x, cap_feats=None, siglip_feats=None, offset=0, omni=False, transformer_options={}):
+ bsz = 1
+ pH = pW = self.patch_size
+ device = x.device
+ embeds, freqs_cis, cap_feats_len = self.embed_cap(cap_feats, offset=offset, bsz=bsz, device=device, dtype=x.dtype)
+
+ if (not omni) or self.siglip_embedder is None:
+ cap_feats_len = embeds[0].shape[1] + offset
+ embeds += (None,)
+ freqs_cis += (None,)
+ else:
+ cap_feats_len += offset
+ if siglip_feats is not None:
+ b, h, w, c = siglip_feats.shape
+ siglip_feats = siglip_feats.permute(0, 3, 1, 2).reshape(b, h * w, c)
+ siglip_feats = self.siglip_embedder(siglip_feats)
+ siglip_pos_ids = torch.zeros((bsz, siglip_feats.shape[1], 3), dtype=torch.float32, device=device)
+ siglip_pos_ids[:, :, 0] = cap_feats_len + 2
+ siglip_pos_ids[:, :, 1] = (torch.linspace(0, h * 8 - 1, steps=h, dtype=torch.float32, device=device).floor()).view(-1, 1).repeat(1, w).flatten()
+ siglip_pos_ids[:, :, 2] = (torch.linspace(0, w * 8 - 1, steps=w, dtype=torch.float32, device=device).floor()).view(1, -1).repeat(h, 1).flatten()
+ if self.siglip_pad_token is not None:
+ siglip_feats, pad_extra = pad_zimage(siglip_feats, self.siglip_pad_token, self.pad_tokens_multiple) # TODO: double check
+ siglip_pos_ids = torch.nn.functional.pad(siglip_pos_ids, (0, 0, 0, pad_extra))
+ else:
+ if self.siglip_pad_token is not None:
+ siglip_feats = self.siglip_pad_token.to(device=device, dtype=x.dtype, copy=True).unsqueeze(0).repeat(bsz, self.pad_tokens_multiple, 1)
+ siglip_pos_ids = torch.zeros((bsz, siglip_feats.shape[1], 3), dtype=torch.float32, device=device)
+
+ if siglip_feats is None:
+ embeds += (None,)
+ freqs_cis += (None,)
+ else:
+ embeds += (siglip_feats,)
+ freqs_cis += (self.rope_embedder(siglip_pos_ids).movedim(1, 2),)
+
+ B, C, H, W = x.shape
+ x = self.x_embedder(x.view(B, C, H // pH, pH, W // pW, pW).permute(0, 2, 4, 3, 5, 1).flatten(3).flatten(1, 2))
+ x_pos_ids = pos_ids_x(cap_feats_len + 1, H // pH, W // pW, bsz, device, transformer_options=transformer_options)
+ if self.pad_tokens_multiple is not None:
+ x, pad_extra = pad_zimage(x, self.x_pad_token, self.pad_tokens_multiple)
+ x_pos_ids = torch.nn.functional.pad(x_pos_ids, (0, 0, 0, pad_extra))
+
+ embeds += (x,)
+ freqs_cis += (self.rope_embedder(x_pos_ids).movedim(1, 2),)
+ return embeds, freqs_cis, cap_feats_len + len(freqs_cis) - 1
+
+
+ def patchify_and_embed(
+ self, x: torch.Tensor, cap_feats: torch.Tensor, cap_mask: torch.Tensor, t: torch.Tensor, num_tokens, ref_latents=[], ref_contexts=[], siglip_feats=[], transformer_options={}
+ ) -> Tuple[torch.Tensor, torch.Tensor, List[Tuple[int, int]], List[int], torch.Tensor]:
+ bsz = x.shape[0]
+ cap_mask = None # TODO?
+ main_siglip = None
+ orig_x = x
+
+ embeds = ([], [], [])
+ freqs_cis = ([], [], [])
+ leftover_cap = []
+
+ start_t = 0
+ omni = len(ref_latents) > 0
+ if omni:
+ for i, ref in enumerate(ref_latents):
+ if i < len(ref_contexts):
+ ref_con = ref_contexts[i]
+ else:
+ ref_con = None
+ if i < len(siglip_feats):
+ sig_feat = siglip_feats[i]
+ else:
+ sig_feat = None
+
+ out = self.embed_all(ref, ref_con, sig_feat, offset=start_t, omni=omni, transformer_options=transformer_options)
+ for i, e in enumerate(out[0]):
+ if e is not None:
+ embeds[i].append(comfy.utils.repeat_to_batch_size(e, bsz))
+ freqs_cis[i].append(out[1][i])
+ start_t = out[2]
+ leftover_cap = ref_contexts[len(ref_latents):]
+
+ H, W = x.shape[-2], x.shape[-1]
+ img_sizes = [(H, W)] * bsz
+ out = self.embed_all(x, cap_feats, main_siglip, offset=start_t, omni=omni, transformer_options=transformer_options)
+ img_len = out[0][-1].shape[1]
+ cap_len = out[0][0].shape[1]
+ for i, e in enumerate(out[0]):
+ if e is not None:
+ e = comfy.utils.repeat_to_batch_size(e, bsz)
+ embeds[i].append(e)
+ freqs_cis[i].append(out[1][i])
+ start_t = out[2]
+
+ for cap in leftover_cap:
+ out = self.embed_cap(cap, offset=start_t, bsz=bsz, device=x.device, dtype=x.dtype)
+ cap_len += out[0][0].shape[1]
+ embeds[0].append(comfy.utils.repeat_to_batch_size(out[0][0], bsz))
+ freqs_cis[0].append(out[1][0])
+ start_t += out[2]
+
+ patches = transformer_options.get("patches", {})
+
+ # refine context
+ cap_feats = torch.cat(embeds[0], dim=1)
+ cap_freqs_cis = torch.cat(freqs_cis[0], dim=1)
+ for layer in self.context_refiner:
+ cap_feats = layer(cap_feats, cap_mask, cap_freqs_cis, transformer_options=transformer_options)
+
+ feats = (cap_feats,)
+ fc = (cap_freqs_cis,)
+
+ if omni and len(embeds[1]) > 0:
+ siglip_mask = None
+ siglip_feats_combined = torch.cat(embeds[1], dim=1)
+ siglip_feats_freqs_cis = torch.cat(freqs_cis[1], dim=1)
+ if self.siglip_refiner is not None:
+ for layer in self.siglip_refiner:
+ siglip_feats_combined = layer(siglip_feats_combined, siglip_mask, siglip_feats_freqs_cis, transformer_options=transformer_options)
+ feats += (siglip_feats_combined,)
+ fc += (siglip_feats_freqs_cis,)
+
+ padded_img_mask = None
+ x = torch.cat(embeds[-1], dim=1)
+ fc_x = torch.cat(freqs_cis[-1], dim=1)
+ if omni:
+ timestep_zero_index = [(x.shape[1] - img_len, x.shape[1])]
+ else:
+ timestep_zero_index = None
+
+ x_input = x
+ for i, layer in enumerate(self.noise_refiner):
+ x = layer(x, padded_img_mask, fc_x, t, timestep_zero_index=timestep_zero_index, transformer_options=transformer_options)
+ if "noise_refiner" in patches:
+ for p in patches["noise_refiner"]:
+ out = p({"img": x, "img_input": x_input, "txt": cap_feats, "pe": fc_x, "vec": t, "x": orig_x, "block_index": i, "transformer_options": transformer_options, "block_type": "noise_refiner"})
+ if "img" in out:
+ x = out["img"]
+
+ padded_full_embed = torch.cat(feats + (x,), dim=1)
+ if timestep_zero_index is not None:
+ ind = padded_full_embed.shape[1] - x.shape[1]
+ timestep_zero_index = [(ind + x.shape[1] - img_len, ind + x.shape[1])]
+ timestep_zero_index.append((feats[0].shape[1] - cap_len, feats[0].shape[1]))
+
+ mask = None
+ l_effective_cap_len = [padded_full_embed.shape[1] - img_len] * bsz
+ return padded_full_embed, mask, img_sizes, l_effective_cap_len, torch.cat(fc + (fc_x,), dim=1), timestep_zero_index
+
+ def forward(self, x, timesteps, context, num_tokens, attention_mask=None, **kwargs):
+ return comfy.patcher_extension.WrapperExecutor.new_class_executor(
+ self._forward,
+ self,
+ comfy.patcher_extension.get_all_wrappers(comfy.patcher_extension.WrappersMP.DIFFUSION_MODEL, kwargs.get("transformer_options", {}))
+ ).execute(x, timesteps, context, num_tokens, attention_mask, **kwargs)
+
+ # def forward(self, x, t, cap_feats, cap_mask):
+ def _forward(self, x, timesteps, context, num_tokens, attention_mask=None, ref_latents=[], ref_contexts=[], siglip_feats=[], transformer_options={}, **kwargs):
+ omni = len(ref_latents) > 0
+ if omni:
+ timesteps = torch.cat([timesteps * 0, timesteps], dim=0)
+
+ t = 1.0 - timesteps
+ cap_feats = context
+ cap_mask = attention_mask
+ bs, c, h, w = x.shape
+ x = comfy.ldm.common_dit.pad_to_patch_size(x, (self.patch_size, self.patch_size))
+ """
+ Forward pass of NextDiT.
+ t: (N,) tensor of diffusion timesteps
+ y: (N,) tensor of text tokens/features
+ """
+
+ t = self.t_embedder(t * self.time_scale, dtype=x.dtype) # (N, D)
+ adaln_input = t
+
+ if self.clip_text_pooled_proj is not None:
+ pooled = kwargs.get("clip_text_pooled", None)
+ if pooled is not None:
+ pooled = self.clip_text_pooled_proj(pooled)
+ else:
+ pooled = torch.zeros((x.shape[0], self.clip_text_dim), device=x.device, dtype=x.dtype)
+
+ adaln_input = self.time_text_embed(torch.cat((t, pooled), dim=-1))
+
+ patches = transformer_options.get("patches", {})
+ x_is_tensor = isinstance(x, torch.Tensor)
+ img, mask, img_size, cap_size, freqs_cis, timestep_zero_index = self.patchify_and_embed(x, cap_feats, cap_mask, adaln_input, num_tokens, ref_latents=ref_latents, ref_contexts=ref_contexts, siglip_feats=siglip_feats, transformer_options=transformer_options)
+ freqs_cis = freqs_cis.to(img.device)
+
+ transformer_options["total_blocks"] = len(self.layers)
+ transformer_options["block_type"] = "double"
+ img_input = img
+ for i, layer in enumerate(self.layers):
+ transformer_options["block_index"] = i
+ img = layer(img, mask, freqs_cis, adaln_input, timestep_zero_index=timestep_zero_index, transformer_options=transformer_options)
+ if "double_block" in patches:
+ for p in patches["double_block"]:
+ out = p({"img": img[:, cap_size[0]:], "img_input": img_input[:, cap_size[0]:], "txt": img[:, :cap_size[0]], "pe": freqs_cis[:, cap_size[0]:], "vec": adaln_input, "x": x, "block_index": i, "transformer_options": transformer_options})
+ if "img" in out:
+ img[:, cap_size[0]:] = out["img"]
+ if "txt" in out:
+ img[:, :cap_size[0]] = out["txt"]
+
+ img = self.final_layer(img, adaln_input, timestep_zero_index=timestep_zero_index)
+ img = self.unpatchify(img, img_size, cap_size, return_tensor=x_is_tensor)[:, :, :h, :w]
+ return -img
+
+
+#############################################################################
+# Pixel Space Decoder Components #
+#############################################################################
+
+def _modulate_shift_scale(x, shift, scale):
+ return x * (1 + scale) + shift
+
+
+class PixelResBlock(nn.Module):
+ """
+ Residual block with AdaLN modulation, zero-initialised so it starts as
+ an identity at the beginning of training.
+ """
+
+ def __init__(self, channels: int, dtype=None, device=None, operations=None):
+ super().__init__()
+ self.in_ln = operations.LayerNorm(channels, eps=1e-6, dtype=dtype, device=device)
+ self.mlp = nn.Sequential(
+ operations.Linear(channels, channels, bias=True, dtype=dtype, device=device),
+ nn.SiLU(),
+ operations.Linear(channels, channels, bias=True, dtype=dtype, device=device),
+ )
+ self.adaLN_modulation = nn.Sequential(
+ nn.SiLU(),
+ operations.Linear(channels, 3 * channels, bias=True, dtype=dtype, device=device),
+ )
+
+ def forward(self, x: torch.Tensor, y: torch.Tensor) -> torch.Tensor:
+ shift, scale, gate = self.adaLN_modulation(y).chunk(3, dim=-1)
+ h = _modulate_shift_scale(self.in_ln(x), shift, scale)
+ h = self.mlp(h)
+ return x + gate * h
+
+
+class DCTFinalLayer(nn.Module):
+ """Zero-initialised output projection (adopted from DiT)."""
+
+ def __init__(self, model_channels: int, out_channels: int, dtype=None, device=None, operations=None):
+ super().__init__()
+ self.norm_final = operations.LayerNorm(model_channels, elementwise_affine=False, eps=1e-6, dtype=dtype, device=device)
+ self.linear = operations.Linear(model_channels, out_channels, bias=True, dtype=dtype, device=device)
+
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
+ return self.linear(self.norm_final(x))
+
+
+class SimpleMLPAdaLN(nn.Module):
+ """
+ Small MLP decoder head for the pixel-space variant.
+
+ Takes per-patch pixel values and a per-patch conditioning vector from the
+ transformer backbone and predicts the denoised pixel values.
+
+ x : [B*N, P^2, C] – noisy pixel values per patch position
+ c : [B*N, dim] – backbone hidden state per patch (conditioning)
+ → [B*N, P^2, C]
+ """
+
+ def __init__(
+ self,
+ in_channels: int,
+ model_channels: int,
+ out_channels: int,
+ z_channels: int,
+ num_res_blocks: int,
+ max_freqs: int = 8,
+ dtype=None,
+ device=None,
+ operations=None,
+ ):
+ super().__init__()
+ self.dtype = dtype
+
+ # Project backbone hidden state → per-patch conditioning
+ self.cond_embed = operations.Linear(z_channels, model_channels, dtype=dtype, device=device)
+
+ # Input projection with DCT positional encoding
+ self.input_embedder = NerfEmbedder(
+ in_channels=in_channels,
+ hidden_size_input=model_channels,
+ max_freqs=max_freqs,
+ dtype=dtype,
+ device=device,
+ operations=operations,
+ )
+
+ # Residual blocks
+ self.res_blocks = nn.ModuleList([
+ PixelResBlock(model_channels, dtype=dtype, device=device, operations=operations) for _ in range(num_res_blocks)
+ ])
+
+ # Output projection
+ self.final_layer = DCTFinalLayer(model_channels, out_channels, dtype=dtype, device=device, operations=operations)
+
+ def forward(self, x: torch.Tensor, c: torch.Tensor) -> torch.Tensor:
+ # x: [B*N, 1, P^2*C], c: [B*N, dim]
+ original_dtype = x.dtype
+ weight_dtype = self.cond_embed.weight.dtype if hasattr(self.cond_embed, "weight") and self.cond_embed.weight is not None else (self.dtype or x.dtype)
+ x = self.input_embedder(x) # [B*N, 1, model_channels]
+ y = self.cond_embed(c.to(weight_dtype)).unsqueeze(1) # [B*N, 1, model_channels]
+ x = x.to(weight_dtype)
+ for block in self.res_blocks:
+ x = block(x, y)
+ return self.final_layer(x).to(original_dtype) # [B*N, 1, P^2*C]
+
+
+#############################################################################
+# NextDiT – Pixel Space #
+#############################################################################
+
+class NextDiTPixelSpace(NextDiT):
+ """
+ Pixel-space variant of NextDiT.
+
+ Identical transformer backbone to NextDiT, but the output head is replaced
+ with a small MLP decoder (SimpleMLPAdaLN) that operates on raw pixel values
+ per patch rather than a single affine projection.
+
+ Key differences vs NextDiT:
+ • ``final_layer`` is removed; ``dec_net`` (SimpleMLPAdaLN) is used instead.
+ • ``_forward`` stores the raw patchified pixel values before the backbone
+ embedding and feeds them to ``dec_net`` together with the per-patch
+ backbone hidden states.
+ • Supports optional x0 prediction via ``use_x0``.
+ """
+
+ def __init__(
+ self,
+ # decoder-specific
+ decoder_hidden_size: int = 3840,
+ decoder_num_res_blocks: int = 4,
+ decoder_max_freqs: int = 8,
+ decoder_in_channels: int = None, # full flattened patch size (patch_size^2 * in_channels)
+ use_x0: bool = False,
+ # all NextDiT args forwarded unchanged
+ **kwargs,
+ ):
+ super().__init__(**kwargs)
+
+ # Remove the latent-space final layer – not used in pixel space
+ del self.final_layer
+
+ patch_size = kwargs.get("patch_size", 2)
+ in_channels = kwargs.get("in_channels", 4)
+ dim = kwargs.get("dim", 4096)
+
+ # decoder_in_channels is the full flattened patch: patch_size^2 * in_channels
+ dec_in_ch = decoder_in_channels if decoder_in_channels is not None else patch_size ** 2 * in_channels
+
+ self.dec_net = SimpleMLPAdaLN(
+ in_channels=dec_in_ch,
+ model_channels=decoder_hidden_size,
+ out_channels=dec_in_ch,
+ z_channels=dim,
+ num_res_blocks=decoder_num_res_blocks,
+ max_freqs=decoder_max_freqs,
+ dtype=kwargs.get("dtype"),
+ device=kwargs.get("device"),
+ operations=kwargs.get("operations"),
+ )
+
+ if use_x0:
+ self.register_buffer("__x0__", torch.tensor([]))
+
+ # ------------------------------------------------------------------
+ # Forward — mirrors NextDiT._forward exactly, replacing final_layer
+ # with the pixel-space dec_net decoder.
+ # ------------------------------------------------------------------
+ def _forward(self, x, timesteps, context, num_tokens, attention_mask=None, ref_latents=[], ref_contexts=[], siglip_feats=[], transformer_options={}, **kwargs):
+ omni = len(ref_latents) > 0
+ if omni:
+ timesteps = torch.cat([timesteps * 0, timesteps], dim=0)
+
+ t = 1.0 - timesteps
+ cap_feats = context
+ cap_mask = attention_mask
+ bs, c, h, w = x.shape
+ x = comfy.ldm.common_dit.pad_to_patch_size(x, (self.patch_size, self.patch_size))
+
+ t = self.t_embedder(t * self.time_scale, dtype=x.dtype)
+ adaln_input = t
+
+ if self.clip_text_pooled_proj is not None:
+ pooled = kwargs.get("clip_text_pooled", None)
+ if pooled is not None:
+ pooled = self.clip_text_pooled_proj(pooled)
+ else:
+ pooled = torch.zeros((x.shape[0], self.clip_text_dim), device=x.device, dtype=x.dtype)
+ adaln_input = self.time_text_embed(torch.cat((t, pooled), dim=-1))
+
+ # ---- capture raw pixel patches before patchify_and_embed embeds them ----
+ pH = pW = self.patch_size
+ B, C, H, W = x.shape
+ pixel_patches = (
+ x.view(B, C, H // pH, pH, W // pW, pW)
+ .permute(0, 2, 4, 3, 5, 1) # [B, Ht, Wt, pH, pW, C]
+ .flatten(3) # [B, Ht, Wt, pH*pW*C]
+ .flatten(1, 2) # [B, N, pH*pW*C]
+ )
+ N = pixel_patches.shape[1]
+ # decoder sees one token per patch: [B*N, 1, P^2*C]
+ pixel_values = pixel_patches.reshape(B * N, 1, pH * pW * C)
+
+ patches = transformer_options.get("patches", {})
+ x_is_tensor = isinstance(x, torch.Tensor)
+ img, mask, img_size, cap_size, freqs_cis, timestep_zero_index = self.patchify_and_embed(
+ x, cap_feats, cap_mask, adaln_input, num_tokens,
+ ref_latents=ref_latents, ref_contexts=ref_contexts,
+ siglip_feats=siglip_feats, transformer_options=transformer_options
+ )
+ freqs_cis = freqs_cis.to(img.device)
+
+ transformer_options["total_blocks"] = len(self.layers)
+ transformer_options["block_type"] = "double"
+ img_input = img
+ for i, layer in enumerate(self.layers):
+ transformer_options["block_index"] = i
+ img = layer(img, mask, freqs_cis, adaln_input, timestep_zero_index=timestep_zero_index, transformer_options=transformer_options)
+ if "double_block" in patches:
+ for p in patches["double_block"]:
+ out = p({"img": img[:, cap_size[0]:], "img_input": img_input[:, cap_size[0]:], "txt": img[:, :cap_size[0]], "pe": freqs_cis[:, cap_size[0]:], "vec": adaln_input, "x": x, "block_index": i, "transformer_options": transformer_options})
+ if "img" in out:
+ img[:, cap_size[0]:] = out["img"]
+ if "txt" in out:
+ img[:, :cap_size[0]] = out["txt"]
+
+ # ---- pixel-space decoder (replaces final_layer + unpatchify) ----
+ # img may have padding tokens beyond N; only the first N are real image patches
+ img_hidden = img[:, cap_size[0]:cap_size[0] + N, :] # [B, N, dim]
+ decoder_cond = img_hidden.reshape(B * N, self.dim) # [B*N, dim]
+
+ output = self.dec_net(pixel_values, decoder_cond) # [B*N, 1, P^2*C]
+ output = output.reshape(B, N, -1) # [B, N, P^2*C]
+
+ # prepend zero cap placeholder so unpatchify indexing works unchanged
+ cap_placeholder = torch.zeros(
+ B, cap_size[0], output.shape[-1], device=output.device, dtype=output.dtype
+ )
+ img_out = self.unpatchify(
+ torch.cat([cap_placeholder, output], dim=1),
+ img_size, cap_size, return_tensor=x_is_tensor
+ )[:, :, :h, :w]
+
+ return -img_out
+
+ def forward(self, x, timesteps, context, num_tokens, attention_mask=None, **kwargs):
+ # _forward returns neg_x0 = -x0 (negated decoder output).
+ #
+ # Reference inference (working_inference_reference.py):
+ # out = _forward(img, t) # = -x0
+ # pred = (img - out) / t # = (img + x0) / t [_apply_x0_residual]
+ # img += (t_prev - t_curr) * pred # Euler step
+ #
+ # ComfyUI's Euler sampler does the same:
+ # x_next = x + (sigma_next - sigma) * model_output
+ # So model_output must equal pred = (x - neg_x0) / t = (x - (-x0)) / t = (x + x0) / t
+ neg_x0 = comfy.patcher_extension.WrapperExecutor.new_class_executor(
+ self._forward,
+ self,
+ comfy.patcher_extension.get_all_wrappers(comfy.patcher_extension.WrappersMP.DIFFUSION_MODEL, kwargs.get("transformer_options", {}))
+ ).execute(x, timesteps, context, num_tokens, attention_mask, **kwargs)
+
+ return (x - neg_x0) / timesteps.view(-1, 1, 1, 1)
diff --git a/ComfyUI/comfy/ldm/mage_flow/__pycache__/model.cpython-312.pyc b/ComfyUI/comfy/ldm/mage_flow/__pycache__/model.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..03e67b29cef995ab89f61c3fe7cbe77c682d089f
Binary files /dev/null and b/ComfyUI/comfy/ldm/mage_flow/__pycache__/model.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/mage_flow/__pycache__/vae.cpython-312.pyc b/ComfyUI/comfy/ldm/mage_flow/__pycache__/vae.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..214d65e4f3cebca5fffe0db9cdf5118cfc9cdd6c
Binary files /dev/null and b/ComfyUI/comfy/ldm/mage_flow/__pycache__/vae.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/mage_flow/model.py b/ComfyUI/comfy/ldm/mage_flow/model.py
new file mode 100644
index 0000000000000000000000000000000000000000..ac29bb610d17e6c8038b294cc22da8d744cca7da
--- /dev/null
+++ b/ComfyUI/comfy/ldm/mage_flow/model.py
@@ -0,0 +1,186 @@
+# Mage-Flow (https://github.com/microsoft/Mage) native-resolution MMDiT (MIT)
+# Architecture is a 12-layer variant of the Qwen-Image double-stream block with
+# patch_size=1 (no 2x2 packing), unrotated text tokens and a bf16-rounded
+# timestep frequency table.
+import math
+import torch
+import torch.nn as nn
+from typing import Optional, Tuple
+
+from comfy.ldm.lightricks.model import TimestepEmbedding
+from comfy.ldm.flux.layers import EmbedND
+from comfy.ldm.qwen_image.model import QwenImageTransformerBlock, LastLayer
+import comfy.patcher_extension
+
+
+class MageTimestepProjEmbeddings(nn.Module):
+ def __init__(self, embedding_dim, dtype=None, device=None, operations=None):
+ super().__init__()
+ self.timestep_embedder = TimestepEmbedding(
+ in_channels=256, time_embed_dim=embedding_dim,
+ dtype=dtype, device=device, operations=operations
+ )
+
+ def forward(self, timestep, hidden_states):
+ half_dim = 128
+ exponent = -math.log(10000) * torch.arange(half_dim, dtype=torch.float32, device=timestep.device) / half_dim
+ emb = torch.exp(exponent).to(timestep.dtype)
+ emb = timestep[:, None].float() * emb[None, :]
+ emb = 1000.0 * emb
+ emb = torch.cat([torch.sin(emb), torch.cos(emb)], dim=-1)
+ emb = torch.cat([emb[:, half_dim:], emb[:, :half_dim]], dim=-1) # flip_sin_to_cos
+ return self.timestep_embedder(emb.to(dtype=hidden_states.dtype))
+
+
+class MageFlowTransformer2DModel(nn.Module):
+ def __init__(
+ self,
+ in_channels: int = 128,
+ out_channels: Optional[int] = 128,
+ num_layers: int = 12,
+ attention_head_dim: int = 128,
+ num_attention_heads: int = 24,
+ joint_attention_dim: int = 2560,
+ axes_dims_rope: Tuple[int, int, int] = (16, 56, 56),
+ image_model=None,
+ dtype=None,
+ device=None,
+ operations=None,
+ ):
+ super().__init__()
+ self.dtype = dtype
+ self.patch_size = 1
+ self.in_channels = in_channels
+ self.out_channels = out_channels or in_channels
+ self.inner_dim = num_attention_heads * attention_head_dim
+
+ self.pe_embedder = EmbedND(dim=attention_head_dim, theta=10000, axes_dim=list(axes_dims_rope))
+
+ self.time_text_embed = MageTimestepProjEmbeddings(embedding_dim=self.inner_dim, dtype=dtype, device=device, operations=operations)
+
+ self.txt_norm = operations.RMSNorm(joint_attention_dim, eps=1e-6, dtype=dtype, device=device)
+ self.img_in = operations.Linear(in_channels, self.inner_dim, dtype=dtype, device=device)
+ self.txt_in = operations.Linear(joint_attention_dim, self.inner_dim, dtype=dtype, device=device)
+
+ self.transformer_blocks = nn.ModuleList([
+ QwenImageTransformerBlock(
+ dim=self.inner_dim,
+ num_attention_heads=num_attention_heads,
+ attention_head_dim=attention_head_dim,
+ dtype=dtype,
+ device=device,
+ operations=operations
+ )
+ for _ in range(num_layers)
+ ])
+
+ self.norm_out = LastLayer(self.inner_dim, self.inner_dim, dtype=dtype, device=device, operations=operations)
+ self.proj_out = operations.Linear(self.inner_dim, self.out_channels, bias=True, dtype=dtype, device=device)
+
+ def process_img(self, x, index=0):
+ # patch_size=1: tokens are raw latent pixels, no 2x2 packing.
+ bs, c, h, w = x.shape
+ hidden_states = x.movedim(1, -1).reshape(bs, h * w, c)
+
+ img_ids = torch.zeros((h, w, 3), device=x.device)
+ # Frame axis: positive image index (0 = target, 1..N = reference images).
+ img_ids[:, :, 0] = index
+ # Mage scale_rope centering: positions [-ceil(n/2), floor(n/2)), i.e.
+ # offset by (n - n//2). Differs from Qwen-Image's -(n//2) for odd sizes.
+ img_ids[:, :, 1] = img_ids[:, :, 1] + torch.arange(h, device=x.device)[:, None] - (h - h // 2)
+ img_ids[:, :, 2] = img_ids[:, :, 2] + torch.arange(w, device=x.device)[None, :] - (w - w // 2)
+ return hidden_states, img_ids.reshape(h * w, 3).unsqueeze(0).expand(bs, -1, -1), (h, w)
+
+ def forward(self, x, timestep, context, attention_mask=None, ref_latents=None, transformer_options={}, **kwargs):
+ return comfy.patcher_extension.WrapperExecutor.new_class_executor(
+ self._forward,
+ self,
+ comfy.patcher_extension.get_all_wrappers(comfy.patcher_extension.WrappersMP.DIFFUSION_MODEL, transformer_options)
+ ).execute(x, timestep, context, attention_mask, ref_latents, transformer_options, **kwargs)
+
+ def _forward(self, x, timestep, context, attention_mask=None, ref_latents=None, transformer_options={}, control=None, **kwargs):
+ if attention_mask is not None and not torch.is_floating_point(attention_mask):
+ attention_mask = (attention_mask - 1).to(x.dtype) * torch.finfo(x.dtype).max
+
+ hidden_states, img_ids, orig_shape = self.process_img(x)
+ num_embeds = hidden_states.shape[1]
+
+ if ref_latents is not None:
+ ref_num_tokens = []
+ index = 0
+ for ref in ref_latents:
+ index += 1
+ kontext, kontext_ids, _ = self.process_img(ref, index=index)
+ hidden_states = torch.cat([hidden_states, kontext], dim=1)
+ img_ids = torch.cat([img_ids, kontext_ids], dim=1)
+ ref_num_tokens.append(kontext.shape[1])
+ transformer_options = transformer_options.copy()
+ transformer_options["reference_image_num_tokens"] = ref_num_tokens
+
+ # Text tokens are not rotated in Mage-Flow: RoPE at position 0 is the
+ # identity rotation.
+ txt_ids = torch.zeros((x.shape[0], context.shape[1], 3), device=x.device)
+
+ hidden_states = self.img_in(hidden_states)
+ context = self.txt_norm(context)
+ context = self.txt_in(context)
+
+ temb = self.time_text_embed(timestep, hidden_states)
+
+ patches_replace = transformer_options.get("patches_replace", {})
+ patches = transformer_options.get("patches", {})
+ blocks_replace = patches_replace.get("dit", {})
+
+ if "post_input" in patches:
+ for p in patches["post_input"]:
+ out = p({"img": hidden_states, "txt": context, "img_ids": img_ids, "txt_ids": txt_ids, "transformer_options": transformer_options})
+ hidden_states = out["img"]
+ context = out["txt"]
+ img_ids = out["img_ids"]
+ txt_ids = out["txt_ids"]
+
+ ids = torch.cat((txt_ids, img_ids), dim=1)
+ image_rotary_emb = self.pe_embedder(ids).contiguous()
+ del ids, txt_ids, img_ids
+
+ transformer_options["total_blocks"] = len(self.transformer_blocks)
+ transformer_options["block_type"] = "double"
+ for i, block in enumerate(self.transformer_blocks):
+ transformer_options["block_index"] = i
+ if ("double_block", i) in blocks_replace:
+ def block_wrap(args):
+ out = {}
+ out["txt"], out["img"] = block(hidden_states=args["img"], encoder_hidden_states=args["txt"], encoder_hidden_states_mask=attention_mask, temb=args["vec"], image_rotary_emb=args["pe"], transformer_options=args["transformer_options"])
+ return out
+ out = blocks_replace[("double_block", i)]({"img": hidden_states, "txt": context, "vec": temb, "pe": image_rotary_emb, "transformer_options": transformer_options}, {"original_block": block_wrap})
+ hidden_states = out["img"]
+ context = out["txt"]
+ else:
+ context, hidden_states = block(
+ hidden_states=hidden_states,
+ encoder_hidden_states=context,
+ encoder_hidden_states_mask=attention_mask,
+ temb=temb,
+ image_rotary_emb=image_rotary_emb,
+ transformer_options=transformer_options,
+ )
+
+ if "double_block" in patches:
+ for p in patches["double_block"]:
+ out = p({"img": hidden_states, "txt": context, "x": x, "block_index": i, "transformer_options": transformer_options})
+ hidden_states = out["img"]
+ context = out["txt"]
+
+ if control is not None: # Controlnet
+ control_i = control.get("input")
+ if i < len(control_i):
+ add = control_i[i]
+ if add is not None:
+ hidden_states[:, :add.shape[1]] += add
+
+ hidden_states = self.norm_out(hidden_states, temb)
+ hidden_states = self.proj_out(hidden_states)
+
+ hidden_states = hidden_states[:, :num_embeds]
+ h, w = orig_shape
+ return hidden_states.reshape(x.shape[0], h, w, self.out_channels).movedim(-1, 1)
diff --git a/ComfyUI/comfy/ldm/mage_flow/vae.py b/ComfyUI/comfy/ldm/mage_flow/vae.py
new file mode 100644
index 0000000000000000000000000000000000000000..e6e21b99f5e6f4a321be9acdb401d25ea4a0c162
--- /dev/null
+++ b/ComfyUI/comfy/ldm/mage_flow/vae.py
@@ -0,0 +1,477 @@
+# Mage-VAE (https://github.com/microsoft/Mage) (MIT)
+# Symmetric one-step diffusion codec: DConvEncoder (image -> 128ch latent) and
+# DConvDenoiser + CoD Decoder (latent -> image). 16x downsample, latents in the
+# Flux.2-VAE-anchored space (no patch packing, no BN normalization).
+# Both encode and decode are single forward passes at t=0.
+import math
+
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+
+import comfy.ops
+from comfy.ldm.modules.diffusionmodules.model import vae_attention
+
+ops = comfy.ops.disable_weight_init
+
+
+def nonlinearity(x):
+ return torch.nn.functional.silu(x)
+
+
+def Normalize(in_channels):
+ return ops.GroupNorm(num_groups=32, num_channels=in_channels, eps=1e-6, affine=True)
+
+
+def modulate(x, shift, scale):
+ if x.dim() == 4:
+ b, c = x.shape[:2]
+ return x * (1 + scale.view(b, c, 1, 1)) + shift.view(b, c, 1, 1)
+ return x * (1 + scale.unsqueeze(1)) + shift.unsqueeze(1)
+
+
+class LayerNorm2d(ops.LayerNorm):
+ def __init__(self, num_channels, eps=1e-6, affine=True):
+ super().__init__(num_channels, eps=eps, elementwise_affine=affine)
+
+ def forward(self, x):
+ x = x.permute(0, 2, 3, 1).contiguous()
+ x = super().forward(x)
+ return x.permute(0, 3, 1, 2).contiguous()
+
+
+class TimestepEmbedder(nn.Module):
+ """DConv-style timestep MLP (max_period=10000, freq_size=256)."""
+
+ def __init__(self, hidden_size, frequency_embedding_size=256):
+ super().__init__()
+ self.mlp = nn.Sequential(
+ ops.Linear(frequency_embedding_size, hidden_size, bias=True),
+ nn.SiLU(),
+ ops.Linear(hidden_size, hidden_size, bias=True),
+ )
+ self.frequency_embedding_size = frequency_embedding_size
+
+ @staticmethod
+ def timestep_embedding(t, dim, max_period=10000):
+ half = dim // 2
+ freqs = torch.exp(
+ -math.log(max_period) * torch.arange(0, half, dtype=torch.float32) / half
+ ).to(t.device)
+ args = t[:, None].float() * freqs[None]
+ emb = torch.cat([torch.cos(args), torch.sin(args)], dim=-1)
+ if dim % 2:
+ emb = torch.cat([emb, torch.zeros_like(emb[:, :1])], dim=-1)
+ return emb
+
+ def forward(self, t, dtype):
+ emb = self.timestep_embedding(t, self.frequency_embedding_size)
+ return self.mlp(emb.to(dtype))
+
+
+class BottleneckPatchEmbed(nn.Module):
+ """Image patch embed concatenated with a per-patch conditioning vector."""
+
+ def __init__(self, patch_size=16, in_chans=3, pca_dim=128, embed_dim=384, bias=True):
+ super().__init__()
+ self.proj1 = ops.Conv2d(in_chans, pca_dim, kernel_size=patch_size, stride=patch_size, bias=False)
+ self.proj2 = ops.Conv2d(pca_dim + embed_dim, embed_dim, kernel_size=1, bias=bias)
+
+ def forward(self, x, cond):
+ return self.proj2(torch.cat([self.proj1(x), cond], dim=1))
+
+
+class DiCoBlock(nn.Module):
+ """DConv block with adaLN modulation."""
+
+ def __init__(self, hidden_size, mlp_ratio=4.0):
+ super().__init__()
+ self.conv1 = ops.Conv2d(hidden_size, hidden_size, 1, bias=True)
+ self.conv2 = ops.Conv2d(hidden_size, hidden_size, 3, padding=1, groups=hidden_size, bias=True)
+ self.conv3 = ops.Conv2d(hidden_size, hidden_size, 1, bias=True)
+
+ self.ca = nn.Sequential(
+ nn.AdaptiveAvgPool2d(1),
+ ops.Conv2d(hidden_size, hidden_size, 1, bias=True),
+ nn.Sigmoid(),
+ )
+
+ ffn = int(mlp_ratio * hidden_size)
+ self.conv4 = ops.Conv2d(hidden_size, ffn, 1, bias=True)
+ self.conv5 = ops.Conv2d(ffn, hidden_size, 1, bias=True)
+
+ self.norm1 = LayerNorm2d(hidden_size, affine=False)
+ self.norm2 = LayerNorm2d(hidden_size, affine=False)
+
+ self.adaLN_modulation = nn.Sequential(
+ nn.SiLU(),
+ ops.Linear(hidden_size, 6 * hidden_size, bias=True),
+ )
+
+ def forward(self, inp, c):
+ shift_msa, scale_msa, gate_msa, shift_mlp, scale_mlp, gate_mlp = self.adaLN_modulation(c).chunk(6, dim=1)
+ x = modulate(self.norm1(inp), shift_msa, scale_msa)
+ x = F.gelu(self.conv2(self.conv1(x)))
+ x = x * self.ca(x)
+ x = self.conv3(x)
+ x = inp + gate_msa[..., None, None] * x
+ x = x + gate_mlp[..., None, None] * self.conv5(
+ F.gelu(self.conv4(modulate(self.norm2(x), shift_mlp, scale_mlp)))
+ )
+ return x
+
+
+class EncoderDiCoBlock(nn.Module):
+ """DiCoBlock without adaLN, for the encoder head pathway."""
+
+ def __init__(self, hidden_size, mlp_ratio=4.0):
+ super().__init__()
+ self.conv1 = ops.Conv2d(hidden_size, hidden_size, 1, bias=True)
+ self.conv2 = ops.Conv2d(hidden_size, hidden_size, 3, padding=1, groups=hidden_size, bias=True)
+ self.conv3 = ops.Conv2d(hidden_size, hidden_size, 1, bias=True)
+ self.ca = nn.Sequential(
+ nn.AdaptiveAvgPool2d(1),
+ ops.Conv2d(hidden_size, hidden_size, 1, bias=True),
+ nn.Sigmoid(),
+ )
+ ffn = int(mlp_ratio * hidden_size)
+ self.conv4 = ops.Conv2d(hidden_size, ffn, 1, bias=True)
+ self.conv5 = ops.Conv2d(ffn, hidden_size, 1, bias=True)
+ self.norm1 = LayerNorm2d(hidden_size)
+ self.norm2 = LayerNorm2d(hidden_size)
+
+ def forward(self, inp):
+ x = self.norm1(inp)
+ x = F.gelu(self.conv2(self.conv1(x)))
+ x = x * self.ca(x)
+ x = self.conv3(x)
+ x = inp + x
+ return x + self.conv5(F.gelu(self.conv4(self.norm2(x))))
+
+
+class NerfEmbedder(nn.Module):
+ """Patch-position embedder used by the DConv decoder x-pathway."""
+
+ def __init__(self, in_channels, hidden_size_input, max_freqs=8):
+ super().__init__()
+ self.max_freqs = max_freqs
+ self.embedder = nn.Sequential(
+ ops.Linear(in_channels + max_freqs ** 2, hidden_size_input, bias=True),
+ )
+
+ def fetch_pos(self, patch_size, device, dtype):
+ pos = torch.linspace(0, 1, patch_size, device=device, dtype=dtype)
+ pos_y, pos_x = torch.meshgrid(pos, pos, indexing="ij")
+ pos_x = pos_x.reshape(-1, 1, 1)
+ pos_y = pos_y.reshape(-1, 1, 1)
+ freqs = torch.linspace(0, self.max_freqs, self.max_freqs, dtype=dtype, device=device)
+ fx = freqs[None, :, None]
+ fy = freqs[None, None, :]
+ coeffs = (1 + fx * fy) ** -1
+ dct_x = torch.cos(pos_x * fx * torch.pi)
+ dct_y = torch.cos(pos_y * fy * torch.pi)
+ return (dct_x * dct_y * coeffs).view(1, -1, self.max_freqs ** 2)
+
+ def forward(self, x):
+ B, P2, _ = x.shape
+ ps = int(P2 ** 0.5)
+ dct = self.fetch_pos(ps, x.device, x.dtype).expand(B, -1, -1)
+ return self.embedder(torch.cat([x, dct], dim=-1))
+
+
+class NerfFinalLayer(nn.Module):
+ def __init__(self, hidden_size, out_channels):
+ super().__init__()
+ self.norm = ops.RMSNorm(hidden_size, eps=1e-6)
+ self.linear = ops.Linear(hidden_size, out_channels, bias=True)
+
+ def forward(self, x):
+ return self.linear(self.norm(x))
+
+
+class MLPResBlock(nn.Module):
+ def __init__(self, channels):
+ super().__init__()
+ self.in_ln = ops.LayerNorm(channels, eps=1e-6)
+ self.mlp = nn.Sequential(
+ ops.Linear(channels, channels, bias=True),
+ nn.SiLU(),
+ ops.Linear(channels, channels, bias=True),
+ )
+ self.adaLN_modulation = nn.Sequential(
+ nn.SiLU(),
+ ops.Linear(channels, 3 * channels, bias=True),
+ )
+
+ def forward(self, x, y):
+ shift, scale, gate = self.adaLN_modulation(y).chunk(3, dim=-1)
+ h = self.in_ln(x) * (1 + scale) + shift
+ return x + gate * self.mlp(h)
+
+
+class SimpleMLPAdaLN(nn.Module):
+ """Final small MLP that maps NerfEmbedder features to per-patch RGB."""
+
+ def __init__(self, in_channels, model_channels, out_channels, z_channels, num_res_blocks, patch_size):
+ super().__init__()
+ self.in_channels = in_channels
+ self.model_channels = model_channels
+ self.out_channels = out_channels
+ self.num_res_blocks = num_res_blocks
+ self.patch_size = patch_size
+
+ self.cond_embed = ops.Linear(z_channels, patch_size ** 2 * model_channels)
+ self.input_proj = ops.Linear(in_channels, model_channels)
+
+ self.res_blocks = nn.ModuleList(MLPResBlock(model_channels) for _ in range(num_res_blocks))
+
+ def forward(self, x, c):
+ x = self.input_proj(x)
+ c = self.cond_embed(c).reshape(c.shape[0], self.patch_size ** 2, -1)
+ for block in self.res_blocks:
+ x = block(x, c)
+ return x
+
+
+class ResnetBlock(nn.Module):
+ """GroupNorm + Conv ResBlock used by the CoD Decoder."""
+
+ def __init__(self, *, in_channels, out_channels=None):
+ super().__init__()
+ out_channels = out_channels or in_channels
+ self.in_channels = in_channels
+ self.out_channels = out_channels
+
+ self.norm1 = Normalize(in_channels)
+ self.conv1 = ops.Conv2d(in_channels, out_channels, 3, padding=1)
+ self.norm2 = Normalize(out_channels)
+ self.conv2 = ops.Conv2d(out_channels, out_channels, 3, padding=1)
+ if in_channels != out_channels:
+ self.nin_shortcut = ops.Conv2d(in_channels, out_channels, 1)
+
+ def forward(self, x):
+ h = self.conv1(nonlinearity(self.norm1(x)))
+ h = self.conv2(nonlinearity(self.norm2(h)))
+ if self.in_channels != self.out_channels:
+ x = self.nin_shortcut(x)
+ return x + h
+
+
+class AttnBlock(nn.Module):
+ """Patched (windowed) self-attention used by the CoD Decoder."""
+
+ def __init__(self, in_channels, patch_size=32):
+ super().__init__()
+ self.in_channels = in_channels
+ self.patch_size = patch_size
+ self.norm = Normalize(in_channels)
+ self.q = ops.Conv2d(in_channels, in_channels, 1)
+ self.k = ops.Conv2d(in_channels, in_channels, 1)
+ self.v = ops.Conv2d(in_channels, in_channels, 1)
+ self.proj_out = ops.Conv2d(in_channels, in_channels, 1)
+ # VAE attention selection: full-precision backends only (no sage/quantized attention)
+ self.optimized_attention = vae_attention()
+
+ def forward(self, x):
+ h_ = self.norm(x)
+ Q = self.q(h_)
+ K = self.k(h_)
+ V = self.v(h_)
+
+ d = self.patch_size
+ b, c, H, W = Q.shape
+ pad_h = (d - H % d) % d
+ pad_w = (d - W % d) % d
+ if pad_h or pad_w:
+ Q = F.pad(Q, (0, pad_w, 0, pad_h), mode="replicate")
+ K = F.pad(K, (0, pad_w, 0, pad_h), mode="replicate")
+ V = F.pad(V, (0, pad_w, 0, pad_h), mode="replicate")
+ _, _, H_pad, W_pad = Q.shape
+ nph, npw = H_pad // d, W_pad // d
+ np_ = nph * npw
+
+ def to_patches(t):
+ return (t.reshape(b, c, nph, d, npw, d)
+ .permute(0, 2, 4, 1, 3, 5)
+ .reshape(b * np_, c, d * d))
+
+ # [b*np, c, d*d]: attention over the d*d spatial positions of each window
+ Q = to_patches(Q)
+ K = to_patches(K)
+ V = to_patches(V)
+
+ h_ = self.optimized_attention(Q, K, V)
+ h_ = h_.reshape(b, nph, npw, c, d, d).permute(0, 3, 1, 4, 2, 5).reshape(b, c, H_pad, W_pad)
+ if pad_h or pad_w:
+ h_ = h_[:, :, :H, :W]
+ return x + self.proj_out(h_)
+
+
+class CoDDecoder(nn.Module):
+ """CoD Decoder: latent -> conditioning features for the denoiser (ds=16, light)."""
+
+ def __init__(self, out_ch=384, z_ch=128):
+ super().__init__()
+ self.conv_in = ops.Conv2d(z_ch, out_ch, kernel_size=3, stride=1, padding=1)
+ self.block = nn.Sequential(
+ ResnetBlock(in_channels=out_ch, out_channels=out_ch),
+ AttnBlock(out_ch, patch_size=32),
+ ResnetBlock(in_channels=out_ch, out_channels=out_ch),
+ AttnBlock(out_ch, patch_size=32),
+ ResnetBlock(in_channels=out_ch, out_channels=out_ch),
+ )
+ self.norm_out = Normalize(out_ch)
+ self.conv_out = ops.Conv2d(out_ch, out_ch, kernel_size=3, stride=1, padding=1)
+ self.ada = nn.Identity()
+
+ def forward(self, z):
+ h = self.block(self.conv_in(z))
+ h = self.conv_out(nonlinearity(self.norm_out(h)))
+ return self.ada(h)
+
+
+class DConvEncoder(nn.Module):
+ """DConvEncoder: image -> packed (mean, logvar) latent."""
+
+ def __init__(
+ self,
+ z_ch=128,
+ hidden_size=384,
+ num_blocks=21,
+ patch_size=16,
+ mlp_ratio=4.0,
+ head_size=768,
+ num_head_blocks=2,
+ out_ch_mult=2,
+ ):
+ super().__init__()
+ self.z_ch = z_ch
+ self.patch_size = patch_size
+ self.patch_cond_embed = ops.Conv2d(3, head_size, kernel_size=patch_size, stride=patch_size, bias=True)
+ self.head_blocks = nn.ModuleList([
+ EncoderDiCoBlock(head_size, mlp_ratio=mlp_ratio) for _ in range(num_head_blocks)
+ ])
+ self.proj_down = ops.Conv2d(head_size, hidden_size, kernel_size=1, bias=True)
+ self.z_proj = ops.Conv2d(z_ch, hidden_size, kernel_size=1, bias=True)
+ self.fuse_proj = ops.Conv2d(hidden_size * 2, hidden_size, kernel_size=1, bias=True)
+ self.t_embedder = TimestepEmbedder(hidden_size)
+ self.blocks = nn.ModuleList([
+ DiCoBlock(hidden_size, mlp_ratio=mlp_ratio) for _ in range(num_blocks)
+ ])
+ self.norm_out = LayerNorm2d(hidden_size)
+ self.proj_out = ops.Conv2d(hidden_size, z_ch * out_ch_mult, kernel_size=1, bias=True)
+
+ def forward_pred(self, z_t, t, y):
+ cond = self.patch_cond_embed(y)
+ for block in self.head_blocks:
+ cond = block(cond)
+ cond = self.proj_down(cond)
+
+ s = self.fuse_proj(torch.cat([cond, self.z_proj(z_t)], dim=1))
+ c = self.t_embedder(t.view(-1), y.dtype)
+ for block in self.blocks:
+ s = block(s, c)
+ return self.proj_out(self.norm_out(s))
+
+
+class YEmbedder(nn.Module):
+ """Holds only the CoD decoder (the original Flux2-VAE encoder side is dropped at load)."""
+
+ def __init__(self, ch=384, z_ch=128):
+ super().__init__()
+ self.decoder = CoDDecoder(out_ch=ch, z_ch=z_ch)
+
+
+class DConvDenoiser(nn.Module):
+ """One-step DConv denoiser: latent (via cond) + zero noise -> reconstructed image."""
+
+ def __init__(
+ self,
+ patch_size=16,
+ in_channels=3,
+ hidden_size=384,
+ hidden_size_x=32,
+ mlp_ratio=4.0,
+ num_blocks=24,
+ num_cond_blocks=21,
+ bottleneck_dim=128,
+ ):
+ super().__init__()
+ self.in_channels = in_channels
+ self.patch_size = patch_size
+ self.hidden_size = hidden_size
+ self.num_cond_blocks = num_cond_blocks
+
+ self.t_embedder = TimestepEmbedder(hidden_size)
+ self.y_embedder_x = ops.Conv2d(hidden_size, hidden_size_x * patch_size ** 2, 1, 1, 0)
+ self.x_embedder = NerfEmbedder(in_channels + hidden_size_x, hidden_size_x, max_freqs=8)
+ self.s_embedder = BottleneckPatchEmbed(patch_size, in_channels, bottleneck_dim, hidden_size, bias=True)
+ self.blocks = nn.ModuleList([
+ DiCoBlock(hidden_size, mlp_ratio=mlp_ratio) for _ in range(num_cond_blocks)
+ ])
+ self.dec_net = SimpleMLPAdaLN(
+ in_channels=hidden_size_x,
+ model_channels=hidden_size_x,
+ out_channels=in_channels,
+ z_channels=hidden_size,
+ num_res_blocks=num_blocks - num_cond_blocks,
+ patch_size=patch_size,
+ )
+ self.final_layer = NerfFinalLayer(hidden_size_x, in_channels)
+ self.y_embedder = YEmbedder(ch=hidden_size, z_ch=bottleneck_dim)
+
+ def forward(self, x, t, cond):
+ b, _, h, w = x.shape
+ c = self.t_embedder(t.view(-1), x.dtype)
+
+ s = self.s_embedder(x, cond)
+ for block in self.blocks:
+ s = block(s, c)
+
+ length = s.shape[-2] * s.shape[-1]
+ s = s.permute(0, 2, 3, 1).reshape(-1, self.hidden_size)
+
+ x = torch.nn.functional.unfold(x, kernel_size=self.patch_size, stride=self.patch_size)
+ x = torch.cat([x, self.y_embedder_x(cond).flatten(2)], dim=1)
+ x = x.reshape(b, -1, self.patch_size ** 2, length).permute(0, 3, 2, 1).flatten(0, 1)
+ x = self.x_embedder(x)
+
+ x = self.dec_net(x, s)
+ x = self.final_layer(x)
+ x = x.transpose(1, 2).reshape(b, length, -1)
+ return torch.nn.functional.fold(
+ x.transpose(1, 2).contiguous(), (h, w),
+ kernel_size=self.patch_size, stride=self.patch_size,
+ )
+
+
+class MageVAE(nn.Module):
+ """
+ Encode: DConvEncoder (one-step at t=0) -> posterior mean [B, 128, H/16, W/16]
+ Decode: DConvDenoiser + CoD Decoder -> image [B, 3, H, W] in [-1, 1]
+ """
+
+ latent_channels = 128
+ downsample_factor = 16
+
+ def __init__(self):
+ super().__init__()
+ self.dconv_encoder = DConvEncoder()
+ self.decoder_model = DConvDenoiser()
+
+ def encode(self, x):
+ B, _, H, W = x.shape
+ ps = self.dconv_encoder.patch_size
+ z_t = torch.zeros(B, self.dconv_encoder.z_ch, H // ps, W // ps, device=x.device, dtype=x.dtype)
+ t = torch.zeros(B, device=x.device, dtype=x.dtype)
+ out = self.dconv_encoder.forward_pred(z_t, t, x)
+ return out[:, : self.latent_channels] # posterior mean (sample_posterior=False)
+
+ def decode(self, z):
+ cond = self.decoder_model.y_embedder.decoder(z)
+ B = z.shape[0]
+ H = z.shape[2] * self.downsample_factor
+ W = z.shape[3] * self.downsample_factor
+ noise = torch.zeros(B, 3, H, W, device=z.device, dtype=z.dtype)
+ t = torch.zeros(B, device=z.device, dtype=z.dtype)
+ return self.decoder_model.forward(noise, t, cond)
diff --git a/ComfyUI/comfy/ldm/minimax/__pycache__/audio_vae.cpython-312.pyc b/ComfyUI/comfy/ldm/minimax/__pycache__/audio_vae.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..f50a56439551caeb5b2cba81d32ce125832039b6
Binary files /dev/null and b/ComfyUI/comfy/ldm/minimax/__pycache__/audio_vae.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/minimax/__pycache__/model.cpython-312.pyc b/ComfyUI/comfy/ldm/minimax/__pycache__/model.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..9fe77e550deffebabcdd5cf60e1d5eeb2c399cd7
Binary files /dev/null and b/ComfyUI/comfy/ldm/minimax/__pycache__/model.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/minimax/__pycache__/vae.cpython-312.pyc b/ComfyUI/comfy/ldm/minimax/__pycache__/vae.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..63fabc84930ace7d9cc6ae264513e33642a4c098
Binary files /dev/null and b/ComfyUI/comfy/ldm/minimax/__pycache__/vae.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/minimax/audio_vae.py b/ComfyUI/comfy/ldm/minimax/audio_vae.py
new file mode 100644
index 0000000000000000000000000000000000000000..a1be63d5474b8c264198b787b37aa81b17da58fd
--- /dev/null
+++ b/ComfyUI/comfy/ldm/minimax/audio_vae.py
@@ -0,0 +1,443 @@
+# MiniMax H3 audio VAE: DAC-lineage waveform encoder + BigVGAN decoder.
+# Weight-norm parametrizations are folded into plain conv weights, so this
+# module uses ordinary ops.Conv1d / ops.ConvTranspose1d and loads the converted
+# checkpoint (plain "*.weight" tensors) with strict=True.
+#
+# Lineage / licenses of the reference implementation:
+# DAC encoder: descript-audio-codec (MIT)
+# BigVGAN decoder: NVIDIA BigVGAN (MIT), adapted from hifi-gan (MIT)
+# Alias-free ops: junjun3518/alias-free-torch (Apache-2.0), julius (MIT)
+
+import math
+
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+
+import comfy.ops
+
+ops = comfy.ops.disable_weight_init
+
+
+# Snake activations
+
+def snake(x, alpha, beta):
+ # x + 1/beta * sin^2(alpha * x)
+ t = torch.sin(alpha * x)
+ return t.mul_(t).mul_((beta + 1e-9).reciprocal()).add_(x)
+
+
+class Snake1d(nn.Module):
+ """Snake activation with per-channel alpha (encoder side)."""
+
+ def __init__(self, channels):
+ super().__init__()
+ self.alpha = nn.Parameter(torch.empty(1, channels, 1))
+
+ def forward(self, x):
+ alpha = comfy.ops.cast_to_input(self.alpha, x)
+ return snake(x, alpha, alpha)
+
+
+class SnakeBeta(nn.Module):
+ """SnakeBeta := x + 1/beta * sin^2(alpha * x); alpha/beta stored in log scale."""
+
+ def __init__(self, in_features):
+ super().__init__()
+ self.alpha = nn.Parameter(torch.empty(in_features))
+ self.beta = nn.Parameter(torch.empty(in_features))
+
+ def forward(self, x):
+ alpha = torch.exp(comfy.ops.cast_to_input(self.alpha, x)).view(1, -1, 1)
+ beta = torch.exp(comfy.ops.cast_to_input(self.beta, x)).view(1, -1, 1)
+ return snake(x, alpha, beta)
+
+
+# Alias-free (anti-aliased) activation: kaiser-windowed sinc resampling
+
+def kaiser_sinc_filter1d(cutoff, half_width, kernel_size):
+ # returns filter [1, 1, kernel_size]
+ even = kernel_size % 2 == 0
+ half_size = kernel_size // 2
+
+ # kaiser window design
+ delta_f = 4 * half_width
+ A = 2.285 * (half_size - 1) * math.pi * delta_f + 7.95
+ if A > 50.0:
+ beta = 0.1102 * (A - 8.7)
+ elif A >= 21.0:
+ beta = 0.5842 * (A - 21) ** 0.4 + 0.07886 * (A - 21.0)
+ else:
+ beta = 0.0
+ window = torch.kaiser_window(kernel_size, beta=beta, periodic=False)
+
+ if even:
+ time = torch.arange(-half_size, half_size) + 0.5
+ else:
+ time = torch.arange(kernel_size) - half_size
+
+ filter_ = 2 * cutoff * window * torch.sinc(2 * cutoff * time)
+ # Normalize filter to have sum = 1, otherwise there is a small leakage of
+ # the constant component in the input signal.
+ filter_ /= filter_.sum()
+ return filter_.view(1, 1, kernel_size)
+
+
+class UpSample1d(nn.Module):
+ def __init__(self, ratio=2, kernel_size=12):
+ super().__init__()
+ self.ratio = ratio
+ self.stride = ratio
+ self.pad = kernel_size // ratio - 1
+ self.pad_left = self.pad * ratio + (kernel_size - ratio) // 2
+ self.pad_right = self.pad * ratio + (kernel_size - ratio + 1) // 2
+ self.register_buffer(
+ "filter",
+ kaiser_sinc_filter1d(cutoff=0.5 / ratio, half_width=0.6 / ratio, kernel_size=kernel_size),
+ )
+
+ def forward(self, x):
+ _, C, _ = x.shape
+ x = F.pad(x, (self.pad, self.pad), mode="replicate")
+ x = F.conv_transpose1d(x, self.filter.expand(C, -1, -1).to(x.dtype), stride=self.stride, groups=C).mul_(self.ratio)
+ x = x[..., self.pad_left:-self.pad_right]
+ return x
+
+
+class LowPassFilter1d(nn.Module):
+ def __init__(self, cutoff=0.5, half_width=0.6, stride=1, kernel_size=12):
+ super().__init__()
+ self.pad_left = kernel_size // 2 - int(kernel_size % 2 == 0)
+ self.pad_right = kernel_size // 2
+ self.stride = stride
+ self.register_buffer("filter", kaiser_sinc_filter1d(cutoff, half_width, kernel_size))
+
+ def forward(self, x):
+ _, C, _ = x.shape
+ x = F.pad(x, (self.pad_left, self.pad_right), mode="replicate")
+ return F.conv1d(x, self.filter.expand(C, -1, -1).to(x.dtype), stride=self.stride, groups=C)
+
+
+class DownSample1d(nn.Module):
+ def __init__(self, ratio=2, kernel_size=12):
+ super().__init__()
+ self.ratio = ratio
+ self.kernel_size = kernel_size
+ self.lowpass = LowPassFilter1d(
+ cutoff=0.5 / ratio,
+ half_width=0.6 / ratio,
+ stride=ratio,
+ kernel_size=self.kernel_size,
+ )
+
+ def forward(self, x):
+ return self.lowpass(x)
+
+
+class Activation1d(nn.Module):
+ """upsample x2 -> pointwise activation -> downsample x2 (anti-aliased)."""
+
+ def __init__(self, activation, up_ratio=2, down_ratio=2, up_kernel_size=12, down_kernel_size=12):
+ super().__init__()
+ self.act = activation
+ self.upsample = UpSample1d(up_ratio, up_kernel_size)
+ self.downsample = DownSample1d(down_ratio, down_kernel_size)
+
+ def forward(self, x):
+ x = self.upsample(x)
+ x = self.act(x)
+ x = self.downsample(x)
+ return x
+
+
+# DAC encoder
+
+class ResidualUnit(nn.Module):
+ def __init__(self, dim=16, dilation=1):
+ super().__init__()
+ pad = ((7 - 1) * dilation) // 2
+ self.block = nn.Sequential(
+ Snake1d(dim),
+ ops.Conv1d(dim, dim, kernel_size=7, dilation=dilation, padding=pad),
+ Snake1d(dim),
+ ops.Conv1d(dim, dim, kernel_size=1),
+ )
+
+ def forward(self, x):
+ y = self.block(x)
+ pad = (x.shape[-1] - y.shape[-1]) // 2
+ if pad > 0:
+ x = x[..., pad:-pad]
+ return y.add_(x)
+
+
+class EncoderBlock(nn.Module):
+ def __init__(self, dim=16, stride=1):
+ super().__init__()
+ self.block = nn.Sequential(
+ ResidualUnit(dim // 2, dilation=1),
+ ResidualUnit(dim // 2, dilation=3),
+ ResidualUnit(dim // 2, dilation=9),
+ Snake1d(dim // 2),
+ ops.Conv1d(
+ dim // 2,
+ dim,
+ kernel_size=2 * stride,
+ stride=stride,
+ padding=math.ceil(stride / 2),
+ ),
+ )
+
+ def forward(self, x):
+ return self.block(x)
+
+
+class Encoder(nn.Module):
+ def __init__(self, d_model=64, strides=(2, 4, 4, 5, 5), d_latent=2048):
+ super().__init__()
+ block = [ops.Conv1d(1, d_model, kernel_size=7, padding=3)]
+ for stride in strides:
+ d_model *= 2
+ block += [EncoderBlock(d_model, stride=stride)]
+ block += [
+ Snake1d(d_model),
+ ops.Conv1d(d_model, d_latent, kernel_size=3, padding=1),
+ ]
+ self.block = nn.Sequential(*block)
+
+ def forward(self, x):
+ return self.block(x)
+
+
+# Attention projection (encoder posterior head)
+
+class GeGluMlp(nn.Module):
+ def __init__(self, in_features, hidden_features):
+ super().__init__()
+ self.norm = ops.LayerNorm(in_features)
+ self.act = nn.GELU(approximate="tanh")
+ self.w0 = ops.Linear(in_features, hidden_features)
+ self.w1 = ops.Linear(in_features, hidden_features)
+ self.w2 = ops.Linear(hidden_features, in_features)
+
+ def forward(self, x):
+ x = self.norm(x)
+ return self.w2(self.act(self.w0(x)).mul_(self.w1(x)))
+
+
+class CausalAttention(nn.Module):
+ def __init__(self, in_dim, out_dim, num_heads):
+ super().__init__()
+ self.head_dim = in_dim // num_heads
+ self.num_heads = num_heads
+ self.out_dim = out_dim
+ self.qkv = ops.Linear(in_dim, in_dim * 3, bias=False)
+ self.q_bias = nn.Parameter(torch.empty(in_dim))
+ self.v_bias = nn.Parameter(torch.empty(in_dim))
+ self.register_buffer("zero_k_bias", torch.empty(in_dim))
+ self.proj = ops.Linear(out_dim, out_dim)
+
+ def forward(self, x):
+ B, N, C = x.shape
+ weight, _, offload_stream = comfy.ops.cast_bias_weight(self.qkv, x, offloadable=True)
+ qkv = F.linear(x, weight=weight, bias=comfy.ops.cast_to_input(torch.cat((self.q_bias, self.zero_k_bias, self.v_bias)), x))
+ comfy.ops.uncast_bias_weight(self.qkv, weight, None, offload_stream)
+ q, k, v = qkv.reshape(B, N, 3, self.num_heads, self.head_dim).permute(2, 0, 3, 1, 4).unbind(0)
+
+ # mean over heads then pool down to the latent width (in_dim >> out_dim)
+ x = comfy.ops.scaled_dot_product_attention(q, k, v, is_causal=True)
+ x = F.adaptive_avg_pool1d(torch.mean(x, dim=1), self.out_dim)
+ return self.proj(x)
+
+
+class AttnProjection(nn.Module):
+ def __init__(self, in_dim, out_dim, num_heads, mlp_ratio=2):
+ super().__init__()
+ self.norm1 = ops.LayerNorm(in_dim)
+ self.attn = CausalAttention(in_dim, out_dim, num_heads)
+ self.proj = ops.Linear(in_dim, out_dim)
+ self.norm3 = ops.LayerNorm(in_dim)
+
+ self.norm2 = ops.LayerNorm(out_dim)
+ hidden_dim = int(out_dim * mlp_ratio)
+ self.mlp = GeGluMlp(in_features=out_dim, hidden_features=hidden_dim)
+
+ def forward(self, x):
+ # x: [B, T, in_dim]
+ x = self.proj(self.norm3(x)).add_(self.attn(self.norm1(x)))
+ return x.add_(self.mlp(self.norm2(x)))
+
+
+# BigVGAN decoder
+
+def get_padding(kernel_size, dilation=1):
+ return int((kernel_size * dilation - dilation) / 2)
+
+
+class AMPBlock1(nn.Module):
+ def __init__(self, channels, kernel_size=3, dilation=(1, 3, 5)):
+ super().__init__()
+ self.convs1 = nn.ModuleList(
+ [
+ ops.Conv1d(channels, channels, kernel_size, stride=1, dilation=d, padding=get_padding(kernel_size, d))
+ for d in dilation
+ ]
+ )
+ self.convs2 = nn.ModuleList(
+ [
+ ops.Conv1d(channels, channels, kernel_size, stride=1, dilation=1, padding=get_padding(kernel_size, 1))
+ for _ in range(len(dilation))
+ ]
+ )
+ self.num_layers = len(self.convs1) + len(self.convs2)
+ self.activations = nn.ModuleList(
+ [Activation1d(activation=SnakeBeta(channels)) for _ in range(self.num_layers)]
+ )
+
+ def forward(self, x):
+ acts1, acts2 = self.activations[::2], self.activations[1::2]
+ for c1, c2, a1, a2 in zip(self.convs1, self.convs2, acts1, acts2):
+ xt = a1(x)
+ xt = c1(xt)
+ xt = a2(xt)
+ xt = c2(xt)
+ x = xt.add_(x)
+ return x
+
+
+class BigVGAN(nn.Module):
+ """BigVGAN vocoder (MiniMax H3 32 kHz configuration).
+
+ use_bias_at_final=False, use_tanh_at_final=False (output clamped to [-1, 1]).
+ """
+
+ def __init__(
+ self,
+ num_mels=2048,
+ upsample_initial_channel=1024,
+ upsample_rates=(5, 5, 2, 2, 2, 2, 2),
+ upsample_kernel_sizes=(9, 9, 4, 4, 4, 4, 4),
+ resblock_kernel_sizes=(3, 7, 11),
+ resblock_dilation_sizes=((1, 3, 5), (1, 3, 5), (1, 3, 5)),
+ ):
+ super().__init__()
+ self.num_kernels = len(resblock_kernel_sizes)
+ self.num_upsamples = len(upsample_rates)
+
+ self.conv_pre = ops.Conv1d(num_mels, upsample_initial_channel, 7, 1, padding=3)
+
+ self.ups = nn.ModuleList()
+ for i, (u, k) in enumerate(zip(upsample_rates, upsample_kernel_sizes)):
+ self.ups.append(
+ nn.ModuleList(
+ [
+ ops.ConvTranspose1d(
+ upsample_initial_channel // (2 ** i),
+ upsample_initial_channel // (2 ** (i + 1)),
+ k,
+ u,
+ padding=(k - u) // 2,
+ )
+ ]
+ )
+ )
+
+ self.resblocks = nn.ModuleList()
+ for i in range(len(self.ups)):
+ ch = upsample_initial_channel // (2 ** (i + 1))
+ for k, d in zip(resblock_kernel_sizes, resblock_dilation_sizes):
+ self.resblocks.append(AMPBlock1(ch, k, d))
+
+ self.activation_post = Activation1d(activation=SnakeBeta(ch))
+ self.conv_post = ops.Conv1d(ch, 1, 7, 1, padding=3, bias=False)
+
+ def forward(self, x):
+ x = self.conv_pre(x)
+
+ for i in range(self.num_upsamples):
+ for i_up in range(len(self.ups[i])):
+ x = self.ups[i][i_up](x)
+ xs = None
+ for j in range(self.num_kernels):
+ if xs is None:
+ xs = self.resblocks[i * self.num_kernels + j](x)
+ else:
+ xs += self.resblocks[i * self.num_kernels + j](x)
+ x = xs.div_(self.num_kernels)
+
+ x = self.activation_post(x)
+ return self.conv_post(x).clamp_(-1.0, 1.0)
+
+
+# Top-level VAE
+
+class MiniMaxH3AudioVAE(nn.Module):
+ """MiniMax H3 stereo audio VAE at 32 kHz.
+
+ Latents are [B, 32, 2, T]: 32 channels, 2 stereo channels, T frames at
+ 40 latent frames per second (800 audio samples per latent frame). The
+ stereo channels are processed independently by the mono encoder/decoder.
+ Latents are normalized with the stored per-channel latents_mean/std.
+ """
+
+ def __init__(
+ self,
+ encoder_dim=64,
+ encoder_rates=(2, 4, 4, 5, 5),
+ latent_dim=2048,
+ decoder_dim=1024,
+ vae_latent_channels=32,
+ ):
+ super().__init__()
+ self.sample_rate = 32000
+
+ self.hop_length = 1
+ for r in encoder_rates:
+ self.hop_length *= r
+ self.samples_per_latent = self.hop_length # 800
+ self.latents_per_second = self.sample_rate // self.hop_length # 40
+ self.output_sample_rate = self.sample_rate # read by LTXVAudioVAEDecode
+
+ self.encoder = Encoder(encoder_dim, encoder_rates, latent_dim)
+
+ self.pre_block = AttnProjection(latent_dim, vae_latent_channels, num_heads=8)
+
+ self.mean_proj = ops.Conv1d(vae_latent_channels, vae_latent_channels, 1)
+ # logs_proj exists in the checkpoint but is unused at inference
+ # (encode returns the posterior mean, no sampling).
+ self.logs_proj = ops.Conv1d(vae_latent_channels, vae_latent_channels, 1)
+
+ self.dec_in_proj = ops.Conv1d(vae_latent_channels, latent_dim, 1)
+ self.decoder = BigVGAN(num_mels=latent_dim, upsample_initial_channel=decoder_dim)
+
+ self.register_buffer("latents_mean", torch.empty(vae_latent_channels))
+ self.register_buffer("latents_std", torch.empty(vae_latent_channels))
+
+ def decode(self, z):
+ """Decode normalized latents [B, 32, 2, T] to stereo waveforms [B, 2, L] at 32 kHz."""
+ b, c, s, t = z.shape
+ z = z.permute(0, 2, 1, 3).reshape(b * s, c, t)
+ mean = self.latents_mean.view(1, -1, 1).to(device=z.device, dtype=z.dtype)
+ std = self.latents_std.view(1, -1, 1).to(device=z.device, dtype=z.dtype)
+ z = z * std + mean
+ x = self.dec_in_proj(z)
+ x = self.decoder(x) # [b * s, 1, L], already clamped to [-1, 1]
+ return x.reshape(b, s, -1)
+
+ def encode(self, waveform):
+ """Encode stereo waveforms [B, 2, L] at 32 kHz (in [-1, 1]) to normalized latents [B, 32, 2, T].
+
+ L is right-padded with zeros to a multiple of 800 samples; the returned
+ posterior mean is used directly (no sampling).
+ """
+ b, s, length = waveform.shape
+ right_pad = math.ceil(length / self.hop_length) * self.hop_length - length
+ waveform = F.pad(waveform, (0, right_pad))
+ x = waveform.reshape(b * s, 1, -1)
+ x = self.encoder(x) # [b * s, latent_dim, T]
+ x = self.pre_block(x.transpose(1, 2)).transpose(1, 2) # [b * s, 32, T]
+ z = self.mean_proj(x)
+ mean = self.latents_mean.view(1, -1, 1).to(device=z.device, dtype=z.dtype)
+ std = self.latents_std.view(1, -1, 1).to(device=z.device, dtype=z.dtype)
+ z = (z - mean) / std
+ return z.reshape(b, s, z.shape[1], z.shape[2]).permute(0, 2, 1, 3)
diff --git a/ComfyUI/comfy/ldm/minimax/model.py b/ComfyUI/comfy/ldm/minimax/model.py
new file mode 100644
index 0000000000000000000000000000000000000000..494350d40b2678812af92c0cba75b5c564b02810
--- /dev/null
+++ b/ComfyUI/comfy/ldm/minimax/model.py
@@ -0,0 +1,646 @@
+"""MiniMax H3 audio-video DiT.
+
+Single-stream packed-token transformer denoising video (24ch, patch 1x2x2) and
+stereo audio (32ch, 40 Hz) latents jointly, conditioned on Qwen3-VL layer-50 hidden states.
+The packed sequence is:
+[text | cond rows | audio | video] for t2va/fl2va
+[text | reference blocks | audio | video] for ref2va
+
+Timestep domain: the model receives the *video* sigma from the sampler and
+derives per-token timesteps t = 1 - sigma internally; the audio stream runs on
+its own shifted schedule (sigma_shift video 12.0 / audio 3.0), mapped from the
+video sigma in closed form. The audio velocity is returned scaled by the
+schedule map's derivative d(sigma_a)/d(sigma_v).
+"""
+
+import math
+
+import torch
+import torch.nn as nn
+
+import comfy.ldm.common_dit
+import comfy.model_management
+import comfy.model_prefetch
+import comfy.ops
+import comfy.patcher_extension
+import comfy.quant_ops
+from comfy.ldm.modules.attention import optimized_attention
+
+FRAME_PER_TOKEN = (1, 4, 4, 4, 4)
+FRAME_RESCALE = 5.0 / 3.0
+VISUAL_COND_TIMESTEP = 0.999
+AUDIO_COND_TIMESTEP = 1.0
+
+
+def time_shift_sigma(sigma, from_shift, to_shift):
+ # invert sigma = s*b/(1+(s-1)*b) to the base grid, re-apply the other shift
+ base = sigma / (from_shift + sigma * (1.0 - from_shift))
+ return to_shift * base / (1.0 + (to_shift - 1.0) * base)
+
+
+def time_shift_slope(sigma, from_shift, to_shift):
+ """d(sigma_to)/d(sigma_from) at the same base-grid point.
+
+ Scaling a stream's returned velocity by this slope makes the flat ODE that
+ any sampler integrates on the from-schedule equal to that stream's true ODE
+ on its own schedule.
+ """
+ base = sigma / (from_shift + sigma * (1.0 - from_shift))
+ return (to_shift * (1.0 + (from_shift - 1.0) * base) ** 2) / (from_shift * (1.0 + (to_shift - 1.0) * base) ** 2)
+
+
+def patchify_video(latent, patch_size=(1, 2, 2)):
+ # [B, C, T, H, W] -> [B*t*h*w, C*pt*ph*pw]
+ b, c, t_full, h_full, w_full = latent.shape
+ pt, ph, pw = patch_size
+ t, h, w = t_full // pt, h_full // ph, w_full // pw
+ x = latent.reshape(b, c, t, pt, h, ph, w, pw)
+ x = torch.einsum("nctrhpwq->nthwcrpq", x)
+ return x.reshape(b * t * h * w, c * pt * ph * pw)
+
+
+def unpatchify_video(rows, t, h, w, c=24, patch_size=(1, 2, 2)):
+ pt, ph, pw = patch_size
+ x = rows.reshape(-1, t, h, w, c, pt, ph, pw)
+ x = torch.einsum("nthwcrpq->nctrhpwq", x)
+ return x.reshape(-1, c, t * pt, h * ph, w * pw)
+
+
+def pack_audio(latent):
+ # [B, C=32, ch=2, T] -> [ch*T, 32] channel-major (ch0 t0..T-1, ch1 t0..T-1)
+ b, c, ch, t = latent.shape
+ return latent[0].permute(1, 2, 0).reshape(ch * t, c)
+
+
+def unpack_audio(rows, ch=2):
+ t = rows.shape[0] // ch
+ return rows.reshape(ch, t, rows.shape[-1]).permute(2, 0, 1).unsqueeze(0)
+
+
+def _axis_from_sqrt_area(dim, patch, sqrt_area):
+ # linspace((1 - ratio) / 2, (1 + ratio) / 2, dim // patch, endpoint=False) * 32
+ ratio = dim / sqrt_area
+ n = dim // patch
+ return (torch.arange(n, dtype=torch.float64) * (ratio / n) + (1.0 - ratio) / 2.0) * 32.0
+
+
+def _frame_grid(h, w):
+ # area-normalized (h, w) coordinates of one latent frame's 2x2-patch rows
+ area = math.sqrt(h * w)
+ hh, ww = torch.meshgrid(_axis_from_sqrt_area(h, 2, area), _axis_from_sqrt_area(w, 2, area), indexing="ij")
+ return torch.stack([hh.reshape(-1), ww.reshape(-1)], dim=-1), _axis_from_sqrt_area(w, 2, area)
+
+
+def _video_t_spans(n):
+ return [FRAME_RESCALE * FRAME_PER_TOKEN[k % 5] for k in range(n)]
+
+
+def _video_t_grid(n, origin):
+ # origin + exclusive cumsum
+ spans = torch.tensor(_video_t_spans(n), dtype=torch.float64)
+ return float(origin) + torch.cat([torch.zeros(1, dtype=torch.float64), spans[:-1].cumsum(0)])
+
+
+def _audio_grid(cursor, t, w_low, w_high):
+ # channel-major stereo rows: t advances per latent frame, w pinned to the grid extremes per stereo channel, h stays 0
+ g = torch.zeros(t * 2, 3, dtype=torch.float64)
+ g[:, 0] = (cursor + torch.arange(t, dtype=torch.float64)).repeat(2)
+ g[:t, 2] = w_low
+ g[t:, 2] = w_high
+ return g
+
+
+def _video_grid(vt, frame, cursor):
+ g = torch.empty(vt, frame.shape[0], 3, dtype=torch.float64)
+ g[:, :, 0] = _video_t_grid(vt, cursor)[:, None]
+ g[:, :, 1:] = frame[None]
+ return g.reshape(-1, 3)
+
+
+class TimeEmbedder(nn.Module):
+ def __init__(self, freq_dim, hidden, out, dtype=None, device=None, operations=None):
+ super().__init__()
+ self.freq_dim = freq_dim
+ self.proj_in = operations.Linear(freq_dim, hidden, bias=True, dtype=dtype, device=device)
+ self.proj_out = operations.Linear(hidden, out, bias=True, dtype=dtype, device=device)
+
+ def forward(self, t):
+ # t: [M] in [0, 1]; fp32 throughout, cos before sin
+ half = self.freq_dim // 2
+ freqs = torch.exp(-math.log(10000.0) * torch.arange(half, dtype=torch.float32, device=t.device) / half)
+ args = t.to(torch.float32)[:, None] * freqs[None]
+ emb = torch.cat([torch.cos(args), torch.sin(args)], dim=-1)
+ return self.proj_out(nn.functional.silu(self.proj_in(emb)))
+
+
+def rope_rotation_table(angles, dtype):
+ """[S, rot_dim] pair angles -> [1, S, 1, rot_dim/2, 2, 2] rotation matrices."""
+ half = angles.shape[-1] // 2
+ ang = angles[:, :half] # duplicated halves: [:, :half] == [:, half:]
+ c, s = torch.cos(ang), torch.sin(ang)
+ table = torch.stack([c, -s, s, c], dim=-1).reshape(1, angles.shape[0], 1, half, 2, 2)
+ return table.to(dtype)
+
+
+class Attention(nn.Module):
+ def __init__(self, hidden, heads, head_dim, eps, dtype=None, device=None, operations=None):
+ super().__init__()
+ self.heads = heads
+ self.head_dim = head_dim
+ inner = heads * head_dim
+ self.qkv_proj = operations.Linear(hidden, inner * 3, bias=False, dtype=dtype, device=device)
+ self.q_norm = operations.RMSNorm(head_dim, eps=eps, dtype=dtype, device=device)
+ self.k_norm = operations.RMSNorm(head_dim, eps=eps, dtype=dtype, device=device)
+ self.out_proj = operations.Linear(inner, hidden, bias=False, dtype=dtype, device=device)
+
+ def forward(self, x, rope_freqs=None, transformer_options={}):
+ s = x.shape[0]
+ q, k, v = self.qkv_proj(x).split(self.heads * self.head_dim, dim=-1)
+ v = v.view(s, self.heads, self.head_dim)
+ if rope_freqs is not None:
+ # fused per-head RMSNorm + partial split-half rope, in place on the qkv buffer
+ q = q.view(1, s, self.heads, self.head_dim)
+ k = k.view(1, s, self.heads, self.head_dim)
+ qw = comfy.model_management.cast_to(self.q_norm.weight, device=x.device)
+ kw = comfy.model_management.cast_to(self.k_norm.weight, device=x.device)
+ rot = rope_freqs.shape[-3] * 2
+ if comfy.model_management.in_training:
+ q, k = comfy.quant_ops.ck.rms_rope_split_half(
+ q, k, rope_freqs, qw, kw, epsilon=self.q_norm.eps, rot_dim=rot)
+ else:
+ comfy.quant_ops.ck.rms_rope_split_half_(
+ q, k, rope_freqs, qw, kw, epsilon=self.q_norm.eps, rot_dim=rot)
+ q = q[0]
+ k = k[0]
+ else:
+ q = self.q_norm(q.view(s, self.heads, self.head_dim))
+ k = self.k_norm(k.view(s, self.heads, self.head_dim))
+ q = q.transpose(0, 1).unsqueeze(0)
+ k = k.transpose(0, 1).unsqueeze(0)
+ v = v.transpose(0, 1).unsqueeze(0)
+ out = optimized_attention(q, k, v, self.heads, mask=None, skip_reshape=True, transformer_options=transformer_options)
+ return self.out_proj(out.squeeze(0))
+
+
+class MLP(nn.Module):
+ def __init__(self, hidden, ffn, dtype=None, device=None, operations=None):
+ super().__init__()
+ self.fc1 = operations.Linear(hidden, ffn * 2, bias=False, dtype=dtype, device=device)
+ self.fc2 = operations.Linear(ffn, hidden, bias=False, dtype=dtype, device=device)
+
+ def forward(self, x):
+ return comfy.ops.linear_input_act(self.fc2, self.fc1(x), "swiglu")
+
+
+class AdalnProj(nn.Module):
+ def __init__(self, t_dim, hidden, expand, modalities, apply_silu=True,
+ dtype=None, device=None, operations=None):
+ super().__init__()
+ self.expand = expand
+ self.modalities = modalities
+ self.hidden = hidden
+ self.apply_silu = apply_silu
+ self.linear = operations.Linear(t_dim, expand * hidden * modalities, bias=True, dtype=dtype, device=device)
+
+ def forward(self, t_emb):
+ # [M, t_dim] -> expand tensors of [M*modalities, hidden]
+ x = self.linear(nn.functional.silu(t_emb) if self.apply_silu else t_emb)
+ x = x.view(x.shape[0] * self.modalities, self.expand * self.hidden)
+ return x.chunk(self.expand, dim=-1)
+
+
+def _mod_scale_shift(h, shift, scale, segments):
+ # segments: [(start, stop, mod_row)] covering h contiguously.
+ for a, b, row in segments:
+ h[a:b].mul_(1.0 + scale[row].to(h.dtype)).add_(shift[row].to(h.dtype))
+ return h
+
+
+def _mod_gate(x, gate, other, segments):
+ # other is the fresh attn/mlp output: accumulate the gated residual into the stream in place, one fused kernel per segment
+ for a, b, row in segments:
+ x[a:b].addcmul_(other[a:b], gate[row].to(x.dtype))
+ return x
+
+
+class RefinerBlock(nn.Module):
+ def __init__(self, hidden, heads, head_dim, ffn, eps, qk_eps, dtype=None, device=None, operations=None):
+ super().__init__()
+ self.norm1 = operations.RMSNorm(hidden, eps=eps, dtype=dtype, device=device)
+ self.norm2 = operations.RMSNorm(hidden, eps=eps, dtype=dtype, device=device)
+ self.attn = Attention(hidden, heads, head_dim, qk_eps, dtype=dtype, device=device, operations=operations)
+ self.mlp = MLP(hidden, ffn, dtype=dtype, device=device, operations=operations)
+
+ def forward(self, x, transformer_options={}):
+ # attn/mlp outputs are fresh: accumulate residuals in place
+ x = self.attn(self.norm1(x), transformer_options=transformer_options).add_(x)
+ return self.mlp(self.norm2(x)).add_(x)
+
+
+class TokenRefiner(nn.Module):
+ def __init__(self, num_layers, hidden, heads, head_dim, ffn, eps, qk_eps, final_eps,
+ dtype=None, device=None, operations=None):
+ super().__init__()
+ self.blocks = nn.ModuleList([
+ RefinerBlock(hidden, heads, head_dim, ffn, eps, qk_eps, dtype=dtype, device=device, operations=operations)
+ for _ in range(num_layers)])
+ self.final_norm = operations.RMSNorm(hidden, eps=final_eps, dtype=dtype, device=device)
+
+ def forward(self, x, transformer_options={}):
+ for block in self.blocks:
+ x = block(x, transformer_options=transformer_options)
+ return self.final_norm(x)
+
+
+class DiTBlock(nn.Module):
+ def __init__(self, hidden, heads, head_dim, ffn, t_dim, eps, qk_eps,
+ apply_silu=True, adaln_dtype=None, dtype=None, device=None, operations=None):
+ super().__init__()
+ self.norm1 = operations.RMSNorm(hidden, eps=eps, dtype=dtype, device=device)
+ self.norm2 = operations.RMSNorm(hidden, eps=eps, dtype=dtype, device=device)
+ self.attn = Attention(hidden, heads, head_dim, qk_eps, dtype=dtype, device=device, operations=operations)
+ self.mlp = MLP(hidden, ffn, dtype=dtype, device=device, operations=operations)
+ self.adaln_proj = AdalnProj(t_dim, hidden, 6, 3, apply_silu=apply_silu,
+ dtype=adaln_dtype if adaln_dtype is not None else dtype,
+ device=device, operations=operations)
+
+ def forward(self, x, t_emb, mod_segments, rope_freqs, transformer_options={}):
+ shift_msa, scale_msa, gate_msa, shift_mlp, scale_mlp, gate_mlp = self.adaln_proj(t_emb)
+ h = _mod_scale_shift(self.norm1(x), shift_msa, scale_msa, mod_segments)
+ x = _mod_gate(x, gate_msa, self.attn(h, rope_freqs=rope_freqs, transformer_options=transformer_options), mod_segments)
+ h = _mod_scale_shift(self.norm2(x), shift_mlp, scale_mlp, mod_segments)
+ return _mod_gate(x, gate_mlp, self.mlp(h), mod_segments)
+
+
+class FinalLayer(nn.Module):
+ def __init__(self, hidden, t_dim, video_dim, audio_dim, eps, apply_silu=True, adaln_dtype=None,
+ dtype=None, device=None, operations=None):
+ super().__init__()
+ self.norm = operations.RMSNorm(hidden, eps=eps, dtype=dtype, device=device)
+ self.adaln_proj = AdalnProj(t_dim, hidden, 2, 1, apply_silu=apply_silu,
+ dtype=adaln_dtype if adaln_dtype is not None else dtype,
+ device=device, operations=operations)
+ # output heads are the checkpoint's fp32 island; norm/adaln are stored at model dtype
+ self.video_out = operations.Linear(hidden, video_dim, bias=True, dtype=torch.float32, device=device)
+ self.audio_out = operations.Linear(hidden, audio_dim, bias=True, dtype=torch.float32, device=device)
+
+ def forward(self, x, t_emb, video_seg, audio_seg):
+ # video_seg / audio_seg: (start, stop, timestep_row) of the target streams
+ shift, scale = self.adaln_proj(t_emb)
+ va, vb, vrow = video_seg
+ aa, ab, arow = audio_seg
+ hv = (self.norm(x[va:vb]) * (1.0 + scale[vrow]) + shift[vrow]).to(torch.float32)
+ ha = (self.norm(x[aa:ab]) * (1.0 + scale[arow]) + shift[arow]).to(torch.float32)
+ return self.video_out(hv), self.audio_out(ha)
+
+
+class PackedLayout:
+ """Static packed-sequence structure for one shape/conditioning signature."""
+
+ def __init__(self, text_len, latent_t, latent_h, latent_w, audio_t, keyframes=None, refs=None, frame_count=None):
+ frame, w_grid = _frame_grid(latent_h, latent_w)
+ frame_rows = frame.shape[0]
+
+ segments = [("text", text_len)] # (kind, n_rows)
+ g = torch.zeros(text_len, 3, dtype=torch.float64)
+ g[:, 0] = torch.arange(text_len, dtype=torch.float64)
+ pos = [g] # per segment: [n, 3] float64 (t, h, w)
+
+ img_pos, img_update = [], []
+ audio_pos, audio_update = [], []
+ cursor = text_len
+ row = text_len
+
+ if keyframes:
+ # fl2va: keyframe cond rows right after text, sharing the target spatial grid
+ for kf in keyframes:
+ pixel_index = kf["resolved_frame_index"]
+ if pixel_index == 0:
+ cond_t = float(text_len)
+ elif frame_count is not None and pixel_index == frame_count - 1:
+ cond_t = float(text_len) + sum(_video_t_spans(latent_t)) - FRAME_RESCALE
+ else:
+ raise ValueError("only first/last keyframe anchors are supported")
+ g = torch.empty(frame_rows, 3, dtype=torch.float64)
+ g[:, 0] = cond_t
+ g[:, 1:] = frame
+ segments.append(("cond", frame_rows))
+ pos.append(g)
+ img_pos.append(torch.arange(row, row + frame_rows))
+ img_update.append(torch.zeros(frame_rows, dtype=torch.bool))
+ row += frame_rows
+
+ target_audio_w = (float(w_grid[0]), float(w_grid[-1]))
+ if refs:
+ cursor = float(text_len)
+ for blk in refs:
+ kind = blk["kind"]
+ if kind == "image":
+ r_frame, _ = _frame_grid(blk["latent_h"], blk["latent_w"])
+ n = r_frame.shape[0]
+ g = torch.empty(n, 3, dtype=torch.float64)
+ g[:, 0] = cursor
+ g[:, 1:] = r_frame
+ segments.append(("ref_img", n))
+ pos.append(g)
+ img_pos.append(torch.arange(row, row + n))
+ img_update.append(torch.zeros(n, dtype=torch.bool))
+ row += n
+ cursor += 1.0
+ elif kind == "audio":
+ rt = blk["ref_audio_t"]
+ if rt > 0:
+ segments.append(("ref_audio", rt * 2))
+ pos.append(_audio_grid(cursor, rt, *target_audio_w))
+ audio_pos.append(torch.arange(row, row + rt * 2))
+ audio_update.append(torch.zeros(rt * 2, dtype=torch.bool))
+ row += rt * 2
+ cursor += float(rt)
+ elif kind in ("video", "video_audio"):
+ # the block's audio rows pack immediately before its video
+ # rows, both sharing the cursor origin
+ rt = blk["ref_audio_t"]
+ vt = blk["latent_t"]
+ r_frame, r_w_grid = _frame_grid(blk["latent_h"], blk["latent_w"])
+ if rt > 0:
+ segments.append(("ref_audio", rt * 2))
+ pos.append(_audio_grid(cursor, rt, float(r_w_grid[0]), float(r_w_grid[-1])))
+ audio_pos.append(torch.arange(row, row + rt * 2))
+ audio_update.append(torch.zeros(rt * 2, dtype=torch.bool))
+ row += rt * 2
+ n = vt * r_frame.shape[0]
+ segments.append(("ref_img", n))
+ pos.append(_video_grid(vt, r_frame, cursor))
+ img_pos.append(torch.arange(row, row + n))
+ img_update.append(torch.zeros(n, dtype=torch.bool))
+ row += n
+ cursor += max(float(rt), sum(_video_t_spans(vt)))
+
+ # target audio then target video, always the last two segments
+ segments.append(("audio", audio_t * 2))
+ pos.append(_audio_grid(cursor, audio_t, *target_audio_w))
+ audio_pos.append(torch.arange(row, row + audio_t * 2))
+ audio_update.append(torch.ones(audio_t * 2, dtype=torch.bool))
+ row += audio_t * 2
+
+ n_video = latent_t * frame_rows
+ segments.append(("video", n_video))
+ pos.append(_video_grid(latent_t, frame, cursor))
+ img_pos.append(torch.arange(row, row + n_video))
+ img_update.append(torch.ones(n_video, dtype=torch.bool))
+ row += n_video
+
+ self.seq_len = row
+ self.position_ids = torch.cat(pos) # [S, 3] float64
+ self.img_pos = torch.cat(img_pos)
+ self.img_update = torch.cat(img_update)
+ self.audio_pos = torch.cat(audio_pos)
+ self.audio_update = torch.cat(audio_update)
+ self.signature = (text_len, latent_t, latent_h, latent_w, audio_t)
+ # contiguous segment table (start, stop, kind)
+ # kinds: text / cond / ref_img / ref_audio / audio / video
+ # the packed sequence is uniform per segment in (modality tag, timestep class),
+ # except the text span (tag runs resolved at forward time from the presentation tags)
+ seg_abs = []
+ off = 0
+ for kind, n in segments:
+ seg_abs.append((off, off + n, kind))
+ off += n
+ self.segments = seg_abs
+
+
+class MiniMaxH3Model(nn.Module):
+ def __init__(self, hidden_size=5376, num_layers=50, token_refiner_num_layers=2,
+ num_attention_heads=56, attention_head_dim=128, ffn_hidden_size=14336,
+ latents_dim=24, audio_latents_dim=32, patch_size=(1, 2, 2), text_dim=5120,
+ timestep_input_dim=256, time_embed_hidden_size=5376, time_embed_dim=2688,
+ rope_inv_freq_len=16, norm_eps=1e-5, qk_norm_eps=1e-5, final_norm_eps=1e-5,
+ sigma_shift_video=12.0, sigma_shift_audio=3.0,
+ adaln_curve_grid=None,
+ image_model=None, dtype=None, device=None, operations=None, **kwargs):
+ super().__init__()
+ self.dtype = dtype
+ self.hidden_size = hidden_size
+ self.patch_size = tuple(patch_size)
+ self.latents_dim = latents_dim
+ self.audio_latents_dim = audio_latents_dim
+ self.sigma_shift_video = sigma_shift_video
+ self.sigma_shift_audio = sigma_shift_audio
+ self.use_adaln_curves = adaln_curve_grid is not None
+ # curve-form checkpoints replace the time embedder and full-width adaln weights with a small shared basis of the time-embedding curve
+ curve = {"apply_silu": not self.use_adaln_curves,
+ "adaln_dtype": torch.float32 if self.use_adaln_curves else dtype}
+ video_patch_dim = latents_dim * self.patch_size[0] * self.patch_size[1] * self.patch_size[2]
+
+ self.video_patch_proj = operations.Linear(video_patch_dim, hidden_size, bias=True, dtype=torch.float32, device=device)
+ self.audio_patch_proj = operations.Linear(audio_latents_dim, hidden_size, bias=True, dtype=torch.float32, device=device)
+ self.condition_proj = operations.Linear(text_dim, hidden_size, bias=True, dtype=dtype, device=device)
+ if self.use_adaln_curves:
+ self.register_buffer("adaln_t_table", torch.empty(adaln_curve_grid, time_embed_dim, dtype=torch.float32))
+ else:
+ self.time_embedder = TimeEmbedder(timestep_input_dim, time_embed_hidden_size, time_embed_dim,
+ dtype=torch.float32, device=device, operations=operations)
+ self.rope = nn.Module()
+ self.rope.register_buffer("inv_freq", torch.empty(rope_inv_freq_len, dtype=torch.float32))
+ self.token_refiner = TokenRefiner(token_refiner_num_layers, hidden_size, num_attention_heads,
+ attention_head_dim, ffn_hidden_size, norm_eps, qk_norm_eps,
+ final_norm_eps, dtype=dtype, device=device, operations=operations)
+ self.blocks = nn.ModuleList([
+ DiTBlock(hidden_size, num_attention_heads, attention_head_dim, ffn_hidden_size,
+ time_embed_dim, norm_eps, qk_norm_eps, **curve, dtype=dtype, device=device, operations=operations)
+ for _ in range(num_layers)])
+ self.final_layer = FinalLayer(hidden_size, time_embed_dim, video_patch_dim, audio_latents_dim,
+ final_norm_eps, **curve, dtype=dtype, device=device, operations=operations)
+
+ def preprocess_text_embeds(self, text_states):
+ """[B, L, text_dim] Qwen states -> [B, L, hidden] refined text embeds."""
+ if text_states.shape[-1] == self.hidden_size:
+ return text_states
+ return self.token_refiner(self.condition_proj(text_states[0])).unsqueeze(0)
+
+ def rope_freqs(self, position_ids, device):
+ # [S, 3] float64 -> [S, 96] fp32
+ pos = position_ids.to(torch.float32).to(device)
+ inv = comfy.model_management.cast_to(self.rope.inv_freq, device=device)
+ per_axis = pos.unsqueeze(-1) * inv.view(1, 1, -1) # [S, 3, 16]
+ t_f, h_f, w_f = per_axis.unbind(dim=1)
+ half = torch.cat((t_f, h_f, w_f), dim=-1) # [S, 48]
+ return torch.cat((half, half), dim=-1) # [S, 96]
+
+ def _cond_video_rows(self, payload, device):
+ """Concatenated visual condition rows (normalized latents -> patchified), with condition noise augmentation."""
+ rows = []
+ aug = payload.get("visual_cond_noise_aug", VISUAL_COND_TIMESTEP)
+ seed = int(payload.get("seed", 0))
+ # every condition intentionally restarts the same RNG stream
+ for z in payload.get("cond_video_latents", []):
+ r = patchify_video(z.to(torch.float32), self.patch_size)
+ if aug < 1.0:
+ gen = torch.Generator("cpu").manual_seed(seed)
+ noise = torch.randn(r.shape, generator=gen, dtype=torch.float32)
+ r = aug * r + (1.0 - aug) * noise.to(r.device)
+ rows.append(r.to(device))
+ return torch.cat(rows, dim=0) if rows else None
+
+ def _cond_audio_rows(self, payload, device):
+ rows = []
+ aug = payload.get("audio_cond_noise_aug", AUDIO_COND_TIMESTEP)
+ seed = int(payload.get("seed", 0)) + 1
+ for z in payload.get("cond_audio_latents", []):
+ r = pack_audio(z.to(torch.float32))
+ if aug < 1.0:
+ gen = torch.Generator("cpu").manual_seed(seed)
+ noise = torch.randn(r.shape, generator=gen, dtype=torch.float32)
+ r = aug * r + (1.0 - aug) * noise.to(r.device)
+ rows.append(r.to(device))
+ return torch.cat(rows, dim=0) if rows else None
+
+ def forward(self, x, timestep, context, transformer_options={}, minimax_payload=None, **kwargs):
+ return comfy.patcher_extension.WrapperExecutor.new_class_executor(
+ self._forward,
+ self,
+ comfy.patcher_extension.get_all_wrappers(comfy.patcher_extension.WrappersMP.DIFFUSION_MODEL, transformer_options)
+ ).execute(x, timestep, context, transformer_options, minimax_payload=minimax_payload, **kwargs)
+
+ def _forward(self, x, timestep, context, transformer_options={}, minimax_payload=None, **kwargs):
+ video_x, audio_x = x[0], x[1]
+ orig_t, orig_h, orig_w = video_x.shape[2], video_x.shape[3], video_x.shape[4]
+ video_x = comfy.ldm.common_dit.pad_to_patch_size(video_x, self.patch_size)
+ if video_x.shape[0] != 1:
+ raise ValueError("MiniMax H3 supports batch size 1")
+ payload = minimax_payload or {}
+ device = video_x.device
+ dtype = context.dtype # compute dtype
+
+ latent_t, lat_h, lat_w = video_x.shape[2], video_x.shape[3], video_x.shape[4]
+ audio_t = audio_x.shape[-1]
+ text_len = context.shape[1]
+ # extra_conds prebuilds the layout once per sampling run
+ layout = payload.get("layout")
+ if layout is None or layout.signature != (text_len, latent_t, lat_h, lat_w, audio_t):
+ layout = PackedLayout(text_len, latent_t, lat_h, lat_w, audio_t,
+ keyframes=payload.get("keyframes"),
+ refs=payload.get("refs"),
+ frame_count=payload.get("frame_count"))
+
+ # model_base passes model_sampling.timestep(sigma) = sigma * 1000
+ shift_v = float(transformer_options.get("minimax_h3_sigma_shift_video", self.sigma_shift_video))
+ shift_a = float(transformer_options.get("minimax_h3_sigma_shift_audio", self.sigma_shift_audio))
+ sigma_v = (timestep.flatten()[0] / 1000.0).float().clamp(min=1e-6)
+ t_v = float(1.0 - sigma_v)
+ t_a = float(1.0 - time_shift_sigma(sigma_v, shift_v, shift_a))
+
+ # distinct timesteps are known analytically: text/pad follow video, cond rows pin near 1
+ vis_aug = float(payload.get("visual_cond_noise_aug", VISUAL_COND_TIMESTEP))
+ aud_aug = float(payload.get("audio_cond_noise_aug", AUDIO_COND_TIMESTEP))
+ has_vis_cond = any(k in ("cond", "ref_img") for _, _, k in layout.segments)
+ has_aud_cond = any(k == "ref_audio" for _, _, k in layout.segments)
+ seg_t = {"text": t_v, "video": t_v, "audio": t_a,
+ "cond": max(t_v, vis_aug), "ref_img": max(t_v, vis_aug),
+ "ref_audio": max(t_a, aud_aug)}
+ unique_t = sorted({t_v, t_a} | ({seg_t["cond"]} if has_vis_cond else set())
+ | ({seg_t["ref_audio"]} if has_aud_cond else set()))
+ t_row = {t: i for i, t in enumerate(unique_t)}
+ seg_tag = {"text": 1, "video": 0, "audio": 2, "cond": 0, "ref_img": 0, "ref_audio": 2}
+
+ text_tags = payload.get("text_token_tags")
+ mod_segments = []
+ for a, b, kind in layout.segments:
+ row_base = t_row[seg_t[kind]] * 3
+ if kind == "text" and text_tags is not None:
+ # the presentation text span mixes tags (vision pads carry the video modality) split into tag runs
+ tags = text_tags.view(-1).tolist()
+ run_start = 0
+ for i in range(1, b - a + 1):
+ if i == b - a or tags[i] != tags[run_start]:
+ mod_segments.append((a + run_start, a + i, row_base + int(tags[run_start])))
+ run_start = i
+ else:
+ mod_segments.append((a, b, row_base + seg_tag[kind]))
+
+ # embed
+ img_update = layout.img_update.to(device)
+ audio_update = layout.audio_update.to(device)
+ video_rows = patchify_video(video_x.to(torch.float32), self.patch_size)
+ audio_rows = pack_audio(audio_x.to(torch.float32))
+ cond_video_rows = self._cond_video_rows(payload, device)
+ cond_audio_rows = self._cond_audio_rows(payload, device)
+
+ all_video_rows = video_rows
+ if cond_video_rows is not None:
+ all_video_rows = torch.empty(img_update.shape[0], video_rows.shape[1], dtype=torch.float32, device=device)
+ all_video_rows[~img_update] = cond_video_rows
+ all_video_rows[img_update] = video_rows
+ all_audio_rows = audio_rows
+ if cond_audio_rows is not None:
+ all_audio_rows = torch.empty(audio_update.shape[0], audio_rows.shape[1], dtype=torch.float32, device=device)
+ all_audio_rows[~audio_update] = cond_audio_rows
+ all_audio_rows[audio_update] = audio_rows
+
+ video_embed = self.video_patch_proj(all_video_rows).to(dtype)
+ audio_embed = self.audio_patch_proj(all_audio_rows).to(dtype)
+ text_states = context[0]
+ if text_states.shape[-1] != self.hidden_size:
+ text_states = self.token_refiner(self.condition_proj(text_states),
+ transformer_options=transformer_options)
+
+ # segments are contiguous: assemble by slices, embed rows follow segment order
+ h = torch.empty(layout.seq_len, self.hidden_size, dtype=dtype, device=device)
+ voff = aoff = 0
+ for a, b, kind in layout.segments:
+ n = b - a
+ if kind == "text":
+ h[a:b] = text_states
+ elif kind in ("cond", "ref_img", "video"):
+ h[a:b] = video_embed[voff:voff + n]
+ voff += n
+ else: # ref_audio / audio
+ h[a:b] = audio_embed[aoff:aoff + n]
+ aoff += n
+
+ t_vals = torch.tensor(unique_t, dtype=torch.float32, device=device)
+ if self.use_adaln_curves:
+ # adaln projections consume interpolated coordinates of the time-embedding curve
+ table = comfy.model_management.cast_to(self.adaln_t_table, device=device)
+ pos = t_vals.clamp(0.0, 1.0) * (table.shape[0] - 1) # t in [0,1] -> fractional grid index, out-of-range t clamps to the curve ends
+ i0 = pos.floor().long().clamp(max=table.shape[0] - 2) # lower grid row, max-clamp keeps t=1.0 on the last interval instead of reading past the table
+ t_emb = torch.lerp(table[i0], table[i0 + 1], (pos - i0).unsqueeze(1)) # blend the two rows by the fractional part
+ else:
+ t_emb = self.time_embedder(t_vals).to(dtype)
+
+ # rotation table computed once per forward, consumed by the kitchen split-half rope
+ rope_freqs = rope_rotation_table(self.rope_freqs(layout.position_ids, device), dtype)
+
+ # blocks
+ patches_replace = transformer_options.get("patches_replace", {})
+ blocks_replace = patches_replace.get("dit", {})
+ prefetch_queue = comfy.model_prefetch.make_prefetch_queue(list(self.blocks), device, transformer_options)
+ for i, block in enumerate(self.blocks):
+ comfy.model_prefetch.prefetch_queue_pop(prefetch_queue, device, block)
+ if ("double_block", i) in blocks_replace:
+ def block_wrap(args):
+ return {"img": block(args["img"], args["t_emb"], args["mod_segments"], args["rope_freqs"],
+ transformer_options=args["transformer_options"])}
+ h = blocks_replace[("double_block", i)](
+ {"img": h, "t_emb": t_emb, "mod_segments": mod_segments, "rope_freqs": rope_freqs,
+ "transformer_options": transformer_options},
+ {"original_block": block_wrap})["img"]
+ else:
+ h = block(h, t_emb, mod_segments, rope_freqs, transformer_options=transformer_options)
+ if prefetch_queue is not None:
+ comfy.model_prefetch.prefetch_queue_pop(prefetch_queue, device, None)
+
+ # target streams are single contiguous segments (audio then video, last two)
+ video_seg = next((a, b, t_row[seg_t["video"]]) for a, b, k in layout.segments if k == "video")
+ audio_seg = next((a, b, t_row[seg_t["audio"]]) for a, b, k in layout.segments if k == "audio")
+ v, a = self.final_layer(h, t_emb, video_seg, audio_seg)
+
+ video_out = unpatchify_video(v, latent_t, lat_h // 2, lat_w // 2, self.latents_dim, self.patch_size)
+ video_out = video_out[:, :, :orig_t, :orig_h, :orig_w]
+ audio_out = unpack_audio(a)
+
+ # The sampler integrates the flat ODE dX/dsigma_v = (X - denoised)/sigma_v.
+ # Scaling the audio velocity by d(sigma_a)/d(sigma_v) makes that ODE equal
+ # to the audio stream's true ODE on its own shifted schedule.
+ slope_a = time_shift_slope(sigma_v, shift_v, shift_a).to(audio_out.dtype)
+ return [-video_out.to(video_x.dtype), (-slope_a) * audio_out.to(audio_x.dtype)]
diff --git a/ComfyUI/comfy/ldm/minimax/vae.py b/ComfyUI/comfy/ldm/minimax/vae.py
new file mode 100644
index 0000000000000000000000000000000000000000..b03bf0c9a23bee10ff1bddd3eb9707cf3a2d598c
--- /dev/null
+++ b/ComfyUI/comfy/ldm/minimax/vae.py
@@ -0,0 +1,694 @@
+# MiniMax H3 video VAE: 3D causal CNN encoder + ViT3D decoder.
+
+import math
+
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+
+import comfy.ops
+import comfy.quant_ops
+import comfy.rmsnorm
+from comfy.ldm.modules.attention import optimized_attention
+
+ops = comfy.ops.disable_weight_init
+
+IMAGENET_MEAN = (0.485, 0.456, 0.406)
+IMAGENET_STD = (0.229, 0.224, 0.225)
+
+LATENTS_MEAN = [
+ 0.858090341091156, -0.9606591463088989, 1.0661640167236328, -0.5090325474739075,
+ -0.2727581858634949, -1.3675414323806763, -0.2553254961967468, -0.26907554268836975,
+ -0.5376840829849243, -0.0464097298681736, 0.6657370328903198, 0.19690127670764923,
+ -0.5460608005523682, -0.4035342037677765, -0.23683024942874908, 0.25928452610969543,
+ -0.30133944749832153, 0.211341992020607, -1.1206848621368408, 0.3581933379173279,
+ -0.04225143790245056, 0.2604829967021942, 0.22864092886447906, 0.7056031823158264,
+]
+
+LATENTS_STD = [
+ 1.2223774194717407, 1.2767263650894165, 1.68317747116088865, 1.7549455165863037,
+ 1.5636216402053833, 2.194143533706665, 0.96531379222869875, 1.05698859691619875,
+ 0.841948926448822, 0.7729952931404114, 1.8955937623977661, 0.946841835975647,
+ 0.7996809482574463, 0.44988900423049925, 0.7197399735450745, 0.69362932443618775,
+ 2.961095094680786, 2.7694199085235595, 3.0496184825897215, 2.1088054180145265,
+ 3.276226282119751, 3.1627357006073, 2.28168129920959475, 2.6127843856811525,
+]
+
+
+# 3D causal CNN encoder
+
+class CausalConv3d(ops.Conv3d):
+ # Reflect spatial padding, causal (zeros, front-only) temporal padding.
+ def __init__(self, in_channels, out_channels, kernel_size, stride=1, padding=0):
+ super().__init__(in_channels, out_channels, kernel_size=kernel_size, stride=stride)
+ self.causal_padding = (padding,) * 3 if isinstance(padding, int) else tuple(padding)
+
+ def forward(self, x):
+ if sum(self.causal_padding) == 0:
+ return super().forward(x)
+
+ x = F.pad(x, (self.causal_padding[2], self.causal_padding[2], self.causal_padding[1], self.causal_padding[1], 0, 0), mode="reflect")
+ if x.shape[2] == 1:
+ # single frame: the causal front padding is all zeros truncate the temporal taps instead of convolving zero frames
+ return super().forward(x, autopad="causal_zero")
+ x = F.pad(x, (0, 0, 0, 0, self.causal_padding[0] * 2, 0), mode="constant")
+ return super().forward(x)
+
+
+class TemporalIsolatedGroupNorm(ops.GroupNorm):
+ # GroupNorm with statistics computed per frame (time merged into batch).
+ def forward(self, x):
+ if x.dim() == 5:
+ b, c, t, h, w = x.shape
+ x = x.permute(0, 2, 1, 3, 4).contiguous().view(b * t, c, 1, h, w)
+ x = super().forward(x)
+ return x.view(b, t, c, h, w).permute(0, 2, 1, 3, 4).contiguous()
+ return super().forward(x)
+
+
+def group_norm_3d(num_channels):
+ return TemporalIsolatedGroupNorm(num_groups=32, num_channels=num_channels, eps=1e-6, affine=True)
+
+
+class Downsample3D(nn.Module):
+ def __init__(self, in_channels, out_channels, time_stride=1, space_stride=2):
+ super().__init__()
+ self.space_stride = space_stride
+ self.conv = CausalConv3d(
+ in_channels,
+ out_channels,
+ kernel_size=3,
+ padding=(1, 0, 0),
+ stride=(time_stride, space_stride, space_stride),
+ )
+
+ def forward(self, x):
+ if self.space_stride == 2:
+ x = F.pad(x, (0, 1, 0, 1, 0, 0), mode="reflect")
+ return self.conv(x)
+
+
+class ResnetBlock3D(nn.Module):
+ def __init__(self, in_channels, out_channels=None):
+ super().__init__()
+ self.in_channels = in_channels
+ out_channels = in_channels if out_channels is None else out_channels
+ self.out_channels = out_channels
+
+ self.norm1 = group_norm_3d(in_channels)
+ self.norm2 = group_norm_3d(out_channels)
+ self.conv1 = CausalConv3d(in_channels, out_channels, kernel_size=3, padding=1)
+ self.conv2 = CausalConv3d(out_channels, out_channels, kernel_size=3, padding=1)
+ if in_channels != out_channels:
+ self.nin_shortcut = CausalConv3d(in_channels, out_channels, kernel_size=1)
+
+ def forward(self, x):
+ h = self.conv1(F.silu(self.norm1(x), inplace=True))
+ h = self.conv2(F.silu(self.norm2(h), inplace=True))
+ if self.in_channels != self.out_channels:
+ x = self.nin_shortcut(x)
+ return h.add_(x)
+
+
+class EncoderFCN3D(nn.Module):
+ def __init__(self, ch, ch_mult, space_down, time_down, num_res_blocks, in_channels, z_channels, double_z=True):
+ super().__init__()
+ self.num_levels = len(ch_mult)
+ if isinstance(num_res_blocks, int):
+ num_res_blocks = [num_res_blocks] * self.num_levels
+ self.num_res_blocks = num_res_blocks
+
+ block_mid = [ch * ch_mult[i] for i in range(self.num_levels)]
+ block_in = [block_mid[0]] + block_mid[:-1]
+ block_out = block_mid
+
+ self.conv_in = CausalConv3d(in_channels, block_in[0], kernel_size=3, padding=1)
+
+ self.down = nn.ModuleList()
+ for i_level in range(self.num_levels):
+ down = nn.Module()
+ down.block = nn.ModuleList()
+ for i in range(self.num_res_blocks[i_level]):
+ down.block.append(
+ ResnetBlock3D(
+ in_channels=block_in[i_level] if i == 0 else block_mid[i_level],
+ out_channels=block_mid[i_level],
+ )
+ )
+ if space_down[i_level] * time_down[i_level] > 1:
+ down.downsample = Downsample3D(
+ block_mid[i_level],
+ block_out[i_level],
+ time_stride=time_down[i_level],
+ space_stride=space_down[i_level],
+ )
+ self.down.append(down)
+
+ self.norm_out = group_norm_3d(block_out[-1])
+ self.conv_out = CausalConv3d(
+ block_out[-1],
+ 2 * z_channels if double_z else z_channels,
+ kernel_size=3,
+ padding=1,
+ )
+
+ def forward(self, x):
+ h = self.conv_in(x)
+ for i_level in range(self.num_levels):
+ for i_block in range(self.num_res_blocks[i_level]):
+ h = self.down[i_level].block[i_block](h)
+ if hasattr(self.down[i_level], "downsample"):
+ h = self.down[i_level].downsample(h)
+ h = F.silu(self.norm_out(h))
+ return self.conv_out(h)
+
+
+# ViT3D decoder
+
+def create_token_ids(patch_dims, device, dtype):
+ coords_list = []
+ for dim_size in patch_dims:
+ coords = torch.arange(0.5, dim_size, dtype=dtype, device=device)
+ coords = coords / dim_size
+ coords = 2.0 * coords - 1.0
+ coords_list.append(coords)
+ coords = torch.stack(torch.meshgrid(*coords_list, indexing="ij"), dim=-1)
+ return coords.flatten(0, len(patch_dims) - 1).unsqueeze(0)
+
+
+class RotaryEmbeddingND(nn.Module):
+ def __init__(self, dim, rotary_base=100.0, n_dim=3):
+ super().__init__()
+ self.n_dim = n_dim
+ self.angle_scale = 2.0 * math.pi
+ inv_freq = 1 / rotary_base ** torch.arange(0, 1, 2 * n_dim / dim, dtype=torch.float32)
+ self.register_buffer("inv_freq", inv_freq, persistent=False)
+
+ def forward(self, img_ids):
+ # [B, S, n_dim] -> [B, S, 1, pairs, 2, 2] rotation table for the kitchen split-half rope
+ angles = (
+ self.angle_scale
+ * img_ids[:, :, :, None].float()
+ * self.inv_freq.to(img_ids.device)[None, None, None, :]
+ )
+ angles = angles.flatten(2, 3)
+ c, s = torch.cos(angles), torch.sin(angles)
+ table = torch.stack([c, -s, s, c], dim=-1).reshape(*angles.shape[:2], 1, angles.shape[-1], 2, 2)
+ return table.to(img_ids.dtype)
+
+
+class FeedForward(nn.Module):
+ # Gated SiLU FFN.
+ def __init__(self, dim, mult=4, bias=True):
+ super().__init__()
+ inner_dim = dim * mult
+ self.w1 = ops.Linear(dim, inner_dim * 2, bias=bias)
+ self.w2 = ops.Linear(inner_dim, dim, bias=bias)
+
+ def forward(self, x):
+ gate, x = self.w1(x).chunk(2, dim=-1)
+ return self.w2(F.silu(gate).mul_(x))
+
+
+class Attention(nn.Module):
+ def __init__(self, heads, dim_head, bias=True, eps=1e-5):
+ super().__init__()
+ self.dim_head = dim_head
+ self.heads = heads
+ inner_dim = dim_head * heads
+ self.norm_q = ops.RMSNorm(dim_head, eps=eps, elementwise_affine=False)
+ self.norm_k = ops.RMSNorm(dim_head, eps=eps, elementwise_affine=False)
+ self.to_qkv = ops.Linear(inner_dim, inner_dim * 3, bias=bias)
+ self.to_out = ops.Linear(inner_dim, inner_dim, bias=bias)
+
+ def forward(self, x, rotary_pos_emb=None):
+ batch_size, seq_len, _ = x.shape
+
+ qkv = self.to_qkv(x)
+ qkv = qkv.view(batch_size, seq_len, -1, 3 * self.dim_head)
+ query, key, value = torch.chunk(qkv, 3, dim=-1)
+
+ query = comfy.rmsnorm.rms_norm(query, self.norm_q.weight, self.norm_q.eps)
+ key = comfy.rmsnorm.rms_norm(key, self.norm_k.weight, self.norm_k.eps)
+
+ if rotary_pos_emb is not None:
+ rot = rotary_pos_emb.shape[-3] * 2
+ query[..., :rot], key[..., :rot] = comfy.quant_ops.ck.apply_rope_split_half(
+ query[..., :rot], key[..., :rot], rotary_pos_emb)
+
+ out = optimized_attention(query.transpose(1, 2), key.transpose(1, 2), value.transpose(1, 2),
+ self.heads, skip_reshape=True).nan_to_num_(0.0)
+ return self.to_out(out)
+
+
+class TransformerBlock(nn.Module):
+ def __init__(self, heads, dim_head, bias=True, eps=1e-5):
+ super().__init__()
+ dim = heads * dim_head
+ self.norm1 = ops.RMSNorm(dim, elementwise_affine=True, eps=eps)
+ self.attn = Attention(heads=heads, dim_head=dim_head, bias=bias, eps=eps)
+ self.scale1 = nn.Parameter(torch.empty(dim))
+ self.norm2 = ops.RMSNorm(dim, elementwise_affine=True, eps=eps)
+ self.ff = FeedForward(dim=dim, bias=bias)
+ self.scale2 = nn.Parameter(torch.empty(dim))
+
+ def forward(self, x, rotary_pos_emb=None):
+ x = x.addcmul_(self.attn(comfy.rmsnorm.rms_norm(x, self.norm1.weight, self.norm1.eps), rotary_pos_emb), comfy.ops.cast_to_input(self.scale1, x))
+ return x.addcmul_(self.ff(comfy.rmsnorm.rms_norm(x, self.norm2.weight, self.norm2.eps)), comfy.ops.cast_to_input(self.scale2, x))
+
+
+class ViT3DDecoder(nn.Module):
+ def __init__(self, patch_size=16, patch_size_t=4, in_channels=24, out_channels=3, num_layers=36, heads=32, dim_head=64, rope_theta=100.0,
+ rope_dim_ratio=0.75, bias=True, eps=1e-5, num_register_tokens=4):
+ super().__init__()
+ dim = heads * dim_head
+ self.patch_size = patch_size
+ self.patch_size_t = patch_size_t
+ self.out_channels = out_channels
+ self.num_register_tokens = num_register_tokens
+
+ self.pos_embed = RotaryEmbeddingND(int(dim_head * rope_dim_ratio), rope_theta, n_dim=3)
+ self.x_embedder = ops.Linear(in_channels, dim)
+ self.register_tokens = nn.Parameter(torch.empty(1, num_register_tokens, dim))
+ # unused at inference; kept so the checkpoint loads without leftover keys
+ self.register_buffer("mask_token", torch.empty(1, 1, dim))
+
+ self.transformer_blocks = nn.ModuleList(
+ [TransformerBlock(heads=heads, dim_head=dim_head, bias=bias, eps=eps)
+ for _ in range(num_layers)]
+ )
+
+ self.norm_out = ops.LayerNorm(dim, elementwise_affine=True, eps=eps)
+ self.proj_out = ops.Linear(dim, out_channels * patch_size_t * patch_size * patch_size)
+
+ def forward(self, x):
+ B, C, latent_T, latent_H, latent_W = x.shape
+
+ h = self.x_embedder(x.flatten(2).transpose(1, 2)) # [B, T*H*W, C]
+
+ num_patches = h.shape[1]
+ num_suffix = 1 + self.num_register_tokens
+
+ h = torch.cat([h, comfy.ops.cast_to_input(self.register_tokens, h).expand(B, -1, -1), torch.zeros_like(h[:, 0:1, :])], dim=1)
+
+ img_ids = create_token_ids((latent_T, latent_H, latent_W), x.device, x.dtype).expand(B, -1, -1)
+ suffix_ids = torch.zeros((B, num_suffix, 3), device=x.device, dtype=img_ids.dtype)
+ img_ids = torch.cat([img_ids, suffix_ids], dim=1)
+
+ rotary_pos_emb = self.pos_embed(img_ids)
+
+ for block in self.transformer_blocks:
+ h = block(h, rotary_pos_emb)
+
+ output = self.proj_out(self.norm_out(h))
+
+ output = output[:, :num_patches, :]
+
+ output = output.view(
+ B, latent_T, latent_H, latent_W,
+ self.out_channels, self.patch_size_t, self.patch_size, self.patch_size,
+ )
+ output = output.permute(0, 4, 1, 5, 2, 6, 3, 7).contiguous()
+ output = output.reshape(
+ B, self.out_channels,
+ latent_T * self.patch_size_t,
+ latent_H * self.patch_size,
+ latent_W * self.patch_size,
+ )
+ return output
+
+
+# Full VAE
+
+class MiniMaxH3VideoVAE(nn.Module):
+ def __init__(
+ self,
+ in_channels=3,
+ out_ch=3,
+ ch=128,
+ embed_dim=24,
+ z_channels=24,
+ ch_mult=(1, 2, 2, 4, 4, 8),
+ num_res_blocks=2,
+ space_down=(2, 2, 2, 2, 1, 1),
+ time_down=(1, 2, 2, 1, 1, 1),
+ clip_length=17,
+ token_drop=3,
+ tile_size=256,
+ tile_overlap_min=64,
+ tiling=True,
+ ):
+ super().__init__()
+ self.vae_ratio = int(math.prod(space_down))
+ self.vae_ratio_t = int(math.prod(time_down))
+
+ # temporal chunking parameters
+ self.clip_length = clip_length
+ self.token_drop = token_drop
+ self.frame_pre_padding = (-clip_length) % self.vae_ratio_t
+ self.tokens_chunk_size = math.ceil(clip_length / self.vae_ratio_t)
+ self.token_overlap = (-token_drop) % self.tokens_chunk_size
+ self.frame_overlap = max(self.token_overlap * self.vae_ratio_t - self.frame_pre_padding, 0)
+
+ # spatial tiling parameters
+ self.tiling = tiling
+ self.tile_size = tile_size
+ self.tile_overlap_min = tile_overlap_min
+
+ self.encoder = EncoderFCN3D(
+ ch=ch,
+ ch_mult=list(ch_mult),
+ space_down=list(space_down),
+ time_down=list(time_down),
+ num_res_blocks=num_res_blocks,
+ in_channels=in_channels,
+ z_channels=z_channels,
+ double_z=True,
+ )
+ self.quant_conv = ops.Conv3d(z_channels * 2, 2 * embed_dim, 1)
+ self.post_quant_conv = ops.Conv3d(embed_dim, z_channels, 1)
+ self.decoder = ViT3DDecoder(
+ patch_size=self.vae_ratio,
+ patch_size_t=self.vae_ratio_t,
+ in_channels=z_channels,
+ out_channels=out_ch,
+ )
+
+ self.register_buffer("latents_mean", torch.tensor(LATENTS_MEAN))
+ self.register_buffer("latents_std", torch.tensor(LATENTS_STD))
+ self.register_buffer("pixel_mean", torch.tensor(IMAGENET_MEAN).view(1, 3, 1, 1, 1), persistent=False)
+ self.register_buffer("pixel_std", torch.tensor(IMAGENET_STD).view(1, 3, 1, 1, 1), persistent=False)
+
+ # single-shot forward
+
+ def _encode_moments(self, x):
+ return self.quant_conv(self.encoder(x))
+
+ def _decode_pixels(self, z):
+ return self.decoder(self.post_quant_conv(z))
+
+ def _adaptive_encode(self, x):
+ if self.tiling:
+ return self.tiled_encode(x)
+ return self._encode_moments(x)
+
+ def _adaptive_decode(self, z):
+ if self.tiling:
+ return self.tiled_decode(z)
+ return self._decode_pixels(z)
+
+ # spatial tiling
+
+ def split_tiles(self, input_len):
+ tile_size = self.tile_size
+ if tile_size >= input_len:
+ return [0], [input_len], []
+
+ N = math.ceil(input_len / tile_size)
+ while True:
+ overlaps = [self.tile_overlap_min] * (N - 1)
+ remaining = tile_size * N - sum(overlaps) - input_len
+ if remaining < 0:
+ N += 1
+ else:
+ break
+
+ remaining_units = remaining // self.vae_ratio
+ for i in range(remaining_units):
+ overlaps[i % (N - 1)] += self.vae_ratio
+
+ tile_start_idx = [0]
+ for i in range(N - 1):
+ tile_start_idx.append(tile_start_idx[-1] + tile_size - overlaps[i])
+
+ return tile_start_idx, [tile_size] * N, overlaps
+
+ def blend(self, a, b, blend_extent, dim):
+ blend_extent = min(a.shape[dim], b.shape[dim], blend_extent)
+
+ positions = torch.arange(blend_extent, device=b.device, dtype=b.dtype)
+ weight_a = 1 - positions / blend_extent
+ weight_b = positions / blend_extent
+
+ shape = [1] * a.ndim
+ shape[dim] = blend_extent
+ weight_a = weight_a.view(shape)
+ weight_b = weight_b.view(shape)
+
+ slice_a = [slice(None)] * a.ndim
+ slice_a[dim] = slice(-blend_extent, None)
+ slice_b = [slice(None)] * b.ndim
+ slice_b[dim] = slice(0, blend_extent)
+
+ blended = a[tuple(slice_a)] * weight_a + b[tuple(slice_b)] * weight_b
+
+ if blend_extent < b.shape[dim]:
+ slice_b_rest = [slice(None)] * b.ndim
+ slice_b_rest[dim] = slice(blend_extent, None)
+ return torch.cat([blended, b[tuple(slice_b_rest)]], dim=dim)
+ return blended
+
+ def tiled_encode(self, x):
+ height, width = x.shape[-2], x.shape[-1]
+ y_idx, y_len, y_overlap = self.split_tiles(height)
+ x_idx, x_len, x_overlap = self.split_tiles(width)
+
+ rows = []
+ for i_pos, i_len in zip(y_idx, y_len):
+ row = []
+ for j_pos, j_len in zip(x_idx, x_len):
+ tile = x[..., i_pos:i_pos + i_len, j_pos:j_pos + j_len]
+ row.append(self._encode_moments(tile))
+ rows.append(row)
+
+ latent_y_overlap = [o // self.vae_ratio for o in y_overlap]
+ latent_x_overlap = [o // self.vae_ratio for o in x_overlap]
+
+ result_rows = []
+ for i, row in enumerate(rows):
+ result_row = []
+ for j, tile in enumerate(row):
+ if i > 0:
+ tile = self.blend(rows[i - 1][j], tile, latent_y_overlap[i - 1], dim=-2)
+ if j > 0:
+ tile = self.blend(row[j - 1], tile, latent_x_overlap[j - 1], dim=-1)
+ if i < len(rows) - 1:
+ tile = tile[..., :-latent_y_overlap[i], :]
+ if j < len(row) - 1:
+ tile = tile[..., :, :-latent_x_overlap[j]]
+ result_row.append(tile)
+ result_rows.append(torch.cat(result_row, dim=-1))
+ return torch.cat(result_rows, dim=-2)
+
+ def tiled_decode(self, z):
+ height, width = z.shape[-2] * self.vae_ratio, z.shape[-1] * self.vae_ratio
+ y_idx, y_len, y_overlap = self.split_tiles(height)
+ x_idx, x_len, x_overlap = self.split_tiles(width)
+
+ # Blended tiles are written straight into a pre-allocated canvas.
+ canvas = None
+ row_tails = []
+ out_y = 0
+ for i, (i_pos, i_len) in enumerate(zip(y_idx, y_len)):
+ zi, zl = i_pos // self.vae_ratio, i_len // self.vae_ratio
+ new_tails = []
+ left_tail = None
+ out_x = 0
+ for j, (j_pos, j_len) in enumerate(zip(x_idx, x_len)):
+ zj, zw = j_pos // self.vae_ratio, j_len // self.vae_ratio
+ tile = self._decode_pixels(z[..., zi:zi + zl, zj:zj + zw])
+ if i < len(y_idx) - 1:
+ new_tails.append(tile[..., -y_overlap[i]:, :].clone())
+ next_left_tail = tile[..., :, -x_overlap[j]:].clone() if j < len(x_idx) - 1 else None
+ if i > 0:
+ tile = self.blend(row_tails[j], tile, y_overlap[i - 1], dim=-2)
+ if j > 0:
+ tile = self.blend(left_tail, tile, x_overlap[j - 1], dim=-1)
+ left_tail = next_left_tail
+ if i < len(y_idx) - 1:
+ tile = tile[..., :-y_overlap[i], :]
+ if j < len(x_idx) - 1:
+ tile = tile[..., :, :-x_overlap[j]]
+ if canvas is None:
+ canvas = torch.empty(*tile.shape[:-2], height, width, dtype=tile.dtype, device=tile.device)
+ canvas[..., out_y:out_y + tile.shape[-2], out_x:out_x + tile.shape[-1]].copy_(tile)
+ out_x += tile.shape[-1]
+ row_tails = new_tails
+ out_y += tile.shape[-2]
+ return canvas
+
+ # temporal chunking
+
+ def encode_temporal(self, x):
+ if x.shape[2] % self.clip_length != 0:
+ pad_size = (-x.shape[2]) % self.clip_length
+ pad_frames = x[:, :, -1:].repeat(1, 1, pad_size, 1, 1)
+ x = torch.cat([x, pad_frames], dim=2)
+
+ num_chunks = x.shape[2] // self.clip_length
+
+ z_list = []
+ for i in range(num_chunks):
+ clip_x = x[:, :, i * self.clip_length:(i + 1) * self.clip_length, :, :]
+ z_list.append(self._adaptive_encode(clip_x))
+
+ z = torch.cat(z_list, dim=2)
+ if self.token_drop > 0:
+ z = z[:, :, :-self.token_drop]
+ return z
+
+ def _decode_temporal_pad_frames(self, z_len, pad_tokens):
+ if pad_tokens <= 0:
+ return 0
+ intra_tail = self.clip_length % self.vae_ratio_t
+ if intra_tail == 0:
+ return pad_tokens * self.vae_ratio_t
+
+ z_len_before_pad = z_len - pad_tokens
+ return sum(
+ (intra_tail if (z_len_before_pad + k) % self.tokens_chunk_size == 0
+ else self.vae_ratio_t)
+ for k in range(pad_tokens)
+ )
+
+ def _decode_temporal_frame_plan(self, z_len, num_chunks, pad_tokens):
+ chunk_dec = self.tokens_chunk_size * self.vae_ratio_t
+ split_count = int(self.token_drop > 0) + 1
+ total_frames = 0
+ final_overlap_frames = 0
+
+ for i in range(num_chunks):
+ t_start_idx = i * self.tokens_chunk_size
+ t_end_idx = t_start_idx + self.tokens_chunk_size + self.token_overlap
+ clip_token_len = max(0, min(t_end_idx, z_len) - min(t_start_idx, z_len))
+ clip_frame_len = clip_token_len * self.vae_ratio_t
+
+ for j in range(split_count):
+ f_start_idx = j * chunk_dec
+ f_end_idx = min(f_start_idx + chunk_dec, clip_frame_len)
+ chunk_frames = max(0, f_end_idx - f_start_idx - self.frame_pre_padding)
+ if j == 0:
+ total_frames += chunk_frames
+ else:
+ final_overlap_frames = chunk_frames
+
+ total_frames += final_overlap_frames
+ return total_frames - self._decode_temporal_pad_frames(z_len, pad_tokens)
+
+ def decode_temporal(self, z):
+ chunk_dec = self.tokens_chunk_size * self.vae_ratio_t
+ split_count = int(self.token_drop > 0) + 1
+
+ pseudo_total_tokens = z.shape[2] + self.token_drop
+
+ pad_tokens = 0
+ remainder = pseudo_total_tokens % self.tokens_chunk_size
+ if remainder != 0:
+ pad_tokens = self.tokens_chunk_size - remainder
+ pseudo_total_tokens += pad_tokens
+
+ num_chunks = pseudo_total_tokens // self.tokens_chunk_size - int(self.token_drop > 0)
+ if num_chunks < 1:
+ # too few tokens for one chunk (e.g. T_lat == 2): pad one extra chunk
+ pad_tokens += self.tokens_chunk_size
+ num_chunks += 1
+
+ if pad_tokens > 0:
+ pad_z = z[:, :, -1:, :, :].repeat(1, 1, pad_tokens, 1, 1)
+ z = torch.cat([z, pad_z], dim=2)
+
+ output_frames = self._decode_temporal_frame_plan(z.shape[2], num_chunks, pad_tokens)
+
+ dec = None
+ dec_overlap = None
+ write_pos = 0
+
+ def write_part(part):
+ nonlocal dec, write_pos
+ part_frames = part.shape[2]
+ if part_frames <= 0:
+ return
+ if dec is None:
+ out_shape = list(part.shape)
+ out_shape[2] = output_frames
+ dec = torch.empty(out_shape, dtype=part.dtype, device=part.device)
+ copy_frames = min(part_frames, max(0, dec.shape[2] - write_pos))
+ if copy_frames > 0:
+ dec[:, :, write_pos:write_pos + copy_frames, :, :].copy_(
+ part[:, :, :copy_frames, :, :]
+ )
+ write_pos += copy_frames
+
+ for i in range(num_chunks):
+ t_start_idx = i * self.tokens_chunk_size
+ t_end_idx = t_start_idx + self.tokens_chunk_size + self.token_overlap
+ clip_z = z[:, :, t_start_idx:t_end_idx, :, :]
+
+ clip_dec = self._adaptive_decode(clip_z)
+
+ for j in range(split_count):
+ f_start_idx = j * chunk_dec
+ f_end_idx = min(f_start_idx + chunk_dec, clip_dec.shape[2])
+ clip_dec_chunk = clip_dec[:, :, f_start_idx:f_end_idx, :, :]
+ clip_dec_chunk = clip_dec_chunk[:, :, self.frame_pre_padding:, :, :]
+
+ if j == 0:
+ if dec_overlap is not None:
+ clip_dec_chunk = self.blend(
+ dec_overlap, clip_dec_chunk, self.frame_overlap, dim=-3
+ )
+ dec_overlap = None
+ write_part(clip_dec_chunk)
+ else:
+ dec_overlap = clip_dec_chunk.contiguous()
+
+ if i == num_chunks - 1 and dec_overlap is not None:
+ write_part(dec_overlap)
+ dec_overlap = None
+
+ del clip_dec, clip_z
+
+ return dec
+
+
+ def encode(self, x):
+ # x: [B, 3, T, H, W] in [-1, 1] -> normalized latents [B, 24, T_lat, H/16, W/16]
+ if x.ndim == 4:
+ x = x.unsqueeze(2)
+
+ x = x.add(1.0).mul_(0.5).sub_(self.pixel_mean.to(x)).div_(self.pixel_std.to(x))
+
+ if x.shape[2] == 1:
+ moments = self._adaptive_encode(x)
+ moments = moments[:, :, -1:, :, :]
+ else:
+ moments = self.encode_temporal(x)
+
+ mean = torch.chunk(moments.float(), 2, dim=1)[0]
+
+ latents_mean = self.latents_mean.view(1, -1, 1, 1, 1).to(mean)
+ latents_std = self.latents_std.view(1, -1, 1, 1, 1).to(mean)
+ return (mean - latents_mean) / latents_std
+
+ def encode_tiled(self, x, **kwargs):
+ # tiling is always on internally with the reference's semantic tile sizes, ignore tiling fallbacks
+ return self.encode(x)
+
+ def decode_tiled(self, z, **kwargs):
+ return self.decode(z)
+
+ def decode(self, z):
+ # z: [B, 24, T_lat, H_lat, W_lat] normalized latents -> pixels [B, 3, T, H, W] in [-1, 1]
+ latents_mean = self.latents_mean.view(1, -1, 1, 1, 1).to(z)
+ latents_std = self.latents_std.view(1, -1, 1, 1, 1).to(z)
+ z = z * latents_std + latents_mean
+
+ if z.shape[2] == 1:
+ dec = self._adaptive_decode(z)
+ dec = dec[:, :, -1:, :, :]
+ else:
+ dec = self.decode_temporal(z)
+
+ dec = dec.float()
+ dec.mul_(self.pixel_std.to(dec)).add_(self.pixel_mean.to(dec)).clamp_(0.0, 1.0).mul_(2.0).sub_(1.0)
+ return dec
diff --git a/ComfyUI/comfy/ldm/mmaudio/vae/__init__.py b/ComfyUI/comfy/ldm/mmaudio/vae/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/ComfyUI/comfy/ldm/mmaudio/vae/__pycache__/__init__.cpython-312.pyc b/ComfyUI/comfy/ldm/mmaudio/vae/__pycache__/__init__.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..5a39b436d9a59cd51d241b28b688984c4d0241cf
Binary files /dev/null and b/ComfyUI/comfy/ldm/mmaudio/vae/__pycache__/__init__.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/mmaudio/vae/__pycache__/activations.cpython-312.pyc b/ComfyUI/comfy/ldm/mmaudio/vae/__pycache__/activations.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..12e90f69e3e5bd16a0b9363f8695d839d3a29a03
Binary files /dev/null and b/ComfyUI/comfy/ldm/mmaudio/vae/__pycache__/activations.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/mmaudio/vae/__pycache__/alias_free_torch.cpython-312.pyc b/ComfyUI/comfy/ldm/mmaudio/vae/__pycache__/alias_free_torch.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..0c10a3c9fae28385af4e1b122231e52895fa58ca
Binary files /dev/null and b/ComfyUI/comfy/ldm/mmaudio/vae/__pycache__/alias_free_torch.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/mmaudio/vae/__pycache__/autoencoder.cpython-312.pyc b/ComfyUI/comfy/ldm/mmaudio/vae/__pycache__/autoencoder.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..d324ac2db2ec5abfd851dd7c6aba9d99e71f79a0
Binary files /dev/null and b/ComfyUI/comfy/ldm/mmaudio/vae/__pycache__/autoencoder.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/mmaudio/vae/__pycache__/bigvgan.cpython-312.pyc b/ComfyUI/comfy/ldm/mmaudio/vae/__pycache__/bigvgan.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..1ac50f9f34b6ac2fff3ac44d82699ccb75519a1c
Binary files /dev/null and b/ComfyUI/comfy/ldm/mmaudio/vae/__pycache__/bigvgan.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/mmaudio/vae/__pycache__/distributions.cpython-312.pyc b/ComfyUI/comfy/ldm/mmaudio/vae/__pycache__/distributions.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..90931803c1b9c5e04d3a414fcb79fc0ab02c4c30
Binary files /dev/null and b/ComfyUI/comfy/ldm/mmaudio/vae/__pycache__/distributions.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/mmaudio/vae/__pycache__/vae.cpython-312.pyc b/ComfyUI/comfy/ldm/mmaudio/vae/__pycache__/vae.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..4c987bca3d7ed5921e6a92f681782f012e28befc
Binary files /dev/null and b/ComfyUI/comfy/ldm/mmaudio/vae/__pycache__/vae.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/mmaudio/vae/__pycache__/vae_modules.cpython-312.pyc b/ComfyUI/comfy/ldm/mmaudio/vae/__pycache__/vae_modules.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..969fa62bdc69f6b72c019bc640bef5a3ae433344
Binary files /dev/null and b/ComfyUI/comfy/ldm/mmaudio/vae/__pycache__/vae_modules.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/mmaudio/vae/activations.py b/ComfyUI/comfy/ldm/mmaudio/vae/activations.py
new file mode 100644
index 0000000000000000000000000000000000000000..db9192e3e4c4d2ca318178bb93a959beb9bbff42
--- /dev/null
+++ b/ComfyUI/comfy/ldm/mmaudio/vae/activations.py
@@ -0,0 +1,120 @@
+# Implementation adapted from https://github.com/EdwardDixon/snake under the MIT license.
+# LICENSE is in incl_licenses directory.
+
+import torch
+from torch import nn, sin, pow
+from torch.nn import Parameter
+import comfy.model_management
+
+class Snake(nn.Module):
+ '''
+ Implementation of a sine-based periodic activation function
+ Shape:
+ - Input: (B, C, T)
+ - Output: (B, C, T), same shape as the input
+ Parameters:
+ - alpha - trainable parameter
+ References:
+ - This activation function is from this paper by Liu Ziyin, Tilman Hartwig, Masahito Ueda:
+ https://arxiv.org/abs/2006.08195
+ Examples:
+ >>> a1 = snake(256)
+ >>> x = torch.randn(256)
+ >>> x = a1(x)
+ '''
+ def __init__(self, in_features, alpha=1.0, alpha_trainable=True, alpha_logscale=False):
+ '''
+ Initialization.
+ INPUT:
+ - in_features: shape of the input
+ - alpha: trainable parameter
+ alpha is initialized to 1 by default, higher values = higher-frequency.
+ alpha will be trained along with the rest of your model.
+ '''
+ super(Snake, self).__init__()
+ self.in_features = in_features
+
+ # initialize alpha
+ self.alpha_logscale = alpha_logscale
+ if self.alpha_logscale:
+ self.alpha = Parameter(torch.empty(in_features))
+ else:
+ self.alpha = Parameter(torch.empty(in_features))
+
+ self.alpha.requires_grad = alpha_trainable
+
+ self.no_div_by_zero = 0.000000001
+
+ def forward(self, x):
+ '''
+ Forward pass of the function.
+ Applies the function to the input elementwise.
+ Snake ∶= x + 1/a * sin^2 (xa)
+ '''
+ alpha = comfy.model_management.cast_to(self.alpha, dtype=x.dtype, device=x.device).unsqueeze(0).unsqueeze(-1) # line up with x to [B, C, T]
+ if self.alpha_logscale:
+ alpha = torch.exp(alpha)
+ x = x + (1.0 / (alpha + self.no_div_by_zero)) * pow(sin(x * alpha), 2)
+
+ return x
+
+
+class SnakeBeta(nn.Module):
+ '''
+ A modified Snake function which uses separate parameters for the magnitude of the periodic components
+ Shape:
+ - Input: (B, C, T)
+ - Output: (B, C, T), same shape as the input
+ Parameters:
+ - alpha - trainable parameter that controls frequency
+ - beta - trainable parameter that controls magnitude
+ References:
+ - This activation function is a modified version based on this paper by Liu Ziyin, Tilman Hartwig, Masahito Ueda:
+ https://arxiv.org/abs/2006.08195
+ Examples:
+ >>> a1 = snakebeta(256)
+ >>> x = torch.randn(256)
+ >>> x = a1(x)
+ '''
+ def __init__(self, in_features, alpha=1.0, alpha_trainable=True, alpha_logscale=False):
+ '''
+ Initialization.
+ INPUT:
+ - in_features: shape of the input
+ - alpha - trainable parameter that controls frequency
+ - beta - trainable parameter that controls magnitude
+ alpha is initialized to 1 by default, higher values = higher-frequency.
+ beta is initialized to 1 by default, higher values = higher-magnitude.
+ alpha will be trained along with the rest of your model.
+ '''
+ super(SnakeBeta, self).__init__()
+ self.in_features = in_features
+
+ # initialize alpha
+ self.alpha_logscale = alpha_logscale
+ if self.alpha_logscale:
+ self.alpha = Parameter(torch.empty(in_features))
+ self.beta = Parameter(torch.empty(in_features))
+ else:
+ self.alpha = Parameter(torch.empty(in_features))
+ self.beta = Parameter(torch.empty(in_features))
+
+ self.alpha.requires_grad = alpha_trainable
+ self.beta.requires_grad = alpha_trainable
+
+ self.no_div_by_zero = 0.000000001
+
+ def forward(self, x):
+ '''
+ Forward pass of the function.
+ Applies the function to the input elementwise.
+ SnakeBeta ∶= x + 1/b * sin^2 (xa)
+ '''
+ alpha = comfy.model_management.cast_to(self.alpha, dtype=x.dtype, device=x.device).unsqueeze(0).unsqueeze(-1) # line up with x to [B, C, T]
+ beta = comfy.model_management.cast_to(self.beta, dtype=x.dtype, device=x.device).unsqueeze(0).unsqueeze(-1)
+ if self.alpha_logscale:
+ alpha = torch.exp(alpha)
+ beta = torch.exp(beta)
+ x = x + (1.0 / (beta + self.no_div_by_zero)) * pow(sin(x * alpha), 2)
+
+ return x
diff --git a/ComfyUI/comfy/ldm/mmaudio/vae/alias_free_torch.py b/ComfyUI/comfy/ldm/mmaudio/vae/alias_free_torch.py
new file mode 100644
index 0000000000000000000000000000000000000000..35c70b89712017a616add51fc22537093378657d
--- /dev/null
+++ b/ComfyUI/comfy/ldm/mmaudio/vae/alias_free_torch.py
@@ -0,0 +1,157 @@
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+import math
+import comfy.model_management
+
+if 'sinc' in dir(torch):
+ sinc = torch.sinc
+else:
+ # This code is adopted from adefossez's julius.core.sinc under the MIT License
+ # https://adefossez.github.io/julius/julius/core.html
+ # LICENSE is in incl_licenses directory.
+ def sinc(x: torch.Tensor):
+ """
+ Implementation of sinc, i.e. sin(pi * x) / (pi * x)
+ __Warning__: Different to julius.sinc, the input is multiplied by `pi`!
+ """
+ return torch.where(x == 0,
+ torch.tensor(1., device=x.device, dtype=x.dtype),
+ torch.sin(math.pi * x) / math.pi / x)
+
+
+# This code is adopted from adefossez's julius.lowpass.LowPassFilters under the MIT License
+# https://adefossez.github.io/julius/julius/lowpass.html
+# LICENSE is in incl_licenses directory.
+def kaiser_sinc_filter1d(cutoff, half_width, kernel_size): # return filter [1,1,kernel_size]
+ even = (kernel_size % 2 == 0)
+ half_size = kernel_size // 2
+
+ #For kaiser window
+ delta_f = 4 * half_width
+ A = 2.285 * (half_size - 1) * math.pi * delta_f + 7.95
+ if A > 50.:
+ beta = 0.1102 * (A - 8.7)
+ elif A >= 21.:
+ beta = 0.5842 * (A - 21)**0.4 + 0.07886 * (A - 21.)
+ else:
+ beta = 0.
+ window = torch.kaiser_window(kernel_size, beta=beta, periodic=False)
+
+ # ratio = 0.5/cutoff -> 2 * cutoff = 1 / ratio
+ if even:
+ time = (torch.arange(-half_size, half_size) + 0.5)
+ else:
+ time = torch.arange(kernel_size) - half_size
+ if cutoff == 0:
+ filter_ = torch.zeros_like(time)
+ else:
+ filter_ = 2 * cutoff * window * sinc(2 * cutoff * time)
+ # Normalize filter to have sum = 1, otherwise we will have a small leakage
+ # of the constant component in the input signal.
+ filter_ /= filter_.sum()
+ filter = filter_.view(1, 1, kernel_size)
+
+ return filter
+
+
+class LowPassFilter1d(nn.Module):
+ def __init__(self,
+ cutoff=0.5,
+ half_width=0.6,
+ stride: int = 1,
+ padding: bool = True,
+ padding_mode: str = 'replicate',
+ kernel_size: int = 12):
+ # kernel_size should be even number for stylegan3 setup,
+ # in this implementation, odd number is also possible.
+ super().__init__()
+ if cutoff < -0.:
+ raise ValueError("Minimum cutoff must be larger than zero.")
+ if cutoff > 0.5:
+ raise ValueError("A cutoff above 0.5 does not make sense.")
+ self.kernel_size = kernel_size
+ self.even = (kernel_size % 2 == 0)
+ self.pad_left = kernel_size // 2 - int(self.even)
+ self.pad_right = kernel_size // 2
+ self.stride = stride
+ self.padding = padding
+ self.padding_mode = padding_mode
+ filter = kaiser_sinc_filter1d(cutoff, half_width, kernel_size)
+ self.register_buffer("filter", filter)
+
+ #input [B, C, T]
+ def forward(self, x):
+ _, C, _ = x.shape
+
+ if self.padding:
+ x = F.pad(x, (self.pad_left, self.pad_right),
+ mode=self.padding_mode)
+ out = F.conv1d(x, comfy.model_management.cast_to(self.filter.expand(C, -1, -1), dtype=x.dtype, device=x.device),
+ stride=self.stride, groups=C)
+
+ return out
+
+
+class UpSample1d(nn.Module):
+ def __init__(self, ratio=2, kernel_size=None):
+ super().__init__()
+ self.ratio = ratio
+ self.kernel_size = int(6 * ratio // 2) * 2 if kernel_size is None else kernel_size
+ self.stride = ratio
+ self.pad = self.kernel_size // ratio - 1
+ self.pad_left = self.pad * self.stride + (self.kernel_size - self.stride) // 2
+ self.pad_right = self.pad * self.stride + (self.kernel_size - self.stride + 1) // 2
+ filter = kaiser_sinc_filter1d(cutoff=0.5 / ratio,
+ half_width=0.6 / ratio,
+ kernel_size=self.kernel_size)
+ self.register_buffer("filter", filter)
+
+ # x: [B, C, T]
+ def forward(self, x):
+ _, C, _ = x.shape
+
+ x = F.pad(x, (self.pad, self.pad), mode='replicate')
+ x = self.ratio * F.conv_transpose1d(
+ x, comfy.model_management.cast_to(self.filter.expand(C, -1, -1), dtype=x.dtype, device=x.device), stride=self.stride, groups=C)
+ x = x[..., self.pad_left:-self.pad_right]
+
+ return x
+
+
+class DownSample1d(nn.Module):
+ def __init__(self, ratio=2, kernel_size=None):
+ super().__init__()
+ self.ratio = ratio
+ self.kernel_size = int(6 * ratio // 2) * 2 if kernel_size is None else kernel_size
+ self.lowpass = LowPassFilter1d(cutoff=0.5 / ratio,
+ half_width=0.6 / ratio,
+ stride=ratio,
+ kernel_size=self.kernel_size)
+
+ def forward(self, x):
+ xx = self.lowpass(x)
+
+ return xx
+
+class Activation1d(nn.Module):
+ def __init__(self,
+ activation,
+ up_ratio: int = 2,
+ down_ratio: int = 2,
+ up_kernel_size: int = 12,
+ down_kernel_size: int = 12):
+ super().__init__()
+ self.up_ratio = up_ratio
+ self.down_ratio = down_ratio
+ self.act = activation
+ self.upsample = UpSample1d(up_ratio, up_kernel_size)
+ self.downsample = DownSample1d(down_ratio, down_kernel_size)
+
+ # x: [B,C,T]
+ def forward(self, x):
+ x = self.upsample(x)
+ x = self.act(x)
+ x = self.downsample(x)
+
+ return x
diff --git a/ComfyUI/comfy/ldm/mmaudio/vae/autoencoder.py b/ComfyUI/comfy/ldm/mmaudio/vae/autoencoder.py
new file mode 100644
index 0000000000000000000000000000000000000000..cbb9de302092957902e1b32fff3c687cc89d1058
--- /dev/null
+++ b/ComfyUI/comfy/ldm/mmaudio/vae/autoencoder.py
@@ -0,0 +1,156 @@
+from typing import Literal
+
+import torch
+import torch.nn as nn
+
+from .distributions import DiagonalGaussianDistribution
+from .vae import VAE_16k
+from .bigvgan import BigVGANVocoder
+import logging
+
+try:
+ import torchaudio
+except:
+ logging.warning("torchaudio missing, MMAudio VAE model will be broken")
+
+def dynamic_range_compression_torch(x, C=1, clip_val=1e-5, *, norm_fn):
+ return norm_fn(torch.clamp(x, min=clip_val) * C)
+
+
+def spectral_normalize_torch(magnitudes, norm_fn):
+ output = dynamic_range_compression_torch(magnitudes, norm_fn=norm_fn)
+ return output
+
+class MelConverter(nn.Module):
+
+ def __init__(
+ self,
+ *,
+ sampling_rate: float,
+ n_fft: int,
+ num_mels: int,
+ hop_size: int,
+ win_size: int,
+ fmin: float,
+ fmax: float,
+ norm_fn,
+ ):
+ super().__init__()
+ self.sampling_rate = sampling_rate
+ self.n_fft = n_fft
+ self.num_mels = num_mels
+ self.hop_size = hop_size
+ self.win_size = win_size
+ self.fmin = fmin
+ self.fmax = fmax
+ self.norm_fn = norm_fn
+
+ # mel = librosa_mel_fn(sr=self.sampling_rate,
+ # n_fft=self.n_fft,
+ # n_mels=self.num_mels,
+ # fmin=self.fmin,
+ # fmax=self.fmax)
+ # mel_basis = torch.from_numpy(mel).float()
+ mel_basis = torch.empty((num_mels, 1 + n_fft // 2))
+ hann_window = torch.hann_window(self.win_size)
+
+ self.register_buffer('mel_basis', mel_basis)
+ self.register_buffer('hann_window', hann_window)
+
+ @property
+ def device(self):
+ return self.mel_basis.device
+
+ def forward(self, waveform: torch.Tensor, center: bool = False) -> torch.Tensor:
+ waveform = waveform.clamp(min=-1., max=1.).to(self.device)
+
+ waveform = torch.nn.functional.pad(
+ waveform.unsqueeze(1),
+ [int((self.n_fft - self.hop_size) / 2),
+ int((self.n_fft - self.hop_size) / 2)],
+ mode='reflect')
+ waveform = waveform.squeeze(1)
+
+ spec = torch.stft(waveform,
+ self.n_fft,
+ hop_length=self.hop_size,
+ win_length=self.win_size,
+ window=self.hann_window,
+ center=center,
+ pad_mode='reflect',
+ normalized=False,
+ onesided=True,
+ return_complex=True)
+
+ spec = torch.view_as_real(spec)
+ spec = torch.sqrt(spec.pow(2).sum(-1) + (1e-9))
+ spec = torch.matmul(self.mel_basis, spec)
+ spec = spectral_normalize_torch(spec, self.norm_fn)
+
+ return spec
+
+class AudioAutoencoder(nn.Module):
+
+ def __init__(
+ self,
+ *,
+ # ckpt_path: str,
+ mode=Literal['16k', '44k'],
+ need_vae_encoder: bool = True,
+ ):
+ super().__init__()
+
+ assert mode == "16k", "Only 16k mode is supported currently."
+ self.mel_converter = MelConverter(sampling_rate=16_000,
+ n_fft=1024,
+ num_mels=80,
+ hop_size=256,
+ win_size=1024,
+ fmin=0,
+ fmax=8_000,
+ norm_fn=torch.log10)
+
+ self.vae = VAE_16k().eval()
+
+ bigvgan_config = {
+ "resblock": "1",
+ "num_mels": 80,
+ "upsample_rates": [4, 4, 2, 2, 2, 2],
+ "upsample_kernel_sizes": [8, 8, 4, 4, 4, 4],
+ "upsample_initial_channel": 1536,
+ "resblock_kernel_sizes": [3, 7, 11],
+ "resblock_dilation_sizes": [
+ [1, 3, 5],
+ [1, 3, 5],
+ [1, 3, 5],
+ ],
+ "activation": "snakebeta",
+ "snake_logscale": True,
+ }
+
+ self.vocoder = BigVGANVocoder(
+ bigvgan_config
+ ).eval()
+
+ @torch.inference_mode()
+ def encode_audio(self, x) -> DiagonalGaussianDistribution:
+ # x: (B * L)
+ mel = self.mel_converter(x)
+ dist = self.vae.encode(mel)
+
+ return dist
+
+ @torch.no_grad()
+ def decode(self, z):
+ mel_decoded = self.vae.decode(z)
+ audio = self.vocoder(mel_decoded)
+
+ audio = torchaudio.functional.resample(audio, 16000, 44100)
+ return audio
+
+ @torch.no_grad()
+ def encode(self, audio):
+ audio = audio.mean(dim=1)
+ audio = torchaudio.functional.resample(audio, 44100, 16000)
+ dist = self.encode_audio(audio)
+ return dist.mean
diff --git a/ComfyUI/comfy/ldm/mmaudio/vae/bigvgan.py b/ComfyUI/comfy/ldm/mmaudio/vae/bigvgan.py
new file mode 100644
index 0000000000000000000000000000000000000000..3a24337f62342220685662fa7bb3a9ffcc702ff1
--- /dev/null
+++ b/ComfyUI/comfy/ldm/mmaudio/vae/bigvgan.py
@@ -0,0 +1,219 @@
+# Copyright (c) 2022 NVIDIA CORPORATION.
+# Licensed under the MIT license.
+
+# Adapted from https://github.com/jik876/hifi-gan under the MIT license.
+# LICENSE is in incl_licenses directory.
+
+import torch
+import torch.nn as nn
+from types import SimpleNamespace
+from . import activations
+from .alias_free_torch import Activation1d
+import comfy.ops
+ops = comfy.ops.disable_weight_init
+
+def get_padding(kernel_size, dilation=1):
+ return int((kernel_size * dilation - dilation) / 2)
+
+class AMPBlock1(torch.nn.Module):
+
+ def __init__(self, h, channels, kernel_size=3, dilation=(1, 3, 5), activation=None):
+ super(AMPBlock1, self).__init__()
+ self.h = h
+
+ self.convs1 = nn.ModuleList([
+ ops.Conv1d(channels,
+ channels,
+ kernel_size,
+ 1,
+ dilation=dilation[0],
+ padding=get_padding(kernel_size, dilation[0])),
+ ops.Conv1d(channels,
+ channels,
+ kernel_size,
+ 1,
+ dilation=dilation[1],
+ padding=get_padding(kernel_size, dilation[1])),
+ ops.Conv1d(channels,
+ channels,
+ kernel_size,
+ 1,
+ dilation=dilation[2],
+ padding=get_padding(kernel_size, dilation[2]))
+ ])
+
+ self.convs2 = nn.ModuleList([
+ ops.Conv1d(channels,
+ channels,
+ kernel_size,
+ 1,
+ dilation=1,
+ padding=get_padding(kernel_size, 1)),
+ ops.Conv1d(channels,
+ channels,
+ kernel_size,
+ 1,
+ dilation=1,
+ padding=get_padding(kernel_size, 1)),
+ ops.Conv1d(channels,
+ channels,
+ kernel_size,
+ 1,
+ dilation=1,
+ padding=get_padding(kernel_size, 1))
+ ])
+
+ self.num_layers = len(self.convs1) + len(self.convs2) # total number of conv layers
+
+ if activation == 'snake': # periodic nonlinearity with snake function and anti-aliasing
+ self.activations = nn.ModuleList([
+ Activation1d(
+ activation=activations.Snake(channels, alpha_logscale=h.snake_logscale))
+ for _ in range(self.num_layers)
+ ])
+ elif activation == 'snakebeta': # periodic nonlinearity with snakebeta function and anti-aliasing
+ self.activations = nn.ModuleList([
+ Activation1d(
+ activation=activations.SnakeBeta(channels, alpha_logscale=h.snake_logscale))
+ for _ in range(self.num_layers)
+ ])
+ else:
+ raise NotImplementedError(
+ "activation incorrectly specified. check the config file and look for 'activation'."
+ )
+
+ def forward(self, x):
+ acts1, acts2 = self.activations[::2], self.activations[1::2]
+ for c1, c2, a1, a2 in zip(self.convs1, self.convs2, acts1, acts2):
+ xt = a1(x)
+ xt = c1(xt)
+ xt = a2(xt)
+ xt = c2(xt)
+ x = xt + x
+
+ return x
+
+
+class AMPBlock2(torch.nn.Module):
+
+ def __init__(self, h, channels, kernel_size=3, dilation=(1, 3), activation=None):
+ super(AMPBlock2, self).__init__()
+ self.h = h
+
+ self.convs = nn.ModuleList([
+ ops.Conv1d(channels,
+ channels,
+ kernel_size,
+ 1,
+ dilation=dilation[0],
+ padding=get_padding(kernel_size, dilation[0])),
+ ops.Conv1d(channels,
+ channels,
+ kernel_size,
+ 1,
+ dilation=dilation[1],
+ padding=get_padding(kernel_size, dilation[1]))
+ ])
+
+ self.num_layers = len(self.convs) # total number of conv layers
+
+ if activation == 'snake': # periodic nonlinearity with snake function and anti-aliasing
+ self.activations = nn.ModuleList([
+ Activation1d(
+ activation=activations.Snake(channels, alpha_logscale=h.snake_logscale))
+ for _ in range(self.num_layers)
+ ])
+ elif activation == 'snakebeta': # periodic nonlinearity with snakebeta function and anti-aliasing
+ self.activations = nn.ModuleList([
+ Activation1d(
+ activation=activations.SnakeBeta(channels, alpha_logscale=h.snake_logscale))
+ for _ in range(self.num_layers)
+ ])
+ else:
+ raise NotImplementedError(
+ "activation incorrectly specified. check the config file and look for 'activation'."
+ )
+
+ def forward(self, x):
+ for c, a in zip(self.convs, self.activations):
+ xt = a(x)
+ xt = c(xt)
+ x = xt + x
+
+ return x
+
+
+class BigVGANVocoder(torch.nn.Module):
+ # this is our main BigVGAN model. Applies anti-aliased periodic activation for resblocks.
+ def __init__(self, h):
+ super().__init__()
+ if isinstance(h, dict):
+ h = SimpleNamespace(**h)
+ self.h = h
+
+ self.num_kernels = len(h.resblock_kernel_sizes)
+ self.num_upsamples = len(h.upsample_rates)
+
+ # pre conv
+ self.conv_pre = ops.Conv1d(h.num_mels, h.upsample_initial_channel, 7, 1, padding=3)
+
+ # define which AMPBlock to use. BigVGAN uses AMPBlock1 as default
+ resblock = AMPBlock1 if h.resblock == '1' else AMPBlock2
+
+ # transposed conv-based upsamplers. does not apply anti-aliasing
+ self.ups = nn.ModuleList()
+ for i, (u, k) in enumerate(zip(h.upsample_rates, h.upsample_kernel_sizes)):
+ self.ups.append(
+ nn.ModuleList([
+ ops.ConvTranspose1d(h.upsample_initial_channel // (2**i),
+ h.upsample_initial_channel // (2**(i + 1)),
+ k,
+ u,
+ padding=(k - u) // 2)
+ ]))
+
+ # residual blocks using anti-aliased multi-periodicity composition modules (AMP)
+ self.resblocks = nn.ModuleList()
+ for i in range(len(self.ups)):
+ ch = h.upsample_initial_channel // (2**(i + 1))
+ for j, (k, d) in enumerate(zip(h.resblock_kernel_sizes, h.resblock_dilation_sizes)):
+ self.resblocks.append(resblock(h, ch, k, d, activation=h.activation))
+
+ # post conv
+ if h.activation == "snake": # periodic nonlinearity with snake function and anti-aliasing
+ activation_post = activations.Snake(ch, alpha_logscale=h.snake_logscale)
+ self.activation_post = Activation1d(activation=activation_post)
+ elif h.activation == "snakebeta": # periodic nonlinearity with snakebeta function and anti-aliasing
+ activation_post = activations.SnakeBeta(ch, alpha_logscale=h.snake_logscale)
+ self.activation_post = Activation1d(activation=activation_post)
+ else:
+ raise NotImplementedError(
+ "activation incorrectly specified. check the config file and look for 'activation'."
+ )
+
+ self.conv_post = ops.Conv1d(ch, 1, 7, 1, padding=3)
+
+
+ def forward(self, x):
+ # pre conv
+ x = self.conv_pre(x)
+
+ for i in range(self.num_upsamples):
+ # upsampling
+ for i_up in range(len(self.ups[i])):
+ x = self.ups[i][i_up](x)
+ # AMP blocks
+ xs = None
+ for j in range(self.num_kernels):
+ if xs is None:
+ xs = self.resblocks[i * self.num_kernels + j](x)
+ else:
+ xs += self.resblocks[i * self.num_kernels + j](x)
+ x = xs / self.num_kernels
+
+ # post conv
+ x = self.activation_post(x)
+ x = self.conv_post(x)
+ x = torch.tanh(x)
+
+ return x
diff --git a/ComfyUI/comfy/ldm/mmaudio/vae/distributions.py b/ComfyUI/comfy/ldm/mmaudio/vae/distributions.py
new file mode 100644
index 0000000000000000000000000000000000000000..df987c5ec3faaba7da2b02029ad413134bfa08ad
--- /dev/null
+++ b/ComfyUI/comfy/ldm/mmaudio/vae/distributions.py
@@ -0,0 +1,92 @@
+import torch
+import numpy as np
+
+
+class AbstractDistribution:
+ def sample(self):
+ raise NotImplementedError()
+
+ def mode(self):
+ raise NotImplementedError()
+
+
+class DiracDistribution(AbstractDistribution):
+ def __init__(self, value):
+ self.value = value
+
+ def sample(self):
+ return self.value
+
+ def mode(self):
+ return self.value
+
+
+class DiagonalGaussianDistribution(object):
+ def __init__(self, parameters, deterministic=False):
+ self.parameters = parameters
+ self.mean, self.logvar = torch.chunk(parameters, 2, dim=1)
+ self.logvar = torch.clamp(self.logvar, -30.0, 20.0)
+ self.deterministic = deterministic
+ self.std = torch.exp(0.5 * self.logvar)
+ self.var = torch.exp(self.logvar)
+ if self.deterministic:
+ self.var = self.std = torch.zeros_like(self.mean, device=self.parameters.device)
+
+ def sample(self):
+ x = self.mean + self.std * torch.randn(self.mean.shape, device=self.parameters.device)
+ return x
+
+ def kl(self, other=None):
+ if self.deterministic:
+ return torch.Tensor([0.])
+ else:
+ if other is None:
+ return 0.5 * torch.sum(torch.pow(self.mean, 2)
+ + self.var - 1.0 - self.logvar,
+ dim=[1, 2, 3])
+ else:
+ return 0.5 * torch.sum(
+ torch.pow(self.mean - other.mean, 2) / other.var
+ + self.var / other.var - 1.0 - self.logvar + other.logvar,
+ dim=[1, 2, 3])
+
+ def nll(self, sample, dims=[1,2,3]):
+ if self.deterministic:
+ return torch.Tensor([0.])
+ logtwopi = np.log(2.0 * np.pi)
+ return 0.5 * torch.sum(
+ logtwopi + self.logvar + torch.pow(sample - self.mean, 2) / self.var,
+ dim=dims)
+
+ def mode(self):
+ return self.mean
+
+
+def normal_kl(mean1, logvar1, mean2, logvar2):
+ """
+ source: https://github.com/openai/guided-diffusion/blob/27c20a8fab9cb472df5d6bdd6c8d11c8f430b924/guided_diffusion/losses.py#L12
+ Compute the KL divergence between two gaussians.
+ Shapes are automatically broadcasted, so batches can be compared to
+ scalars, among other use cases.
+ """
+ tensor = None
+ for obj in (mean1, logvar1, mean2, logvar2):
+ if isinstance(obj, torch.Tensor):
+ tensor = obj
+ break
+ assert tensor is not None, "at least one argument must be a Tensor"
+
+ # Force variances to be Tensors. Broadcasting helps convert scalars to
+ # Tensors, but it does not work for torch.exp().
+ logvar1, logvar2 = [
+ x if isinstance(x, torch.Tensor) else torch.tensor(x).to(tensor)
+ for x in (logvar1, logvar2)
+ ]
+
+ return 0.5 * (
+ -1.0
+ + logvar2
+ - logvar1
+ + torch.exp(logvar1 - logvar2)
+ + ((mean1 - mean2) ** 2) * torch.exp(-logvar2)
+ )
diff --git a/ComfyUI/comfy/ldm/mmaudio/vae/vae.py b/ComfyUI/comfy/ldm/mmaudio/vae/vae.py
new file mode 100644
index 0000000000000000000000000000000000000000..62f24606c111e8fcd99b2adbf93761541c02e032
--- /dev/null
+++ b/ComfyUI/comfy/ldm/mmaudio/vae/vae.py
@@ -0,0 +1,358 @@
+import logging
+from typing import Optional
+
+import torch
+import torch.nn as nn
+
+from .vae_modules import (AttnBlock1D, Downsample1D, ResnetBlock1D,
+ Upsample1D, nonlinearity)
+from .distributions import DiagonalGaussianDistribution
+
+import comfy.ops
+ops = comfy.ops.disable_weight_init
+
+log = logging.getLogger()
+
+DATA_MEAN_80D = [
+ -1.6058, -1.3676, -1.2520, -1.2453, -1.2078, -1.2224, -1.2419, -1.2439, -1.2922, -1.2927,
+ -1.3170, -1.3543, -1.3401, -1.3836, -1.3907, -1.3912, -1.4313, -1.4152, -1.4527, -1.4728,
+ -1.4568, -1.5101, -1.5051, -1.5172, -1.5623, -1.5373, -1.5746, -1.5687, -1.6032, -1.6131,
+ -1.6081, -1.6331, -1.6489, -1.6489, -1.6700, -1.6738, -1.6953, -1.6969, -1.7048, -1.7280,
+ -1.7361, -1.7495, -1.7658, -1.7814, -1.7889, -1.8064, -1.8221, -1.8377, -1.8417, -1.8643,
+ -1.8857, -1.8929, -1.9173, -1.9379, -1.9531, -1.9673, -1.9824, -2.0042, -2.0215, -2.0436,
+ -2.0766, -2.1064, -2.1418, -2.1855, -2.2319, -2.2767, -2.3161, -2.3572, -2.3954, -2.4282,
+ -2.4659, -2.5072, -2.5552, -2.6074, -2.6584, -2.7107, -2.7634, -2.8266, -2.8981, -2.9673
+]
+
+DATA_STD_80D = [
+ 1.0291, 1.0411, 1.0043, 0.9820, 0.9677, 0.9543, 0.9450, 0.9392, 0.9343, 0.9297, 0.9276, 0.9263,
+ 0.9242, 0.9254, 0.9232, 0.9281, 0.9263, 0.9315, 0.9274, 0.9247, 0.9277, 0.9199, 0.9188, 0.9194,
+ 0.9160, 0.9161, 0.9146, 0.9161, 0.9100, 0.9095, 0.9145, 0.9076, 0.9066, 0.9095, 0.9032, 0.9043,
+ 0.9038, 0.9011, 0.9019, 0.9010, 0.8984, 0.8983, 0.8986, 0.8961, 0.8962, 0.8978, 0.8962, 0.8973,
+ 0.8993, 0.8976, 0.8995, 0.9016, 0.8982, 0.8972, 0.8974, 0.8949, 0.8940, 0.8947, 0.8936, 0.8939,
+ 0.8951, 0.8956, 0.9017, 0.9167, 0.9436, 0.9690, 1.0003, 1.0225, 1.0381, 1.0491, 1.0545, 1.0604,
+ 1.0761, 1.0929, 1.1089, 1.1196, 1.1176, 1.1156, 1.1117, 1.1070
+]
+
+DATA_MEAN_128D = [
+ -3.3462, -2.6723, -2.4893, -2.3143, -2.2664, -2.3317, -2.1802, -2.4006, -2.2357, -2.4597,
+ -2.3717, -2.4690, -2.5142, -2.4919, -2.6610, -2.5047, -2.7483, -2.5926, -2.7462, -2.7033,
+ -2.7386, -2.8112, -2.7502, -2.9594, -2.7473, -3.0035, -2.8891, -2.9922, -2.9856, -3.0157,
+ -3.1191, -2.9893, -3.1718, -3.0745, -3.1879, -3.2310, -3.1424, -3.2296, -3.2791, -3.2782,
+ -3.2756, -3.3134, -3.3509, -3.3750, -3.3951, -3.3698, -3.4505, -3.4509, -3.5089, -3.4647,
+ -3.5536, -3.5788, -3.5867, -3.6036, -3.6400, -3.6747, -3.7072, -3.7279, -3.7283, -3.7795,
+ -3.8259, -3.8447, -3.8663, -3.9182, -3.9605, -3.9861, -4.0105, -4.0373, -4.0762, -4.1121,
+ -4.1488, -4.1874, -4.2461, -4.3170, -4.3639, -4.4452, -4.5282, -4.6297, -4.7019, -4.7960,
+ -4.8700, -4.9507, -5.0303, -5.0866, -5.1634, -5.2342, -5.3242, -5.4053, -5.4927, -5.5712,
+ -5.6464, -5.7052, -5.7619, -5.8410, -5.9188, -6.0103, -6.0955, -6.1673, -6.2362, -6.3120,
+ -6.3926, -6.4797, -6.5565, -6.6511, -6.8130, -6.9961, -7.1275, -7.2457, -7.3576, -7.4663,
+ -7.6136, -7.7469, -7.8815, -8.0132, -8.1515, -8.3071, -8.4722, -8.7418, -9.3975, -9.6628,
+ -9.7671, -9.8863, -9.9992, -10.0860, -10.1709, -10.5418, -11.2795, -11.3861
+]
+
+DATA_STD_128D = [
+ 2.3804, 2.4368, 2.3772, 2.3145, 2.2803, 2.2510, 2.2316, 2.2083, 2.1996, 2.1835, 2.1769, 2.1659,
+ 2.1631, 2.1618, 2.1540, 2.1606, 2.1571, 2.1567, 2.1612, 2.1579, 2.1679, 2.1683, 2.1634, 2.1557,
+ 2.1668, 2.1518, 2.1415, 2.1449, 2.1406, 2.1350, 2.1313, 2.1415, 2.1281, 2.1352, 2.1219, 2.1182,
+ 2.1327, 2.1195, 2.1137, 2.1080, 2.1179, 2.1036, 2.1087, 2.1036, 2.1015, 2.1068, 2.0975, 2.0991,
+ 2.0902, 2.1015, 2.0857, 2.0920, 2.0893, 2.0897, 2.0910, 2.0881, 2.0925, 2.0873, 2.0960, 2.0900,
+ 2.0957, 2.0958, 2.0978, 2.0936, 2.0886, 2.0905, 2.0845, 2.0855, 2.0796, 2.0840, 2.0813, 2.0817,
+ 2.0838, 2.0840, 2.0917, 2.1061, 2.1431, 2.1976, 2.2482, 2.3055, 2.3700, 2.4088, 2.4372, 2.4609,
+ 2.4731, 2.4847, 2.5072, 2.5451, 2.5772, 2.6147, 2.6529, 2.6596, 2.6645, 2.6726, 2.6803, 2.6812,
+ 2.6899, 2.6916, 2.6931, 2.6998, 2.7062, 2.7262, 2.7222, 2.7158, 2.7041, 2.7485, 2.7491, 2.7451,
+ 2.7485, 2.7233, 2.7297, 2.7233, 2.7145, 2.6958, 2.6788, 2.6439, 2.6007, 2.4786, 2.2469, 2.1877,
+ 2.1392, 2.0717, 2.0107, 1.9676, 1.9140, 1.7102, 0.9101, 0.7164
+]
+
+
+class VAE(nn.Module):
+
+ def __init__(
+ self,
+ *,
+ data_dim: int,
+ embed_dim: int,
+ hidden_dim: int,
+ ):
+ super().__init__()
+
+ if data_dim == 80:
+ self.data_mean = nn.Buffer(torch.tensor(DATA_MEAN_80D, dtype=torch.float32))
+ self.data_std = nn.Buffer(torch.tensor(DATA_STD_80D, dtype=torch.float32))
+ elif data_dim == 128:
+ self.data_mean = nn.Buffer(torch.tensor(DATA_MEAN_128D, dtype=torch.float32))
+ self.data_std = nn.Buffer(torch.tensor(DATA_STD_128D, dtype=torch.float32))
+
+ self.data_mean = self.data_mean.view(1, -1, 1)
+ self.data_std = self.data_std.view(1, -1, 1)
+
+ self.encoder = Encoder1D(
+ dim=hidden_dim,
+ ch_mult=(1, 2, 4),
+ num_res_blocks=2,
+ attn_layers=[3],
+ down_layers=[0],
+ in_dim=data_dim,
+ embed_dim=embed_dim,
+ )
+ self.decoder = Decoder1D(
+ dim=hidden_dim,
+ ch_mult=(1, 2, 4),
+ num_res_blocks=2,
+ attn_layers=[3],
+ down_layers=[0],
+ in_dim=data_dim,
+ out_dim=data_dim,
+ embed_dim=embed_dim,
+ )
+
+ self.embed_dim = embed_dim
+ # self.quant_conv = nn.Conv1d(2 * embed_dim, 2 * embed_dim, 1)
+ # self.post_quant_conv = nn.Conv1d(embed_dim, embed_dim, 1)
+
+ self.initialize_weights()
+
+ def initialize_weights(self):
+ pass
+
+ def encode(self, x: torch.Tensor, normalize: bool = True) -> DiagonalGaussianDistribution:
+ if normalize:
+ x = self.normalize(x)
+ moments = self.encoder(x)
+ posterior = DiagonalGaussianDistribution(moments)
+ return posterior
+
+ def decode(self, z: torch.Tensor, unnormalize: bool = True) -> torch.Tensor:
+ dec = self.decoder(z)
+ if unnormalize:
+ dec = self.unnormalize(dec)
+ return dec
+
+ def normalize(self, x: torch.Tensor) -> torch.Tensor:
+ return (x - comfy.model_management.cast_to(self.data_mean, dtype=x.dtype, device=x.device)) / comfy.model_management.cast_to(self.data_std, dtype=x.dtype, device=x.device)
+
+ def unnormalize(self, x: torch.Tensor) -> torch.Tensor:
+ return x * comfy.model_management.cast_to(self.data_std, dtype=x.dtype, device=x.device) + comfy.model_management.cast_to(self.data_mean, dtype=x.dtype, device=x.device)
+
+ def forward(
+ self,
+ x: torch.Tensor,
+ sample_posterior: bool = True,
+ rng: Optional[torch.Generator] = None,
+ normalize: bool = True,
+ unnormalize: bool = True,
+ ) -> tuple[torch.Tensor, DiagonalGaussianDistribution]:
+
+ posterior = self.encode(x, normalize=normalize)
+ if sample_posterior:
+ z = posterior.sample(rng)
+ else:
+ z = posterior.mode()
+ dec = self.decode(z, unnormalize=unnormalize)
+ return dec, posterior
+
+ def load_weights(self, src_dict) -> None:
+ self.load_state_dict(src_dict, strict=True)
+
+ @property
+ def device(self) -> torch.device:
+ return next(self.parameters()).device
+
+ def get_last_layer(self):
+ return self.decoder.conv_out.weight
+
+ def remove_weight_norm(self):
+ return self
+
+
+class Encoder1D(nn.Module):
+
+ def __init__(self,
+ *,
+ dim: int,
+ ch_mult: tuple[int] = (1, 2, 4, 8),
+ num_res_blocks: int,
+ attn_layers: list[int] = [],
+ down_layers: list[int] = [],
+ resamp_with_conv: bool = True,
+ in_dim: int,
+ embed_dim: int,
+ double_z: bool = True,
+ kernel_size: int = 3,
+ clip_act: float = 256.0):
+ super().__init__()
+ self.dim = dim
+ self.num_layers = len(ch_mult)
+ self.num_res_blocks = num_res_blocks
+ self.in_channels = in_dim
+ self.clip_act = clip_act
+ self.down_layers = down_layers
+ self.attn_layers = attn_layers
+ self.conv_in = ops.Conv1d(in_dim, self.dim, kernel_size=kernel_size, padding=kernel_size // 2, bias=False)
+
+ in_ch_mult = (1, ) + tuple(ch_mult)
+ self.in_ch_mult = in_ch_mult
+ # downsampling
+ self.down = nn.ModuleList()
+ for i_level in range(self.num_layers):
+ block = nn.ModuleList()
+ attn = nn.ModuleList()
+ block_in = dim * in_ch_mult[i_level]
+ block_out = dim * ch_mult[i_level]
+ for i_block in range(self.num_res_blocks):
+ block.append(
+ ResnetBlock1D(in_dim=block_in,
+ out_dim=block_out,
+ kernel_size=kernel_size,
+ use_norm=True))
+ block_in = block_out
+ if i_level in attn_layers:
+ attn.append(AttnBlock1D(block_in))
+ down = nn.Module()
+ down.block = block
+ down.attn = attn
+ if i_level in down_layers:
+ down.downsample = Downsample1D(block_in, resamp_with_conv)
+ self.down.append(down)
+
+ # middle
+ self.mid = nn.Module()
+ self.mid.block_1 = ResnetBlock1D(in_dim=block_in,
+ out_dim=block_in,
+ kernel_size=kernel_size,
+ use_norm=True)
+ self.mid.attn_1 = AttnBlock1D(block_in)
+ self.mid.block_2 = ResnetBlock1D(in_dim=block_in,
+ out_dim=block_in,
+ kernel_size=kernel_size,
+ use_norm=True)
+
+ # end
+ self.conv_out = ops.Conv1d(block_in,
+ 2 * embed_dim if double_z else embed_dim,
+ kernel_size=kernel_size, padding=kernel_size // 2, bias=False)
+
+ self.learnable_gain = nn.Parameter(torch.zeros([]))
+
+ def forward(self, x):
+
+ # downsampling
+ h = self.conv_in(x)
+ for i_level in range(self.num_layers):
+ for i_block in range(self.num_res_blocks):
+ h = self.down[i_level].block[i_block](h)
+ if len(self.down[i_level].attn) > 0:
+ h = self.down[i_level].attn[i_block](h)
+ h = h.clamp(-self.clip_act, self.clip_act)
+ if i_level in self.down_layers:
+ h = self.down[i_level].downsample(h)
+
+ # middle
+ h = self.mid.block_1(h)
+ h = self.mid.attn_1(h)
+ h = self.mid.block_2(h)
+ h = h.clamp(-self.clip_act, self.clip_act)
+
+ # end
+ h = nonlinearity(h)
+ h = self.conv_out(h) * (self.learnable_gain + 1)
+ return h
+
+
+class Decoder1D(nn.Module):
+
+ def __init__(self,
+ *,
+ dim: int,
+ out_dim: int,
+ ch_mult: tuple[int] = (1, 2, 4, 8),
+ num_res_blocks: int,
+ attn_layers: list[int] = [],
+ down_layers: list[int] = [],
+ kernel_size: int = 3,
+ resamp_with_conv: bool = True,
+ in_dim: int,
+ embed_dim: int,
+ clip_act: float = 256.0):
+ super().__init__()
+ self.ch = dim
+ self.num_layers = len(ch_mult)
+ self.num_res_blocks = num_res_blocks
+ self.in_channels = in_dim
+ self.clip_act = clip_act
+ self.down_layers = [i + 1 for i in down_layers] # each downlayer add one
+
+ # compute in_ch_mult, block_in and curr_res at lowest res
+ block_in = dim * ch_mult[self.num_layers - 1]
+
+ # z to block_in
+ self.conv_in = ops.Conv1d(embed_dim, block_in, kernel_size=kernel_size, padding=kernel_size // 2, bias=False)
+
+ # middle
+ self.mid = nn.Module()
+ self.mid.block_1 = ResnetBlock1D(in_dim=block_in, out_dim=block_in, use_norm=True)
+ self.mid.attn_1 = AttnBlock1D(block_in)
+ self.mid.block_2 = ResnetBlock1D(in_dim=block_in, out_dim=block_in, use_norm=True)
+
+ # upsampling
+ self.up = nn.ModuleList()
+ for i_level in reversed(range(self.num_layers)):
+ block = nn.ModuleList()
+ attn = nn.ModuleList()
+ block_out = dim * ch_mult[i_level]
+ for i_block in range(self.num_res_blocks + 1):
+ block.append(ResnetBlock1D(in_dim=block_in, out_dim=block_out, use_norm=True))
+ block_in = block_out
+ if i_level in attn_layers:
+ attn.append(AttnBlock1D(block_in))
+ up = nn.Module()
+ up.block = block
+ up.attn = attn
+ if i_level in self.down_layers:
+ up.upsample = Upsample1D(block_in, resamp_with_conv)
+ self.up.insert(0, up) # prepend to get consistent order
+
+ # end
+ self.conv_out = ops.Conv1d(block_in, out_dim, kernel_size=kernel_size, padding=kernel_size // 2, bias=False)
+ self.learnable_gain = nn.Parameter(torch.zeros([]))
+
+ def forward(self, z):
+ # z to block_in
+ h = self.conv_in(z)
+
+ # middle
+ h = self.mid.block_1(h)
+ h = self.mid.attn_1(h)
+ h = self.mid.block_2(h)
+ h = h.clamp(-self.clip_act, self.clip_act)
+
+ # upsampling
+ for i_level in reversed(range(self.num_layers)):
+ for i_block in range(self.num_res_blocks + 1):
+ h = self.up[i_level].block[i_block](h)
+ if len(self.up[i_level].attn) > 0:
+ h = self.up[i_level].attn[i_block](h)
+ h = h.clamp(-self.clip_act, self.clip_act)
+ if i_level in self.down_layers:
+ h = self.up[i_level].upsample(h)
+
+ h = nonlinearity(h)
+ h = self.conv_out(h) * (self.learnable_gain + 1)
+ return h
+
+
+def VAE_16k(**kwargs) -> VAE:
+ return VAE(data_dim=80, embed_dim=20, hidden_dim=384, **kwargs)
+
+
+def VAE_44k(**kwargs) -> VAE:
+ return VAE(data_dim=128, embed_dim=40, hidden_dim=512, **kwargs)
+
+
+def get_my_vae(name: str, **kwargs) -> VAE:
+ if name == '16k':
+ return VAE_16k(**kwargs)
+ if name == '44k':
+ return VAE_44k(**kwargs)
+ raise ValueError(f'Unknown model: {name}')
+
diff --git a/ComfyUI/comfy/ldm/mmaudio/vae/vae_modules.py b/ComfyUI/comfy/ldm/mmaudio/vae/vae_modules.py
new file mode 100644
index 0000000000000000000000000000000000000000..3ad05134bc44e05c54fd7acb8e2fa960d86bb1fb
--- /dev/null
+++ b/ComfyUI/comfy/ldm/mmaudio/vae/vae_modules.py
@@ -0,0 +1,121 @@
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+from comfy.ldm.modules.diffusionmodules.model import vae_attention
+import math
+import comfy.ops
+ops = comfy.ops.disable_weight_init
+
+def nonlinearity(x):
+ # swish
+ return torch.nn.functional.silu(x) / 0.596
+
+def mp_sum(a, b, t=0.5):
+ return a.lerp(b, t) / math.sqrt((1 - t)**2 + t**2)
+
+def normalize(x, dim=None, eps=1e-4):
+ if dim is None:
+ dim = list(range(1, x.ndim))
+ norm = torch.linalg.vector_norm(x, dim=dim, keepdim=True, dtype=torch.float32)
+ norm = torch.add(eps, norm, alpha=math.sqrt(norm.numel() / x.numel()))
+ return x / norm.to(x.dtype)
+
+class ResnetBlock1D(nn.Module):
+
+ def __init__(self, *, in_dim, out_dim=None, conv_shortcut=False, kernel_size=3, use_norm=True):
+ super().__init__()
+ self.in_dim = in_dim
+ out_dim = in_dim if out_dim is None else out_dim
+ self.out_dim = out_dim
+ self.use_conv_shortcut = conv_shortcut
+ self.use_norm = use_norm
+
+ self.conv1 = ops.Conv1d(in_dim, out_dim, kernel_size=kernel_size, padding=kernel_size // 2, bias=False)
+ self.conv2 = ops.Conv1d(out_dim, out_dim, kernel_size=kernel_size, padding=kernel_size // 2, bias=False)
+ if self.in_dim != self.out_dim:
+ if self.use_conv_shortcut:
+ self.conv_shortcut = ops.Conv1d(in_dim, out_dim, kernel_size=kernel_size, padding=kernel_size // 2, bias=False)
+ else:
+ self.nin_shortcut = ops.Conv1d(in_dim, out_dim, kernel_size=1, padding=0, bias=False)
+
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
+
+ # pixel norm
+ if self.use_norm:
+ x = normalize(x, dim=1)
+
+ h = x
+ h = nonlinearity(h)
+ h = self.conv1(h)
+
+ h = nonlinearity(h)
+ h = self.conv2(h)
+
+ if self.in_dim != self.out_dim:
+ if self.use_conv_shortcut:
+ x = self.conv_shortcut(x)
+ else:
+ x = self.nin_shortcut(x)
+
+ return mp_sum(x, h, t=0.3)
+
+
+class AttnBlock1D(nn.Module):
+
+ def __init__(self, in_channels, num_heads=1):
+ super().__init__()
+ self.in_channels = in_channels
+
+ self.num_heads = num_heads
+ self.qkv = ops.Conv1d(in_channels, in_channels * 3, kernel_size=1, padding=0, bias=False)
+ self.proj_out = ops.Conv1d(in_channels, in_channels, kernel_size=1, padding=0, bias=False)
+ self.optimized_attention = vae_attention()
+
+ def forward(self, x):
+ h = x
+ y = self.qkv(h)
+ y = y.reshape(y.shape[0], -1, 3, y.shape[-1])
+ q, k, v = normalize(y, dim=1).unbind(2)
+
+ h = self.optimized_attention(q, k, v)
+ h = self.proj_out(h)
+
+ return mp_sum(x, h, t=0.3)
+
+
+class Upsample1D(nn.Module):
+
+ def __init__(self, in_channels, with_conv):
+ super().__init__()
+ self.with_conv = with_conv
+ if self.with_conv:
+ self.conv = ops.Conv1d(in_channels, in_channels, kernel_size=3, padding=1, bias=False)
+
+ def forward(self, x):
+ x = F.interpolate(x, scale_factor=2.0, mode='nearest-exact') # support 3D tensor(B,C,T)
+ if self.with_conv:
+ x = self.conv(x)
+ return x
+
+
+class Downsample1D(nn.Module):
+
+ def __init__(self, in_channels, with_conv):
+ super().__init__()
+ self.with_conv = with_conv
+ if self.with_conv:
+ # no asymmetric padding in torch conv, must do it ourselves
+ self.conv1 = ops.Conv1d(in_channels, in_channels, kernel_size=1, padding=0, bias=False)
+ self.conv2 = ops.Conv1d(in_channels, in_channels, kernel_size=1, padding=0, bias=False)
+
+ def forward(self, x):
+
+ if self.with_conv:
+ x = self.conv1(x)
+
+ x = F.avg_pool1d(x, kernel_size=2, stride=2)
+
+ if self.with_conv:
+ x = self.conv2(x)
+
+ return x
diff --git a/ComfyUI/comfy/ldm/models/__pycache__/autoencoder.cpython-312.pyc b/ComfyUI/comfy/ldm/models/__pycache__/autoencoder.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..63b9cc3a385a6f8cc5742b165b235cd27091a4d0
Binary files /dev/null and b/ComfyUI/comfy/ldm/models/__pycache__/autoencoder.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/models/autoencoder.py b/ComfyUI/comfy/ldm/models/autoencoder.py
new file mode 100644
index 0000000000000000000000000000000000000000..582b44e6994861523cebef2fccbce86fcdbc0a46
--- /dev/null
+++ b/ComfyUI/comfy/ldm/models/autoencoder.py
@@ -0,0 +1,280 @@
+import logging
+import math
+import torch
+from contextlib import contextmanager
+from typing import Any, Dict, Tuple, Union
+
+from comfy.ldm.modules.distributions.distributions import DiagonalGaussianDistribution
+
+from comfy.ldm.util import get_obj_from_str, instantiate_from_config
+from comfy.ldm.modules.ema import LitEma
+import comfy.ops
+from einops import rearrange
+import comfy.model_management
+
+class DiagonalGaussianRegularizer(torch.nn.Module):
+ def __init__(self, sample: bool = False):
+ super().__init__()
+ self.sample = sample
+
+ def get_trainable_parameters(self) -> Any:
+ yield from ()
+
+ def forward(self, z: torch.Tensor) -> Tuple[torch.Tensor, dict]:
+ posterior = DiagonalGaussianDistribution(z)
+ if self.sample:
+ z = posterior.sample()
+ else:
+ z = posterior.mode()
+ return z, None
+
+class EmptyRegularizer(torch.nn.Module):
+ def __init__(self):
+ super().__init__()
+
+ def forward(self, z: torch.Tensor) -> Tuple[torch.Tensor, dict]:
+ return z, None
+
+class AbstractAutoencoder(torch.nn.Module):
+ """
+ This is the base class for all autoencoders, including image autoencoders, image autoencoders with discriminators,
+ unCLIP models, etc. Hence, it is fairly general, and specific features
+ (e.g. discriminator training, encoding, decoding) must be implemented in subclasses.
+ """
+
+ def __init__(
+ self,
+ ema_decay: Union[None, float] = None,
+ monitor: Union[None, str] = None,
+ input_key: str = "jpg",
+ **kwargs,
+ ):
+ super().__init__()
+
+ self.input_key = input_key
+ self.use_ema = ema_decay is not None
+ if monitor is not None:
+ self.monitor = monitor
+
+ if self.use_ema:
+ self.model_ema = LitEma(self, decay=ema_decay)
+ logging.info(f"Keeping EMAs of {len(list(self.model_ema.buffers()))}.")
+
+ def get_input(self, batch) -> Any:
+ raise NotImplementedError()
+
+ def on_train_batch_end(self, *args, **kwargs):
+ # for EMA computation
+ if self.use_ema:
+ self.model_ema(self)
+
+ @contextmanager
+ def ema_scope(self, context=None):
+ if self.use_ema:
+ self.model_ema.store(self.parameters())
+ self.model_ema.copy_to(self)
+ if context is not None:
+ logging.info(f"{context}: Switched to EMA weights")
+ try:
+ yield None
+ finally:
+ if self.use_ema:
+ self.model_ema.restore(self.parameters())
+ if context is not None:
+ logging.info(f"{context}: Restored training weights")
+
+ def encode(self, *args, **kwargs) -> torch.Tensor:
+ raise NotImplementedError("encode()-method of abstract base class called")
+
+ def decode(self, *args, **kwargs) -> torch.Tensor:
+ raise NotImplementedError("decode()-method of abstract base class called")
+
+ def instantiate_optimizer_from_config(self, params, lr, cfg):
+ logging.info(f"loading >>> {cfg['target']} <<< optimizer from config")
+ return get_obj_from_str(cfg["target"])(
+ params, lr=lr, **cfg.get("params", dict())
+ )
+
+ def configure_optimizers(self) -> Any:
+ raise NotImplementedError()
+
+
+class AutoencodingEngine(AbstractAutoencoder):
+ """
+ Base class for all image autoencoders that we train, like VQGAN or AutoencoderKL
+ (we also restore them explicitly as special cases for legacy reasons).
+ Regularizations such as KL or VQ are moved to the regularizer class.
+ """
+
+ def __init__(
+ self,
+ *args,
+ encoder_config: Dict,
+ decoder_config: Dict,
+ regularizer_config: Dict,
+ **kwargs,
+ ):
+ super().__init__(*args, **kwargs)
+
+ self.encoder: torch.nn.Module = instantiate_from_config(encoder_config)
+ self.decoder: torch.nn.Module = instantiate_from_config(decoder_config)
+ self.regularization = instantiate_from_config(
+ regularizer_config
+ )
+
+ def get_last_layer(self):
+ return self.decoder.get_last_layer()
+
+ def encode(
+ self,
+ x: torch.Tensor,
+ return_reg_log: bool = False,
+ unregularized: bool = False,
+ ) -> Union[torch.Tensor, Tuple[torch.Tensor, dict]]:
+ z = self.encoder(x)
+ if unregularized:
+ return z, dict()
+ z, reg_log = self.regularization(z)
+ if return_reg_log:
+ return z, reg_log
+ return z
+
+ def decode(self, z: torch.Tensor, **kwargs) -> torch.Tensor:
+ x = self.decoder(z, **kwargs)
+ return x
+
+ def forward(
+ self, x: torch.Tensor, **additional_decode_kwargs
+ ) -> Tuple[torch.Tensor, torch.Tensor, dict]:
+ z, reg_log = self.encode(x, return_reg_log=True)
+ dec = self.decode(z, **additional_decode_kwargs)
+ return z, dec, reg_log
+
+
+class AutoencodingEngineLegacy(AutoencodingEngine):
+ def __init__(self, embed_dim: int, **kwargs):
+ self.max_batch_size = kwargs.pop("max_batch_size", None)
+ ddconfig = kwargs.pop("ddconfig")
+ decoder_ddconfig = kwargs.pop("decoder_ddconfig", ddconfig)
+ super().__init__(
+ encoder_config={
+ "target": "comfy.ldm.modules.diffusionmodules.model.Encoder",
+ "params": ddconfig,
+ },
+ decoder_config={
+ "target": "comfy.ldm.modules.diffusionmodules.model.Decoder",
+ "params": decoder_ddconfig,
+ },
+ **kwargs,
+ )
+
+ if ddconfig.get("conv3d", False):
+ conv_op = comfy.ops.disable_weight_init.Conv3d
+ else:
+ conv_op = comfy.ops.disable_weight_init.Conv2d
+
+ self.quant_conv = conv_op(
+ (1 + ddconfig["double_z"]) * ddconfig["z_channels"],
+ (1 + ddconfig["double_z"]) * embed_dim,
+ 1,
+ )
+
+ self.post_quant_conv = conv_op(embed_dim, ddconfig["z_channels"], 1)
+ self.embed_dim = embed_dim
+
+ if ddconfig.get("batch_norm_latent", False):
+ self.bn_eps = 1e-4
+ self.bn_momentum = 0.1
+ self.ps = [2, 2]
+ self.bn = torch.nn.BatchNorm2d(math.prod(self.ps) * ddconfig["z_channels"],
+ eps=self.bn_eps,
+ momentum=self.bn_momentum,
+ affine=False,
+ track_running_stats=True,
+ )
+ self.bn.eval()
+ else:
+ self.bn = None
+
+
+ def get_autoencoder_params(self) -> list:
+ params = super().get_autoencoder_params()
+ return params
+
+ def encode(
+ self, x: torch.Tensor, return_reg_log: bool = False
+ ) -> Union[torch.Tensor, Tuple[torch.Tensor, dict]]:
+ if self.max_batch_size is None:
+ z = self.encoder(x)
+ z = self.quant_conv(z)
+ else:
+ N = x.shape[0]
+ bs = self.max_batch_size
+ n_batches = int(math.ceil(N / bs))
+ z = list()
+ for i_batch in range(n_batches):
+ z_batch = self.encoder(x[i_batch * bs : (i_batch + 1) * bs])
+ z_batch = self.quant_conv(z_batch)
+ z.append(z_batch)
+ z = torch.cat(z, 0)
+
+ z, reg_log = self.regularization(z)
+
+ if self.bn is not None:
+ z = rearrange(z,
+ "... c (i pi) (j pj) -> ... (c pi pj) i j",
+ pi=self.ps[0],
+ pj=self.ps[1],
+ )
+
+ z = torch.nn.functional.batch_norm(z,
+ comfy.model_management.cast_to(self.bn.running_mean, dtype=z.dtype, device=z.device),
+ comfy.model_management.cast_to(self.bn.running_var, dtype=z.dtype, device=z.device),
+ momentum=self.bn_momentum,
+ eps=self.bn_eps)
+
+ if return_reg_log:
+ return z, reg_log
+ return z
+
+ def decode(self, z: torch.Tensor, **decoder_kwargs) -> torch.Tensor:
+ if self.bn is not None:
+ s = torch.sqrt(comfy.model_management.cast_to(self.bn.running_var.view(1, -1, 1, 1), dtype=z.dtype, device=z.device) + self.bn_eps)
+ m = comfy.model_management.cast_to(self.bn.running_mean.view(1, -1, 1, 1), dtype=z.dtype, device=z.device)
+ z = z * s + m
+ z = rearrange(
+ z,
+ "... (c pi pj) i j -> ... c (i pi) (j pj)",
+ pi=self.ps[0],
+ pj=self.ps[1],
+ )
+
+ if self.max_batch_size is None:
+ dec = self.post_quant_conv(z)
+ dec = self.decoder(dec, **decoder_kwargs)
+ else:
+ N = z.shape[0]
+ bs = self.max_batch_size
+ n_batches = int(math.ceil(N / bs))
+ dec = list()
+ for i_batch in range(n_batches):
+ dec_batch = self.post_quant_conv(z[i_batch * bs : (i_batch + 1) * bs])
+ dec_batch = self.decoder(dec_batch, **decoder_kwargs)
+ dec.append(dec_batch)
+ dec = torch.cat(dec, 0)
+
+ return dec
+
+
+class AutoencoderKL(AutoencodingEngineLegacy):
+ def __init__(self, **kwargs):
+ if "lossconfig" in kwargs:
+ kwargs["loss_config"] = kwargs.pop("lossconfig")
+ super().__init__(
+ regularizer_config={
+ "target": (
+ "comfy.ldm.models.autoencoder.DiagonalGaussianRegularizer"
+ )
+ },
+ **kwargs,
+ )
diff --git a/ComfyUI/comfy/ldm/modules/__pycache__/attention.cpython-312.pyc b/ComfyUI/comfy/ldm/modules/__pycache__/attention.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..054c81a8980585eff7cdd8b22ba5b21fb4dca83b
Binary files /dev/null and b/ComfyUI/comfy/ldm/modules/__pycache__/attention.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/modules/__pycache__/ema.cpython-312.pyc b/ComfyUI/comfy/ldm/modules/__pycache__/ema.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..0df30824f1460ea0a9e08ced5f63183e31c81fd4
Binary files /dev/null and b/ComfyUI/comfy/ldm/modules/__pycache__/ema.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/modules/__pycache__/sdpose.cpython-312.pyc b/ComfyUI/comfy/ldm/modules/__pycache__/sdpose.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..1648dd0c31c3a0700a73843e2704c60b1b186784
Binary files /dev/null and b/ComfyUI/comfy/ldm/modules/__pycache__/sdpose.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/modules/__pycache__/sub_quadratic_attention.cpython-312.pyc b/ComfyUI/comfy/ldm/modules/__pycache__/sub_quadratic_attention.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..255cfb4de60cd30b7bd10c29342cec044e7ce1c3
Binary files /dev/null and b/ComfyUI/comfy/ldm/modules/__pycache__/sub_quadratic_attention.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/modules/attention.py b/ComfyUI/comfy/ldm/modules/attention.py
new file mode 100644
index 0000000000000000000000000000000000000000..2c549e09545bb3313551f10d19addc147d4250f5
--- /dev/null
+++ b/ComfyUI/comfy/ldm/modules/attention.py
@@ -0,0 +1,1228 @@
+import math
+import sys
+import inspect
+
+import torch
+import torch.nn.functional as F
+from torch import nn, einsum
+from einops import rearrange, repeat
+from typing import Optional, Any, Callable, Union
+import logging
+import functools
+
+from .diffusionmodules.util import AlphaBlender, timestep_embedding
+from .sub_quadratic_attention import efficient_dot_product_attention
+
+from comfy import model_management
+
+if model_management.xformers_enabled():
+ import xformers
+ import xformers.ops
+
+SAGE_ATTENTION_IS_AVAILABLE = False
+SAGE_ATTENTION_SUPPORTS_MASK = False
+try:
+ from sageattention import sageattn
+ SAGE_ATTENTION_IS_AVAILABLE = True
+ SAGE_ATTENTION_SUPPORTS_MASK = "attn_mask" in inspect.signature(sageattn).parameters
+except ImportError as e:
+ if model_management.sage_attention_enabled():
+ if e.name == "sageattention":
+ logging.error(f"\n\nTo use the `--use-sage-attention` feature, the `sageattention` package must be installed first.\ncommand:\n\t{sys.executable} -m pip install sageattention")
+ else:
+ raise e
+ exit(-1)
+
+SAGE_ATTENTION3_IS_AVAILABLE = False
+try:
+ from sageattn3 import sageattn3_blackwell
+ SAGE_ATTENTION3_IS_AVAILABLE = True
+except ImportError:
+ pass
+
+FLASH_ATTENTION_IS_AVAILABLE = False
+try:
+ from flash_attn import flash_attn_func
+ FLASH_ATTENTION_IS_AVAILABLE = True
+except ImportError:
+ if model_management.flash_attention_enabled():
+ logging.error(f"\n\nTo use the `--use-flash-attention` feature, the `flash-attn` package must be installed first.\ncommand:\n\t{sys.executable} -m pip install flash-attn")
+ exit(-1)
+
+REGISTERED_ATTENTION_FUNCTIONS = {}
+def register_attention_function(name: str, func: Callable):
+ # avoid replacing existing functions
+ if name not in REGISTERED_ATTENTION_FUNCTIONS:
+ REGISTERED_ATTENTION_FUNCTIONS[name] = func
+ else:
+ logging.warning(f"Attention function {name} already registered, skipping registration.")
+
+def get_attention_function(name: str, default: Any=...) -> Union[Callable, None]:
+ if name == "optimized":
+ return optimized_attention
+ elif name not in REGISTERED_ATTENTION_FUNCTIONS:
+ if default is ...:
+ raise KeyError(f"Attention function {name} not found.")
+ else:
+ return default
+ return REGISTERED_ATTENTION_FUNCTIONS[name]
+
+from comfy.cli_args import args
+import comfy.ops
+ops = comfy.ops.disable_weight_init
+
+FORCE_UPCAST_ATTENTION_DTYPE = model_management.force_upcast_attention_dtype()
+
+def get_attn_precision(attn_precision, current_dtype):
+ if args.dont_upcast_attention:
+ return None
+
+ if FORCE_UPCAST_ATTENTION_DTYPE is not None and current_dtype in FORCE_UPCAST_ATTENTION_DTYPE:
+ return FORCE_UPCAST_ATTENTION_DTYPE[current_dtype]
+ return attn_precision
+
+def exists(val):
+ return val is not None
+
+
+def default(val, d):
+ if exists(val):
+ return val
+ return d
+
+def _heads_from_dim(tensor, dim_head, name):
+ inner_dim = tensor.shape[-1]
+ if inner_dim % dim_head != 0:
+ raise ValueError(f"{name} inner dimension {inner_dim} is not divisible by head dimension {dim_head}")
+ return inner_dim // dim_head
+
+def _reshape_qkv_to_heads(q, k, v, b, heads, dim_head, enable_gqa=False, expand_kv=True):
+ q = q.unsqueeze(3).reshape(b, -1, heads, dim_head)
+ if enable_gqa:
+ key_heads = _heads_from_dim(k, dim_head, "Key")
+ value_heads = _heads_from_dim(v, dim_head, "Value")
+ else:
+ key_heads = heads
+ value_heads = heads
+ k = k.unsqueeze(3).reshape(b, -1, key_heads, dim_head)
+ v = v.unsqueeze(3).reshape(b, -1, value_heads, dim_head)
+ if enable_gqa and expand_kv:
+ k, v = comfy.ops.repeat_kv_for_gqa(k, v, heads, -2)
+ return q, k, v
+
+
+# feedforward
+class GEGLU(nn.Module):
+ def __init__(self, dim_in, dim_out, dtype=None, device=None, operations=ops):
+ super().__init__()
+ self.proj = operations.Linear(dim_in, dim_out * 2, dtype=dtype, device=device)
+
+ def forward(self, x):
+ x, gate = self.proj(x).chunk(2, dim=-1)
+ return x * F.gelu(gate)
+
+
+class FeedForward(nn.Module):
+ def __init__(self, dim, dim_out=None, mult=4, glu=False, dropout=0., dtype=None, device=None, operations=ops):
+ super().__init__()
+ inner_dim = int(dim * mult)
+ dim_out = default(dim_out, dim)
+ project_in = nn.Sequential(
+ operations.Linear(dim, inner_dim, dtype=dtype, device=device),
+ nn.GELU()
+ ) if not glu else GEGLU(dim, inner_dim, dtype=dtype, device=device, operations=operations)
+
+ self.net = nn.Sequential(
+ project_in,
+ nn.Dropout(dropout),
+ operations.Linear(inner_dim, dim_out, dtype=dtype, device=device)
+ )
+
+ def forward(self, x):
+ return self.net(x)
+
+def Normalize(in_channels, dtype=None, device=None):
+ return torch.nn.GroupNorm(num_groups=32, num_channels=in_channels, eps=1e-6, affine=True, dtype=dtype, device=device)
+
+
+def wrap_attn(func):
+ @functools.wraps(func)
+ def wrapper(*args, **kwargs):
+ remove_attn_wrapper_key = False
+ try:
+ if "_inside_attn_wrapper" not in kwargs:
+ transformer_options = kwargs.get("transformer_options", None)
+ remove_attn_wrapper_key = True
+ kwargs["_inside_attn_wrapper"] = True
+ if transformer_options is not None:
+ if "optimized_attention_override" in transformer_options:
+ return transformer_options["optimized_attention_override"](func, *args, **kwargs)
+ return func(*args, **kwargs)
+ finally:
+ if remove_attn_wrapper_key:
+ del kwargs["_inside_attn_wrapper"]
+ return wrapper
+
+@wrap_attn
+def attention_basic(q, k, v, heads, mask=None, attn_precision=None, skip_reshape=False, skip_output_reshape=False, **kwargs):
+ attn_precision = get_attn_precision(attn_precision, q.dtype)
+
+ if skip_reshape:
+ b, _, _, dim_head = q.shape
+ else:
+ b, _, dim_head = q.shape
+ dim_head //= heads
+
+ scale = kwargs.get("scale", dim_head ** -0.5)
+
+ h = heads
+ if skip_reshape:
+ if kwargs.get("enable_gqa", False):
+ k, v = comfy.ops.repeat_kv_for_gqa(k, v, q.shape[-3], -3)
+ q, k, v = map(
+ lambda t: t.reshape(b * heads, -1, dim_head),
+ (q, k, v),
+ )
+ else:
+ q, k, v = _reshape_qkv_to_heads(q, k, v, b, heads, dim_head, kwargs.get("enable_gqa", False))
+ q, k, v = map(lambda t: t.permute(0, 2, 1, 3).reshape(b * heads, -1, dim_head).contiguous(), (q, k, v))
+
+ # force cast to fp32 to avoid overflowing
+ if attn_precision == torch.float32:
+ sim = einsum('b i d, b j d -> b i j', q.float(), k.float()) * scale
+ else:
+ sim = einsum('b i d, b j d -> b i j', q, k) * scale
+
+ del q, k
+
+ if exists(mask):
+ if mask.dtype == torch.bool:
+ mask = rearrange(mask, 'b ... -> b (...)') #TODO: check if this bool part matches pytorch attention
+ max_neg_value = -torch.finfo(sim.dtype).max
+ mask = repeat(mask, 'b j -> (b h) () j', h=h)
+ sim.masked_fill_(~mask, max_neg_value)
+ else:
+ if len(mask.shape) == 2:
+ bs = 1
+ else:
+ bs = mask.shape[0]
+ mask = mask.reshape(bs, -1, mask.shape[-2], mask.shape[-1]).expand(b, heads, -1, -1).reshape(-1, mask.shape[-2], mask.shape[-1])
+ sim.add_(mask)
+
+ # attention, what we cannot get enough of
+ sim = sim.softmax(dim=-1)
+
+ out = einsum('b i j, b j d -> b i d', sim.to(v.dtype), v)
+
+ if skip_output_reshape:
+ out = (
+ out.unsqueeze(0)
+ .reshape(b, heads, -1, dim_head)
+ )
+ else:
+ out = (
+ out.unsqueeze(0)
+ .reshape(b, heads, -1, dim_head)
+ .permute(0, 2, 1, 3)
+ .reshape(b, -1, heads * dim_head)
+ )
+ return out
+
+@wrap_attn
+def attention_sub_quad(query, key, value, heads, mask=None, attn_precision=None, skip_reshape=False, skip_output_reshape=False, **kwargs):
+ attn_precision = get_attn_precision(attn_precision, query.dtype)
+
+ if skip_reshape:
+ b, _, _, dim_head = query.shape
+ else:
+ b, _, dim_head = query.shape
+ dim_head //= heads
+
+ if "scale" in kwargs:
+ # Pre-scale query to match requested scale (cancels internal 1/sqrt(dim_head))
+ query = query * (kwargs["scale"] * dim_head ** 0.5)
+
+ if skip_reshape:
+ if kwargs.get("enable_gqa", False):
+ key, value = comfy.ops.repeat_kv_for_gqa(key, value, query.shape[-3], -3)
+ query = query.reshape(b * heads, -1, dim_head)
+ value = value.reshape(b * heads, -1, dim_head)
+ key = key.reshape(b * heads, -1, dim_head).movedim(1, 2)
+ else:
+ query, key, value = _reshape_qkv_to_heads(query, key, value, b, heads, dim_head, kwargs.get("enable_gqa", False))
+ query = query.permute(0, 2, 1, 3).reshape(b * heads, -1, dim_head)
+ value = value.permute(0, 2, 1, 3).reshape(b * heads, -1, dim_head)
+ key = key.permute(0, 2, 3, 1).reshape(b * heads, dim_head, -1)
+
+
+ dtype = query.dtype
+ upcast_attention = attn_precision == torch.float32 and query.dtype != torch.float32
+ if upcast_attention:
+ bytes_per_token = torch.finfo(torch.float32).bits//8
+ else:
+ bytes_per_token = torch.finfo(query.dtype).bits//8
+ batch_x_heads, q_tokens, _ = query.shape
+ _, _, k_tokens = key.shape
+
+ mem_free_total, _ = model_management.get_free_memory(query.device, True)
+
+ kv_chunk_size_min = None
+ kv_chunk_size = None
+ query_chunk_size = None
+
+ for x in [4096, 2048, 1024, 512, 256]:
+ count = mem_free_total / (batch_x_heads * bytes_per_token * x * 4.0)
+ if count >= k_tokens:
+ kv_chunk_size = k_tokens
+ query_chunk_size = x
+ break
+
+ if query_chunk_size is None:
+ query_chunk_size = 512
+
+ if mask is not None:
+ if len(mask.shape) == 2:
+ bs = 1
+ else:
+ bs = mask.shape[0]
+ mask = mask.reshape(bs, -1, mask.shape[-2], mask.shape[-1]).expand(b, heads, -1, -1).reshape(-1, mask.shape[-2], mask.shape[-1])
+
+ hidden_states = efficient_dot_product_attention(
+ query,
+ key,
+ value,
+ query_chunk_size=query_chunk_size,
+ kv_chunk_size=kv_chunk_size,
+ kv_chunk_size_min=kv_chunk_size_min,
+ use_checkpoint=False,
+ upcast_attention=upcast_attention,
+ mask=mask,
+ )
+
+ hidden_states = hidden_states.to(dtype)
+ if skip_output_reshape:
+ hidden_states = hidden_states.unflatten(0, (-1, heads))
+ else:
+ hidden_states = hidden_states.unflatten(0, (-1, heads)).transpose(1,2).flatten(start_dim=2)
+ return hidden_states
+
+@wrap_attn
+def attention_split(q, k, v, heads, mask=None, attn_precision=None, skip_reshape=False, skip_output_reshape=False, **kwargs):
+ attn_precision = get_attn_precision(attn_precision, q.dtype)
+
+ if skip_reshape:
+ b, _, _, dim_head = q.shape
+ else:
+ b, _, dim_head = q.shape
+ dim_head //= heads
+
+ scale = kwargs.get("scale", dim_head ** -0.5)
+
+ if skip_reshape:
+ if kwargs.get("enable_gqa", False):
+ k, v = comfy.ops.repeat_kv_for_gqa(k, v, q.shape[-3], -3)
+ q, k, v = map(
+ lambda t: t.reshape(b * heads, -1, dim_head),
+ (q, k, v),
+ )
+ else:
+ q, k, v = _reshape_qkv_to_heads(q, k, v, b, heads, dim_head, kwargs.get("enable_gqa", False))
+ q, k, v = map(lambda t: t.permute(0, 2, 1, 3).reshape(b * heads, -1, dim_head).contiguous(), (q, k, v))
+
+ r1 = torch.zeros(q.shape[0], q.shape[1], v.shape[2], device=q.device, dtype=q.dtype)
+
+ mem_free_total = model_management.get_free_memory(q.device)
+
+ if attn_precision == torch.float32:
+ element_size = 4
+ upcast = True
+ else:
+ element_size = q.element_size()
+ upcast = False
+
+ gb = 1024 ** 3
+ tensor_size = q.shape[0] * q.shape[1] * k.shape[1] * element_size
+ modifier = 3
+ mem_required = tensor_size * modifier
+ steps = 1
+
+
+ if mem_required > mem_free_total:
+ steps = 2**(math.ceil(math.log(mem_required / mem_free_total, 2)))
+ # print(f"Expected tensor size:{tensor_size/gb:0.1f}GB, cuda free:{mem_free_cuda/gb:0.1f}GB "
+ # f"torch free:{mem_free_torch/gb:0.1f} total:{mem_free_total/gb:0.1f} steps:{steps}")
+
+ if steps > 64:
+ max_res = math.floor(math.sqrt(math.sqrt(mem_free_total / 2.5)) / 8) * 64
+ raise RuntimeError(f'Not enough memory, use lower resolution (max approx. {max_res}x{max_res}). '
+ f'Need: {mem_required/64/gb:0.1f}GB free, Have:{mem_free_total/gb:0.1f}GB free')
+
+ if mask is not None:
+ if len(mask.shape) == 2:
+ bs = 1
+ else:
+ bs = mask.shape[0]
+ mask = mask.reshape(bs, -1, mask.shape[-2], mask.shape[-1]).expand(b, heads, -1, -1).reshape(-1, mask.shape[-2], mask.shape[-1])
+
+ # print("steps", steps, mem_required, mem_free_total, modifier, q.element_size(), tensor_size)
+ first_op_done = False
+ cleared_cache = False
+ while True:
+ try:
+ slice_size = q.shape[1] // steps if (q.shape[1] % steps) == 0 else q.shape[1]
+ for i in range(0, q.shape[1], slice_size):
+ end = i + slice_size
+ if upcast:
+ with torch.autocast(enabled=False, device_type = 'cuda'):
+ s1 = einsum('b i d, b j d -> b i j', q[:, i:end].float(), k.float()) * scale
+ else:
+ s1 = einsum('b i d, b j d -> b i j', q[:, i:end], k) * scale
+
+ if mask is not None:
+ if len(mask.shape) == 2:
+ s1 += mask[i:end]
+ else:
+ if mask.shape[1] == 1:
+ s1 += mask
+ else:
+ s1 += mask[:, i:end]
+
+ s2 = s1.softmax(dim=-1).to(v.dtype)
+ del s1
+ first_op_done = True
+
+ r1[:, i:end] = einsum('b i j, b j d -> b i d', s2, v)
+ del s2
+ break
+ except Exception as e:
+ model_management.raise_non_oom(e)
+ if first_op_done == False:
+ model_management.soft_empty_cache(True)
+ if cleared_cache == False:
+ cleared_cache = True
+ logging.warning("out of memory error, emptying cache and trying again")
+ continue
+ steps *= 2
+ if steps > 64:
+ raise e
+ logging.warning("out of memory error, increasing steps and trying again {}".format(steps))
+ else:
+ raise e
+
+ del q, k, v
+
+ if skip_output_reshape:
+ r1 = (
+ r1.unsqueeze(0)
+ .reshape(b, heads, -1, dim_head)
+ )
+ else:
+ r1 = (
+ r1.unsqueeze(0)
+ .reshape(b, heads, -1, dim_head)
+ .permute(0, 2, 1, 3)
+ .reshape(b, -1, heads * dim_head)
+ )
+ return r1
+
+BROKEN_XFORMERS = False
+try:
+ x_vers = xformers.__version__
+ # XFormers bug confirmed on all versions from 0.0.21 to 0.0.26 (q with bs bigger than 65535 gives CUDA error)
+ BROKEN_XFORMERS = x_vers.startswith("0.0.2") and not x_vers.startswith("0.0.20")
+except:
+ pass
+
+@wrap_attn
+def attention_xformers(q, k, v, heads, mask=None, attn_precision=None, skip_reshape=False, skip_output_reshape=False, **kwargs):
+ b = q.shape[0]
+ dim_head = q.shape[-1]
+ # check to make sure xformers isn't broken
+ disabled_xformers = False
+
+ if BROKEN_XFORMERS:
+ if b * heads > 65535:
+ disabled_xformers = True
+
+ if not disabled_xformers:
+ if torch.jit.is_tracing() or torch.jit.is_scripting():
+ disabled_xformers = True
+
+ if disabled_xformers:
+ return attention_pytorch(q, k, v, heads, mask, skip_reshape=skip_reshape, skip_output_reshape=skip_output_reshape, **kwargs)
+
+ if skip_reshape:
+ # b h k d -> b k h d
+ q, k, v = map(
+ lambda t: t.permute(0, 2, 1, 3),
+ (q, k, v),
+ )
+ if kwargs.get("enable_gqa", False):
+ k, v = comfy.ops.repeat_kv_for_gqa(k, v, q.shape[-2], -2)
+ # actually do the reshaping
+ else:
+ dim_head //= heads
+ q, k, v = _reshape_qkv_to_heads(q, k, v, b, heads, dim_head, kwargs.get("enable_gqa", False))
+
+ if mask is not None:
+ # add a singleton batch dimension
+ if mask.ndim == 2:
+ mask = mask.unsqueeze(0)
+ # add a singleton heads dimension
+ if mask.ndim == 3:
+ mask = mask.unsqueeze(1)
+ # pad to a multiple of 8
+ pad = 8 - mask.shape[-1] % 8
+ # the xformers docs says that it's allowed to have a mask of shape (1, Nq, Nk)
+ # but when using separated heads, the shape has to be (B, H, Nq, Nk)
+ # in flux, this matrix ends up being over 1GB
+ # here, we create a mask with the same batch/head size as the input mask (potentially singleton or full)
+ mask_out = torch.empty([mask.shape[0], mask.shape[1], q.shape[1], mask.shape[-1] + pad], dtype=q.dtype, device=q.device)
+
+ mask_out[..., :mask.shape[-1]] = mask
+ # doesn't this remove the padding again??
+ mask = mask_out[..., :mask.shape[-1]]
+ mask = mask.expand(b, heads, -1, -1)
+
+ out = xformers.ops.memory_efficient_attention(q, k, v, attn_bias=mask, scale=kwargs.get("scale", None))
+
+ if skip_output_reshape:
+ out = out.permute(0, 2, 1, 3)
+ else:
+ out = (
+ out.reshape(b, -1, heads * dim_head)
+ )
+
+ return out
+
+if model_management.is_nvidia(): #pytorch 2.3 and up seem to have this issue.
+ SDP_BATCH_LIMIT = 2**15
+else:
+ #TODO: other GPUs ?
+ SDP_BATCH_LIMIT = 2**31
+
+@wrap_attn
+def attention_pytorch(q, k, v, heads, mask=None, attn_precision=None, skip_reshape=False, skip_output_reshape=False, **kwargs):
+ if skip_reshape:
+ b, _, _, dim_head = q.shape
+ else:
+ b, _, dim_head = q.shape
+ dim_head //= heads
+ q, k, v = _reshape_qkv_to_heads(q, k, v, b, heads, dim_head, kwargs.get("enable_gqa", False), expand_kv=False)
+ q, k, v = map(lambda t: t.transpose(1, 2), (q, k, v))
+
+ if mask is not None:
+ # add a batch dimension if there isn't already one
+ if mask.ndim == 2:
+ mask = mask.unsqueeze(0)
+ # add a heads dimension if there isn't already one
+ if mask.ndim == 3:
+ mask = mask.unsqueeze(1)
+
+ sdpa_keys = ("scale", "enable_gqa")
+ sdpa_extra = {k: v for k, v in kwargs.items() if k in sdpa_keys}
+
+ if SDP_BATCH_LIMIT >= b:
+ out = comfy.ops.scaled_dot_product_attention(q, k, v, attn_mask=mask, dropout_p=0.0, is_causal=False, **sdpa_extra)
+ if not skip_output_reshape:
+ out = (
+ out.transpose(1, 2).reshape(b, -1, heads * dim_head)
+ )
+ else:
+ out = torch.empty((b, q.shape[2], heads * dim_head), dtype=q.dtype, layout=q.layout, device=q.device)
+ for i in range(0, b, SDP_BATCH_LIMIT):
+ m = mask
+ if mask is not None:
+ if mask.shape[0] > 1:
+ m = mask[i : i + SDP_BATCH_LIMIT]
+
+ out[i : i + SDP_BATCH_LIMIT] = comfy.ops.scaled_dot_product_attention(
+ q[i : i + SDP_BATCH_LIMIT],
+ k[i : i + SDP_BATCH_LIMIT],
+ v[i : i + SDP_BATCH_LIMIT],
+ attn_mask=m,
+ dropout_p=0.0, is_causal=False, **sdpa_extra
+ ).transpose(1, 2).reshape(-1, q.shape[2], heads * dim_head)
+ return out
+
+@wrap_attn
+def attention_sage(q, k, v, heads, mask=None, attn_precision=None, skip_reshape=False, skip_output_reshape=False, **kwargs):
+ if kwargs.get("low_precision_attention", True) is False or (mask is not None and not SAGE_ATTENTION_SUPPORTS_MASK):
+ return attention_pytorch(q, k, v, heads, mask=mask, skip_reshape=skip_reshape, skip_output_reshape=skip_output_reshape, **kwargs)
+
+ exception_fallback = False
+ if skip_reshape:
+ b, _, _, dim_head = q.shape
+ tensor_layout = "HND"
+ if kwargs.get("enable_gqa", False):
+ k, v = comfy.ops.repeat_kv_for_gqa(k, v, q.shape[-3], -3)
+ else:
+ b, _, dim_head = q.shape
+ dim_head //= heads
+ q, k, v = _reshape_qkv_to_heads(q, k, v, b, heads, dim_head, kwargs.get("enable_gqa", False))
+ tensor_layout = "NHD"
+
+ if mask is not None:
+ # add a batch dimension if there isn't already one
+ if mask.ndim == 2:
+ mask = mask.unsqueeze(0)
+ # add a heads dimension if there isn't already one
+ if mask.ndim == 3:
+ mask = mask.unsqueeze(1)
+
+ sage_kwargs = {"is_causal": False, "tensor_layout": tensor_layout, "sm_scale": kwargs.get("scale", None), "smooth_k": False}
+ if mask is not None:
+ sage_kwargs["attn_mask"] = mask
+
+ try:
+ out = sageattn(q, k, v, **sage_kwargs)
+ except Exception as e:
+ logging.error("Error running sage attention: {}, using pytorch attention instead.".format(e))
+ exception_fallback = True
+ if exception_fallback:
+ if tensor_layout == "NHD":
+ q, k, v = map(
+ lambda t: t.transpose(1, 2),
+ (q, k, v),
+ )
+ return attention_pytorch(q, k, v, heads, mask=mask, skip_reshape=True, skip_output_reshape=skip_output_reshape, **kwargs)
+
+ if tensor_layout == "HND":
+ if not skip_output_reshape:
+ out = (
+ out.transpose(1, 2).reshape(b, -1, heads * dim_head)
+ )
+ else:
+ if skip_output_reshape:
+ out = out.transpose(1, 2)
+ else:
+ out = out.reshape(b, -1, heads * dim_head)
+ return out
+
+@wrap_attn
+def attention3_sage(q, k, v, heads, mask=None, attn_precision=None, skip_reshape=False, skip_output_reshape=False, **kwargs):
+ exception_fallback = False
+ if (q.device.type != "cuda" or
+ q.dtype not in (torch.float16, torch.bfloat16) or
+ mask is not None):
+ return attention_pytorch(
+ q, k, v, heads,
+ mask=mask,
+ attn_precision=attn_precision,
+ skip_reshape=skip_reshape,
+ skip_output_reshape=skip_output_reshape,
+ **kwargs
+ )
+
+ if skip_reshape:
+ B, H, L, D = q.shape
+ if H != heads:
+ return attention_pytorch(
+ q, k, v, heads,
+ mask=mask,
+ attn_precision=attn_precision,
+ skip_reshape=True,
+ skip_output_reshape=skip_output_reshape,
+ **kwargs
+ )
+ N = q.shape[2]
+ dim_head = D
+ else:
+ B, N, inner_dim = q.shape
+ if inner_dim % heads != 0:
+ return attention_pytorch(
+ q, k, v, heads,
+ mask=mask,
+ attn_precision=attn_precision,
+ skip_reshape=False,
+ skip_output_reshape=skip_output_reshape,
+ **kwargs
+ )
+ dim_head = inner_dim // heads
+
+ if dim_head >= 256 or N <= 1024:
+ return attention_pytorch(
+ q, k, v, heads,
+ mask=mask,
+ attn_precision=attn_precision,
+ skip_reshape=skip_reshape,
+ skip_output_reshape=skip_output_reshape,
+ **kwargs
+ )
+
+ if skip_reshape:
+ q_s = q
+ if kwargs.get("enable_gqa", False):
+ k_s, v_s = comfy.ops.repeat_kv_for_gqa(k, v, H, -3)
+ else:
+ k_s, v_s = k, v
+ else:
+ q_s, k_s, v_s = _reshape_qkv_to_heads(q, k, v, B, heads, dim_head, kwargs.get("enable_gqa", False))
+ q_s, k_s, v_s = map(lambda t: t.permute(0, 2, 1, 3).contiguous(), (q_s, k_s, v_s))
+ B, H, L, D = q_s.shape
+
+ try:
+ out = sageattn3_blackwell(q_s, k_s, v_s, is_causal=False)
+ except Exception as e:
+ exception_fallback = True
+ logging.error("Error running SageAttention3: %s, falling back to pytorch attention.", e)
+
+ if exception_fallback:
+ if not skip_reshape:
+ del q_s, k_s, v_s
+ return attention_pytorch(
+ q, k, v, heads,
+ mask=mask,
+ attn_precision=attn_precision,
+ skip_reshape=skip_reshape,
+ skip_output_reshape=skip_output_reshape,
+ **kwargs
+ )
+
+ if skip_reshape:
+ if not skip_output_reshape:
+ out = out.permute(0, 2, 1, 3).reshape(B, L, H * D)
+ else:
+ if skip_output_reshape:
+ pass
+ else:
+ out = out.permute(0, 2, 1, 3).reshape(B, L, H * D)
+
+ return out
+
+try:
+ @torch.library.custom_op("comfy::flash_attn", mutates_args=())
+ def flash_attn_wrapper(q: torch.Tensor, k: torch.Tensor, v: torch.Tensor,
+ dropout_p: float = 0.0, causal: bool = False, softmax_scale: float = -1.0) -> torch.Tensor:
+ softmax_scale_arg = None if softmax_scale == -1.0 else softmax_scale
+ return flash_attn_func(q, k, v, dropout_p=dropout_p, causal=causal, softmax_scale=softmax_scale_arg)
+
+
+ @flash_attn_wrapper.register_fake
+ def flash_attn_fake(q, k, v, dropout_p=0.0, causal=False, softmax_scale=-1.0):
+ # Output shape is the same as q
+ return q.new_empty(q.shape)
+except AttributeError as error:
+ FLASH_ATTN_ERROR = error
+
+ def flash_attn_wrapper(q: torch.Tensor, k: torch.Tensor, v: torch.Tensor,
+ dropout_p: float = 0.0, causal: bool = False, softmax_scale: float = -1.0) -> torch.Tensor:
+ assert False, f"Could not define flash_attn_wrapper: {FLASH_ATTN_ERROR}"
+
+@wrap_attn
+def attention_flash(q, k, v, heads, mask=None, attn_precision=None, skip_reshape=False, skip_output_reshape=False, **kwargs):
+ if skip_reshape:
+ b, _, _, dim_head = q.shape
+ else:
+ b, _, dim_head = q.shape
+ dim_head //= heads
+ q, k, v = _reshape_qkv_to_heads(q, k, v, b, heads, dim_head, kwargs.get("enable_gqa", False), expand_kv=False)
+ q, k, v = map(lambda t: t.transpose(1, 2), (q, k, v))
+
+ if mask is not None:
+ # add a batch dimension if there isn't already one
+ if mask.ndim == 2:
+ mask = mask.unsqueeze(0)
+ # add a heads dimension if there isn't already one
+ if mask.ndim == 3:
+ mask = mask.unsqueeze(1)
+
+ try:
+ if mask is not None:
+ raise RuntimeError("Mask must not be set for Flash attention")
+ out = flash_attn_wrapper(
+ q.transpose(1, 2),
+ k.transpose(1, 2),
+ v.transpose(1, 2),
+ dropout_p=0.0,
+ causal=False,
+ softmax_scale=kwargs.get("scale", -1.0),
+ ).transpose(1, 2)
+ except Exception as e:
+ logging.warning(f"Flash Attention failed, using default SDPA: {e}")
+ sdpa_extra = {}
+ if kwargs.get("enable_gqa", False):
+ sdpa_extra["enable_gqa"] = True
+ if "scale" in kwargs:
+ sdpa_extra["scale"] = kwargs["scale"]
+ out = torch.nn.functional.scaled_dot_product_attention(q, k, v, attn_mask=mask, dropout_p=0.0, is_causal=False, **sdpa_extra)
+ if not skip_output_reshape:
+ out = (
+ out.transpose(1, 2).reshape(b, -1, heads * dim_head)
+ )
+ return out
+
+
+optimized_attention = attention_basic
+
+if model_management.sage_attention_enabled():
+ logging.info("Using sage attention")
+ optimized_attention = attention_sage
+elif model_management.flash_attention_enabled():
+ logging.info("Using Flash Attention")
+ optimized_attention = attention_flash
+elif model_management.xformers_enabled():
+ logging.info("Using xformers attention")
+ optimized_attention = attention_xformers
+elif model_management.pytorch_attention_enabled():
+ logging.info("Using pytorch attention")
+ optimized_attention = attention_pytorch
+else:
+ if args.use_split_cross_attention:
+ logging.info("Using split optimization for attention")
+ optimized_attention = attention_split
+ else:
+ logging.info("Using sub quadratic optimization for attention, if you have memory or speed issues try using: --use-split-cross-attention")
+ optimized_attention = attention_sub_quad
+
+optimized_attention_masked = optimized_attention
+
+
+# register core-supported attention functions
+if SAGE_ATTENTION_IS_AVAILABLE:
+ register_attention_function("sage", attention_sage)
+if SAGE_ATTENTION3_IS_AVAILABLE:
+ register_attention_function("sage3", attention3_sage)
+if FLASH_ATTENTION_IS_AVAILABLE:
+ register_attention_function("flash", attention_flash)
+if model_management.xformers_enabled():
+ register_attention_function("xformers", attention_xformers)
+register_attention_function("pytorch", attention_pytorch)
+register_attention_function("sub_quad", attention_sub_quad)
+register_attention_function("split", attention_split)
+
+
+def optimized_attention_for_device(device, mask=False, small_input=False):
+ if small_input:
+ if model_management.pytorch_attention_enabled():
+ return attention_pytorch #TODO: need to confirm but this is probably slightly faster for small inputs in all cases
+ else:
+ return attention_basic
+
+ if device == torch.device("cpu"):
+ return attention_sub_quad
+
+ if mask:
+ return optimized_attention_masked
+
+ return optimized_attention
+
+
+class CrossAttention(nn.Module):
+ def __init__(self, query_dim, context_dim=None, heads=8, dim_head=64, dropout=0., attn_precision=None, dtype=None, device=None, operations=ops):
+ super().__init__()
+ inner_dim = dim_head * heads
+ context_dim = default(context_dim, query_dim)
+ self.attn_precision = attn_precision
+
+ self.heads = heads
+ self.dim_head = dim_head
+
+ self.to_q = operations.Linear(query_dim, inner_dim, bias=False, dtype=dtype, device=device)
+ self.to_k = operations.Linear(context_dim, inner_dim, bias=False, dtype=dtype, device=device)
+ self.to_v = operations.Linear(context_dim, inner_dim, bias=False, dtype=dtype, device=device)
+
+ self.to_out = nn.Sequential(operations.Linear(inner_dim, query_dim, dtype=dtype, device=device), nn.Dropout(dropout))
+
+ def forward(self, x, context=None, value=None, mask=None, transformer_options={}):
+ q = self.to_q(x)
+ context = default(context, x)
+ k = self.to_k(context)
+ if value is not None:
+ v = self.to_v(value)
+ del value
+ else:
+ v = self.to_v(context)
+
+ if mask is None:
+ out = optimized_attention(q, k, v, self.heads, attn_precision=self.attn_precision, transformer_options=transformer_options)
+ else:
+ out = optimized_attention_masked(q, k, v, self.heads, mask, attn_precision=self.attn_precision, transformer_options=transformer_options)
+ return self.to_out(out)
+
+
+class BasicTransformerBlock(nn.Module):
+ def __init__(self, dim, n_heads, d_head, dropout=0., context_dim=None, gated_ff=True, checkpoint=True, ff_in=False, inner_dim=None,
+ disable_self_attn=False, disable_temporal_crossattention=False, switch_temporal_ca_to_sa=False, attn_precision=None, dtype=None, device=None, operations=ops):
+ super().__init__()
+
+ self.ff_in = ff_in or inner_dim is not None
+ if inner_dim is None:
+ inner_dim = dim
+
+ self.is_res = inner_dim == dim
+ self.attn_precision = attn_precision
+
+ if self.ff_in:
+ self.norm_in = operations.LayerNorm(dim, dtype=dtype, device=device)
+ self.ff_in = FeedForward(dim, dim_out=inner_dim, dropout=dropout, glu=gated_ff, dtype=dtype, device=device, operations=operations)
+
+ self.disable_self_attn = disable_self_attn
+ self.attn1 = CrossAttention(query_dim=inner_dim, heads=n_heads, dim_head=d_head, dropout=dropout,
+ context_dim=context_dim if self.disable_self_attn else None, attn_precision=self.attn_precision, dtype=dtype, device=device, operations=operations) # is a self-attention if not self.disable_self_attn
+ self.ff = FeedForward(inner_dim, dim_out=dim, dropout=dropout, glu=gated_ff, dtype=dtype, device=device, operations=operations)
+
+ if disable_temporal_crossattention:
+ if switch_temporal_ca_to_sa:
+ raise ValueError
+ else:
+ self.attn2 = None
+ else:
+ context_dim_attn2 = None
+ if not switch_temporal_ca_to_sa:
+ context_dim_attn2 = context_dim
+
+ self.attn2 = CrossAttention(query_dim=inner_dim, context_dim=context_dim_attn2,
+ heads=n_heads, dim_head=d_head, dropout=dropout, attn_precision=self.attn_precision, dtype=dtype, device=device, operations=operations) # is self-attn if context is none
+ self.norm2 = operations.LayerNorm(inner_dim, dtype=dtype, device=device)
+
+ self.norm1 = operations.LayerNorm(inner_dim, dtype=dtype, device=device)
+ self.norm3 = operations.LayerNorm(inner_dim, dtype=dtype, device=device)
+ self.n_heads = n_heads
+ self.d_head = d_head
+ self.switch_temporal_ca_to_sa = switch_temporal_ca_to_sa
+
+ def forward(self, x, context=None, transformer_options={}):
+ extra_options = {}
+ block = transformer_options.get("block", None)
+ block_index = transformer_options.get("block_index", 0)
+ transformer_patches = {}
+ transformer_patches_replace = {}
+
+ for k in transformer_options:
+ if k == "patches":
+ transformer_patches = transformer_options[k]
+ elif k == "patches_replace":
+ transformer_patches_replace = transformer_options[k]
+ else:
+ extra_options[k] = transformer_options[k]
+
+ extra_options["n_heads"] = self.n_heads
+ extra_options["dim_head"] = self.d_head
+ extra_options["attn_precision"] = self.attn_precision
+
+ if self.ff_in:
+ x_skip = x
+ x = self.ff_in(self.norm_in(x))
+ if self.is_res:
+ x += x_skip
+
+ n = self.norm1(x)
+ if self.disable_self_attn:
+ context_attn1 = context
+ else:
+ context_attn1 = None
+ value_attn1 = None
+
+ if "attn1_patch" in transformer_patches:
+ patch = transformer_patches["attn1_patch"]
+ if context_attn1 is None:
+ context_attn1 = n
+ value_attn1 = context_attn1
+ for p in patch:
+ n, context_attn1, value_attn1 = p(n, context_attn1, value_attn1, extra_options)
+
+ if block is not None:
+ transformer_block = (block[0], block[1], block_index)
+ else:
+ transformer_block = None
+ attn1_replace_patch = transformer_patches_replace.get("attn1", {})
+ block_attn1 = transformer_block
+ if block_attn1 not in attn1_replace_patch:
+ block_attn1 = block
+
+ if block_attn1 in attn1_replace_patch:
+ if context_attn1 is None:
+ context_attn1 = n
+ value_attn1 = n
+ n = self.attn1.to_q(n)
+ context_attn1 = self.attn1.to_k(context_attn1)
+ value_attn1 = self.attn1.to_v(value_attn1)
+ n = attn1_replace_patch[block_attn1](n, context_attn1, value_attn1, extra_options)
+ n = self.attn1.to_out(n)
+ else:
+ n = self.attn1(n, context=context_attn1, value=value_attn1, transformer_options=transformer_options)
+
+ if "attn1_output_patch" in transformer_patches:
+ patch = transformer_patches["attn1_output_patch"]
+ for p in patch:
+ n = p(n, extra_options)
+
+ x = n + x
+ if "middle_patch" in transformer_patches:
+ patch = transformer_patches["middle_patch"]
+ for p in patch:
+ x = p(x, extra_options)
+
+ if self.attn2 is not None:
+ n = self.norm2(x)
+ if self.switch_temporal_ca_to_sa:
+ context_attn2 = n
+ else:
+ context_attn2 = context
+ value_attn2 = None
+ if "attn2_patch" in transformer_patches:
+ patch = transformer_patches["attn2_patch"]
+ value_attn2 = context_attn2
+ for p in patch:
+ n, context_attn2, value_attn2 = p(n, context_attn2, value_attn2, extra_options)
+
+ attn2_replace_patch = transformer_patches_replace.get("attn2", {})
+ block_attn2 = transformer_block
+ if block_attn2 not in attn2_replace_patch:
+ block_attn2 = block
+
+ if block_attn2 in attn2_replace_patch:
+ if value_attn2 is None:
+ value_attn2 = context_attn2
+ n = self.attn2.to_q(n)
+ context_attn2 = self.attn2.to_k(context_attn2)
+ value_attn2 = self.attn2.to_v(value_attn2)
+ n = attn2_replace_patch[block_attn2](n, context_attn2, value_attn2, extra_options)
+ n = self.attn2.to_out(n)
+ else:
+ n = self.attn2(n, context=context_attn2, value=value_attn2, transformer_options=transformer_options)
+
+ if "attn2_output_patch" in transformer_patches:
+ patch = transformer_patches["attn2_output_patch"]
+ for p in patch:
+ n = p(n, extra_options)
+
+ x = n + x
+ if self.is_res:
+ x_skip = x
+ x = self.ff(self.norm3(x))
+ if self.is_res:
+ x = x_skip + x
+
+ return x
+
+
+class SpatialTransformer(nn.Module):
+ """
+ Transformer block for image-like data.
+ First, project the input (aka embedding)
+ and reshape to b, t, d.
+ Then apply standard transformer action.
+ Finally, reshape to image
+ NEW: use_linear for more efficiency instead of the 1x1 convs
+ """
+ def __init__(self, in_channels, n_heads, d_head,
+ depth=1, dropout=0., context_dim=None,
+ disable_self_attn=False, use_linear=False,
+ use_checkpoint=True, attn_precision=None, dtype=None, device=None, operations=ops):
+ super().__init__()
+ if exists(context_dim) and not isinstance(context_dim, list):
+ context_dim = [context_dim] * depth
+ self.in_channels = in_channels
+ inner_dim = n_heads * d_head
+ self.norm = operations.GroupNorm(num_groups=32, num_channels=in_channels, eps=1e-6, affine=True, dtype=dtype, device=device)
+ if not use_linear:
+ self.proj_in = operations.Conv2d(in_channels,
+ inner_dim,
+ kernel_size=1,
+ stride=1,
+ padding=0, dtype=dtype, device=device)
+ else:
+ self.proj_in = operations.Linear(in_channels, inner_dim, dtype=dtype, device=device)
+
+ self.transformer_blocks = nn.ModuleList(
+ [BasicTransformerBlock(inner_dim, n_heads, d_head, dropout=dropout, context_dim=context_dim[d],
+ disable_self_attn=disable_self_attn, checkpoint=use_checkpoint, attn_precision=attn_precision, dtype=dtype, device=device, operations=operations)
+ for d in range(depth)]
+ )
+ if not use_linear:
+ self.proj_out = operations.Conv2d(inner_dim,in_channels,
+ kernel_size=1,
+ stride=1,
+ padding=0, dtype=dtype, device=device)
+ else:
+ self.proj_out = operations.Linear(in_channels, inner_dim, dtype=dtype, device=device)
+ self.use_linear = use_linear
+
+ def forward(self, x, context=None, transformer_options={}):
+ # note: if no context is given, cross-attention defaults to self-attention
+ if not isinstance(context, list):
+ context = [context] * len(self.transformer_blocks)
+ b, c, h, w = x.shape
+ transformer_options["activations_shape"] = list(x.shape)
+ x_in = x
+ x = self.norm(x)
+ if not self.use_linear:
+ x = self.proj_in(x)
+ x = x.movedim(1, 3).flatten(1, 2).contiguous()
+ if self.use_linear:
+ x = self.proj_in(x)
+ for i, block in enumerate(self.transformer_blocks):
+ transformer_options["block_index"] = i
+ x = block(x, context=context[i], transformer_options=transformer_options)
+ if self.use_linear:
+ x = self.proj_out(x)
+ x = x.reshape(x.shape[0], h, w, x.shape[-1]).movedim(3, 1).contiguous()
+ if not self.use_linear:
+ x = self.proj_out(x)
+ return x + x_in
+
+
+class SpatialVideoTransformer(SpatialTransformer):
+ def __init__(
+ self,
+ in_channels,
+ n_heads,
+ d_head,
+ depth=1,
+ dropout=0.0,
+ use_linear=False,
+ context_dim=None,
+ use_spatial_context=False,
+ timesteps=None,
+ merge_strategy: str = "fixed",
+ merge_factor: float = 0.5,
+ time_context_dim=None,
+ ff_in=False,
+ checkpoint=False,
+ time_depth=1,
+ disable_self_attn=False,
+ disable_temporal_crossattention=False,
+ max_time_embed_period: int = 10000,
+ attn_precision=None,
+ dtype=None, device=None, operations=ops
+ ):
+ super().__init__(
+ in_channels,
+ n_heads,
+ d_head,
+ depth=depth,
+ dropout=dropout,
+ use_checkpoint=checkpoint,
+ context_dim=context_dim,
+ use_linear=use_linear,
+ disable_self_attn=disable_self_attn,
+ attn_precision=attn_precision,
+ dtype=dtype, device=device, operations=operations
+ )
+ self.time_depth = time_depth
+ self.depth = depth
+ self.max_time_embed_period = max_time_embed_period
+
+ time_mix_d_head = d_head
+ n_time_mix_heads = n_heads
+
+ time_mix_inner_dim = int(time_mix_d_head * n_time_mix_heads)
+
+ inner_dim = n_heads * d_head
+ if use_spatial_context:
+ time_context_dim = context_dim
+
+ self.time_stack = nn.ModuleList(
+ [
+ BasicTransformerBlock(
+ inner_dim,
+ n_time_mix_heads,
+ time_mix_d_head,
+ dropout=dropout,
+ context_dim=time_context_dim,
+ # timesteps=timesteps,
+ checkpoint=checkpoint,
+ ff_in=ff_in,
+ inner_dim=time_mix_inner_dim,
+ disable_self_attn=disable_self_attn,
+ disable_temporal_crossattention=disable_temporal_crossattention,
+ attn_precision=attn_precision,
+ dtype=dtype, device=device, operations=operations
+ )
+ for _ in range(self.depth)
+ ]
+ )
+
+ assert len(self.time_stack) == len(self.transformer_blocks)
+
+ self.use_spatial_context = use_spatial_context
+ self.in_channels = in_channels
+
+ time_embed_dim = self.in_channels * 4
+ self.time_pos_embed = nn.Sequential(
+ operations.Linear(self.in_channels, time_embed_dim, dtype=dtype, device=device),
+ nn.SiLU(),
+ operations.Linear(time_embed_dim, self.in_channels, dtype=dtype, device=device),
+ )
+
+ self.time_mixer = AlphaBlender(
+ alpha=merge_factor, merge_strategy=merge_strategy
+ )
+
+ def forward(
+ self,
+ x: torch.Tensor,
+ context: Optional[torch.Tensor] = None,
+ time_context: Optional[torch.Tensor] = None,
+ timesteps: Optional[int] = None,
+ image_only_indicator: Optional[torch.Tensor] = None,
+ transformer_options={}
+ ) -> torch.Tensor:
+ _, _, h, w = x.shape
+ transformer_options["activations_shape"] = list(x.shape)
+ x_in = x
+ spatial_context = None
+ if exists(context):
+ spatial_context = context
+
+ if self.use_spatial_context:
+ assert (
+ context.ndim == 3
+ ), f"n dims of spatial context should be 3 but are {context.ndim}"
+
+ if time_context is None:
+ time_context = context
+ time_context_first_timestep = time_context[::timesteps]
+ time_context = repeat(
+ time_context_first_timestep, "b ... -> (b n) ...", n=h * w
+ )
+ elif time_context is not None and not self.use_spatial_context:
+ time_context = repeat(time_context, "b ... -> (b n) ...", n=h * w)
+ if time_context.ndim == 2:
+ time_context = rearrange(time_context, "b c -> b 1 c")
+
+ x = self.norm(x)
+ if not self.use_linear:
+ x = self.proj_in(x)
+ x = rearrange(x, "b c h w -> b (h w) c")
+ if self.use_linear:
+ x = self.proj_in(x)
+
+ num_frames = torch.arange(timesteps, device=x.device)
+ num_frames = repeat(num_frames, "t -> b t", b=x.shape[0] // timesteps)
+ num_frames = rearrange(num_frames, "b t -> (b t)")
+ t_emb = timestep_embedding(num_frames, self.in_channels, repeat_only=False, max_period=self.max_time_embed_period).to(x.dtype)
+ emb = self.time_pos_embed(t_emb)
+ emb = emb[:, None, :]
+
+ for it_, (block, mix_block) in enumerate(
+ zip(self.transformer_blocks, self.time_stack)
+ ):
+ transformer_options["block_index"] = it_
+ x = block(
+ x,
+ context=spatial_context,
+ transformer_options=transformer_options,
+ )
+
+ x_mix = x
+ x_mix = x_mix + emb
+
+ B, S, C = x_mix.shape
+ x_mix = rearrange(x_mix, "(b t) s c -> (b s) t c", t=timesteps)
+ x_mix = mix_block(x_mix, context=time_context, transformer_options=transformer_options)
+ x_mix = rearrange(
+ x_mix, "(b s) t c -> (b t) s c", s=S, b=B // timesteps, c=C, t=timesteps
+ )
+
+ x = self.time_mixer(x_spatial=x, x_temporal=x_mix, image_only_indicator=image_only_indicator)
+
+ if self.use_linear:
+ x = self.proj_out(x)
+ x = rearrange(x, "b (h w) c -> b c h w", h=h, w=w)
+ if not self.use_linear:
+ x = self.proj_out(x)
+ out = x + x_in
+ return out
diff --git a/ComfyUI/comfy/ldm/modules/diffusionmodules/__init__.py b/ComfyUI/comfy/ldm/modules/diffusionmodules/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/ComfyUI/comfy/ldm/modules/diffusionmodules/__pycache__/__init__.cpython-312.pyc b/ComfyUI/comfy/ldm/modules/diffusionmodules/__pycache__/__init__.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..8b2b93d0e1323173420bf1ec1ab5492503faedbe
Binary files /dev/null and b/ComfyUI/comfy/ldm/modules/diffusionmodules/__pycache__/__init__.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/modules/diffusionmodules/__pycache__/mmdit.cpython-312.pyc b/ComfyUI/comfy/ldm/modules/diffusionmodules/__pycache__/mmdit.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..0109feec36fc997d89ce7bf36f82570291b18204
Binary files /dev/null and b/ComfyUI/comfy/ldm/modules/diffusionmodules/__pycache__/mmdit.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/modules/diffusionmodules/__pycache__/model.cpython-312.pyc b/ComfyUI/comfy/ldm/modules/diffusionmodules/__pycache__/model.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..0bd052bc25c6263da63028bae7b3ab005f4023ef
Binary files /dev/null and b/ComfyUI/comfy/ldm/modules/diffusionmodules/__pycache__/model.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/modules/diffusionmodules/__pycache__/openaimodel.cpython-312.pyc b/ComfyUI/comfy/ldm/modules/diffusionmodules/__pycache__/openaimodel.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..35b98538d14230d2a81cb3d94a8041dcfe817dcb
Binary files /dev/null and b/ComfyUI/comfy/ldm/modules/diffusionmodules/__pycache__/openaimodel.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/modules/diffusionmodules/__pycache__/upscaling.cpython-312.pyc b/ComfyUI/comfy/ldm/modules/diffusionmodules/__pycache__/upscaling.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..f9fc92d900e3f7ee83bdbf6850b67400982ce861
Binary files /dev/null and b/ComfyUI/comfy/ldm/modules/diffusionmodules/__pycache__/upscaling.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/modules/diffusionmodules/__pycache__/util.cpython-312.pyc b/ComfyUI/comfy/ldm/modules/diffusionmodules/__pycache__/util.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..6d65555124a7f1aa77bd02d5c425d36e7b9ec229
Binary files /dev/null and b/ComfyUI/comfy/ldm/modules/diffusionmodules/__pycache__/util.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/modules/diffusionmodules/mmdit.py b/ComfyUI/comfy/ldm/modules/diffusionmodules/mmdit.py
new file mode 100644
index 0000000000000000000000000000000000000000..9ab3c463cde2c4d2ce0f827a6c1de9c5353e03be
--- /dev/null
+++ b/ComfyUI/comfy/ldm/modules/diffusionmodules/mmdit.py
@@ -0,0 +1,1037 @@
+from functools import partial
+from typing import Dict, Optional, List
+
+import numpy as np
+import torch
+import torch.nn as nn
+from ..attention import optimized_attention
+from einops import rearrange, repeat
+from .util import timestep_embedding
+import comfy.ops
+import comfy.ldm.common_dit
+
+def default(x, y):
+ if x is not None:
+ return x
+ return y
+
+class Mlp(nn.Module):
+ """ MLP as used in Vision Transformer, MLP-Mixer and related networks
+ """
+ def __init__(
+ self,
+ in_features,
+ hidden_features=None,
+ out_features=None,
+ act_layer=nn.GELU,
+ norm_layer=None,
+ bias=True,
+ drop=0.,
+ use_conv=False,
+ dtype=None,
+ device=None,
+ operations=None,
+ ):
+ super().__init__()
+ out_features = out_features or in_features
+ hidden_features = hidden_features or in_features
+ drop_probs = drop
+ linear_layer = partial(operations.Conv2d, kernel_size=1) if use_conv else operations.Linear
+
+ self.fc1 = linear_layer(in_features, hidden_features, bias=bias, dtype=dtype, device=device)
+ self.act = act_layer()
+ self.drop1 = nn.Dropout(drop_probs)
+ self.norm = norm_layer(hidden_features) if norm_layer is not None else nn.Identity()
+ self.fc2 = linear_layer(hidden_features, out_features, bias=bias, dtype=dtype, device=device)
+ self.drop2 = nn.Dropout(drop_probs)
+
+ def forward(self, x):
+ x = self.fc1(x)
+ x = self.act(x)
+ x = self.drop1(x)
+ x = self.norm(x)
+ x = self.fc2(x)
+ x = self.drop2(x)
+ return x
+
+class PatchEmbed(nn.Module):
+ """ 2D Image to Patch Embedding
+ """
+ dynamic_img_pad: torch.jit.Final[bool]
+
+ def __init__(
+ self,
+ img_size: Optional[int] = 224,
+ patch_size: int = 16,
+ in_chans: int = 3,
+ embed_dim: int = 768,
+ norm_layer = None,
+ flatten: bool = True,
+ bias: bool = True,
+ strict_img_size: bool = True,
+ dynamic_img_pad: bool = True,
+ padding_mode='circular',
+ conv3d=False,
+ dtype=None,
+ device=None,
+ operations=None,
+ ):
+ super().__init__()
+ try:
+ len(patch_size)
+ self.patch_size = patch_size
+ except:
+ if conv3d:
+ self.patch_size = (patch_size, patch_size, patch_size)
+ else:
+ self.patch_size = (patch_size, patch_size)
+ self.padding_mode = padding_mode
+
+ # flatten spatial dim and transpose to channels last, kept for bwd compat
+ self.flatten = flatten
+ self.strict_img_size = strict_img_size
+ self.dynamic_img_pad = dynamic_img_pad
+ if conv3d:
+ self.proj = operations.Conv3d(in_chans, embed_dim, kernel_size=patch_size, stride=patch_size, bias=bias, dtype=dtype, device=device)
+ else:
+ self.proj = operations.Conv2d(in_chans, embed_dim, kernel_size=patch_size, stride=patch_size, bias=bias, dtype=dtype, device=device)
+ self.norm = norm_layer(embed_dim) if norm_layer else nn.Identity()
+
+ def forward(self, x):
+ if self.dynamic_img_pad:
+ x = comfy.ldm.common_dit.pad_to_patch_size(x, self.patch_size, padding_mode=self.padding_mode)
+ x = self.proj(x)
+ if self.flatten:
+ x = x.flatten(2).transpose(1, 2) # NCHW -> NLC
+ x = self.norm(x)
+ return x
+
+def modulate(x, shift, scale):
+ if shift is None:
+ shift = torch.zeros_like(scale)
+ return torch.addcmul(shift.unsqueeze(1), x, 1+ scale.unsqueeze(1))
+
+
+#################################################################################
+# Sine/Cosine Positional Embedding Functions #
+#################################################################################
+
+
+def get_2d_sincos_pos_embed(
+ embed_dim,
+ grid_size,
+ cls_token=False,
+ extra_tokens=0,
+ scaling_factor=None,
+ offset=None,
+):
+ """
+ grid_size: int of the grid height and width
+ return:
+ pos_embed: [grid_size*grid_size, embed_dim] or [1+grid_size*grid_size, embed_dim] (w/ or w/o cls_token)
+ """
+ grid_h = np.arange(grid_size, dtype=np.float32)
+ grid_w = np.arange(grid_size, dtype=np.float32)
+ grid = np.meshgrid(grid_w, grid_h) # here w goes first
+ grid = np.stack(grid, axis=0)
+ if scaling_factor is not None:
+ grid = grid / scaling_factor
+ if offset is not None:
+ grid = grid - offset
+
+ grid = grid.reshape([2, 1, grid_size, grid_size])
+ pos_embed = get_2d_sincos_pos_embed_from_grid(embed_dim, grid)
+ if cls_token and extra_tokens > 0:
+ pos_embed = np.concatenate(
+ [np.zeros([extra_tokens, embed_dim]), pos_embed], axis=0
+ )
+ return pos_embed
+
+
+def get_2d_sincos_pos_embed_from_grid(embed_dim, grid):
+ assert embed_dim % 2 == 0
+
+ # use half of dimensions to encode grid_h
+ emb_h = get_1d_sincos_pos_embed_from_grid(embed_dim // 2, grid[0]) # (H*W, D/2)
+ emb_w = get_1d_sincos_pos_embed_from_grid(embed_dim // 2, grid[1]) # (H*W, D/2)
+
+ emb = np.concatenate([emb_h, emb_w], axis=1) # (H*W, D)
+ return emb
+
+
+def get_1d_sincos_pos_embed_from_grid(embed_dim, pos):
+ """
+ embed_dim: output dimension for each position
+ pos: a list of positions to be encoded: size (M,)
+ out: (M, D)
+ """
+ assert embed_dim % 2 == 0
+ omega = np.arange(embed_dim // 2, dtype=np.float64)
+ omega /= embed_dim / 2.0
+ omega = 1.0 / 10000**omega # (D/2,)
+
+ pos = pos.reshape(-1) # (M,)
+ out = np.einsum("m,d->md", pos, omega) # (M, D/2), outer product
+
+ emb_sin = np.sin(out) # (M, D/2)
+ emb_cos = np.cos(out) # (M, D/2)
+
+ emb = np.concatenate([emb_sin, emb_cos], axis=1) # (M, D)
+ return emb
+
+def get_1d_sincos_pos_embed_from_grid_torch(embed_dim, pos, device=None, dtype=torch.float32):
+ omega = torch.arange(embed_dim // 2, device=device, dtype=dtype)
+ omega /= embed_dim / 2.0
+ omega = 1.0 / 10000**omega # (D/2,)
+ pos = pos.reshape(-1) # (M,)
+ out = torch.einsum("m,d->md", pos, omega) # (M, D/2), outer product
+ emb_sin = torch.sin(out) # (M, D/2)
+ emb_cos = torch.cos(out) # (M, D/2)
+ emb = torch.cat([emb_sin, emb_cos], dim=1) # (M, D)
+ return emb
+
+def get_2d_sincos_pos_embed_torch(embed_dim, w, h, val_center=7.5, val_magnitude=7.5, device=None, dtype=torch.float32):
+ small = min(h, w)
+ val_h = (h / small) * val_magnitude
+ val_w = (w / small) * val_magnitude
+ grid_h, grid_w = torch.meshgrid(torch.linspace(-val_h + val_center, val_h + val_center, h, device=device, dtype=dtype), torch.linspace(-val_w + val_center, val_w + val_center, w, device=device, dtype=dtype), indexing='ij')
+ emb_h = get_1d_sincos_pos_embed_from_grid_torch(embed_dim // 2, grid_h, device=device, dtype=dtype)
+ emb_w = get_1d_sincos_pos_embed_from_grid_torch(embed_dim // 2, grid_w, device=device, dtype=dtype)
+ emb = torch.cat([emb_w, emb_h], dim=1) # (H*W, D)
+ return emb
+
+
+#################################################################################
+# Embedding Layers for Timesteps and Class Labels #
+#################################################################################
+
+
+class TimestepEmbedder(nn.Module):
+ """
+ Embeds scalar timesteps into vector representations.
+ """
+
+ def __init__(self, hidden_size, frequency_embedding_size=256, output_size=None, dtype=None, device=None, operations=None, max_period=10000):
+ super().__init__()
+ if output_size is None:
+ output_size = hidden_size
+ self.mlp = nn.Sequential(
+ operations.Linear(frequency_embedding_size, hidden_size, bias=True, dtype=dtype, device=device),
+ nn.SiLU(),
+ operations.Linear(hidden_size, output_size, bias=True, dtype=dtype, device=device),
+ )
+ self.frequency_embedding_size = frequency_embedding_size
+ self.max_period = max_period
+
+ def forward(self, t, dtype, **kwargs):
+ t_freq = timestep_embedding(t, self.frequency_embedding_size, max_period=self.max_period).to(dtype)
+ t_emb = self.mlp(t_freq)
+ return t_emb
+
+
+class VectorEmbedder(nn.Module):
+ """
+ Embeds a flat vector of dimension input_dim
+ """
+
+ def __init__(self, input_dim: int, hidden_size: int, dtype=None, device=None, operations=None):
+ super().__init__()
+ self.mlp = nn.Sequential(
+ operations.Linear(input_dim, hidden_size, bias=True, dtype=dtype, device=device),
+ nn.SiLU(),
+ operations.Linear(hidden_size, hidden_size, bias=True, dtype=dtype, device=device),
+ )
+
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
+ emb = self.mlp(x)
+ return emb
+
+
+#################################################################################
+# Core DiT Model #
+#################################################################################
+
+
+def split_qkv(qkv, head_dim):
+ qkv = qkv.reshape(qkv.shape[0], qkv.shape[1], 3, -1, head_dim).movedim(2, 0)
+ return qkv[0], qkv[1], qkv[2]
+
+
+class SelfAttention(nn.Module):
+ ATTENTION_MODES = ("xformers", "torch", "torch-hb", "math", "debug")
+
+ def __init__(
+ self,
+ dim: int,
+ num_heads: int = 8,
+ qkv_bias: bool = False,
+ qk_scale: Optional[float] = None,
+ proj_drop: float = 0.0,
+ attn_mode: str = "xformers",
+ pre_only: bool = False,
+ qk_norm: Optional[str] = None,
+ rmsnorm: bool = False,
+ dtype=None,
+ device=None,
+ operations=None,
+ ):
+ super().__init__()
+ self.num_heads = num_heads
+ self.head_dim = dim // num_heads
+
+ self.qkv = operations.Linear(dim, dim * 3, bias=qkv_bias, dtype=dtype, device=device)
+ if not pre_only:
+ self.proj = operations.Linear(dim, dim, dtype=dtype, device=device)
+ self.proj_drop = nn.Dropout(proj_drop)
+ assert attn_mode in self.ATTENTION_MODES
+ self.attn_mode = attn_mode
+ self.pre_only = pre_only
+
+ if qk_norm == "rms":
+ self.ln_q = RMSNorm(self.head_dim, elementwise_affine=True, eps=1.0e-6, dtype=dtype, device=device)
+ self.ln_k = RMSNorm(self.head_dim, elementwise_affine=True, eps=1.0e-6, dtype=dtype, device=device)
+ elif qk_norm == "ln":
+ self.ln_q = operations.LayerNorm(self.head_dim, elementwise_affine=True, eps=1.0e-6, dtype=dtype, device=device)
+ self.ln_k = operations.LayerNorm(self.head_dim, elementwise_affine=True, eps=1.0e-6, dtype=dtype, device=device)
+ elif qk_norm is None:
+ self.ln_q = nn.Identity()
+ self.ln_k = nn.Identity()
+ else:
+ raise ValueError(qk_norm)
+
+ def pre_attention(self, x: torch.Tensor) -> torch.Tensor:
+ B, L, C = x.shape
+ qkv = self.qkv(x)
+ q, k, v = split_qkv(qkv, self.head_dim)
+ q = self.ln_q(q).reshape(q.shape[0], q.shape[1], -1)
+ k = self.ln_k(k).reshape(q.shape[0], q.shape[1], -1)
+ return (q, k, v)
+
+ def post_attention(self, x: torch.Tensor) -> torch.Tensor:
+ assert not self.pre_only
+ x = self.proj(x)
+ x = self.proj_drop(x)
+ return x
+
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
+ q, k, v = self.pre_attention(x)
+ x = optimized_attention(
+ q, k, v, heads=self.num_heads
+ )
+ x = self.post_attention(x)
+ return x
+
+
+class RMSNorm(torch.nn.Module):
+ def __init__(
+ self, dim: int, elementwise_affine: bool = False, eps: float = 1e-6, device=None, dtype=None, **kwargs
+ ):
+ """
+ Initialize the RMSNorm normalization layer.
+ Args:
+ dim (int): The dimension of the input tensor.
+ eps (float, optional): A small value added to the denominator for numerical stability. Default is 1e-6.
+ Attributes:
+ eps (float): A small value added to the denominator for numerical stability.
+ weight (nn.Parameter): Learnable scaling parameter.
+ """
+ super().__init__()
+ self.eps = eps
+ self.learnable_scale = elementwise_affine
+ if self.learnable_scale:
+ self.weight = nn.Parameter(torch.empty(dim, device=device, dtype=dtype))
+ else:
+ self.register_parameter("weight", None)
+
+ def forward(self, x):
+ return comfy.ldm.common_dit.rms_norm(x, self.weight, self.eps)
+
+
+
+class SwiGLUFeedForward(nn.Module):
+ def __init__(
+ self,
+ dim: int,
+ hidden_dim: int,
+ multiple_of: int,
+ ffn_dim_multiplier: Optional[float] = None,
+ ):
+ """
+ Initialize the FeedForward module.
+
+ Args:
+ dim (int): Input dimension.
+ hidden_dim (int): Hidden dimension of the feedforward layer.
+ multiple_of (int): Value to ensure hidden dimension is a multiple of this value.
+ ffn_dim_multiplier (float, optional): Custom multiplier for hidden dimension. Defaults to None.
+
+ Attributes:
+ w1 (ColumnParallelLinear): Linear transformation for the first layer.
+ w2 (RowParallelLinear): Linear transformation for the second layer.
+ w3 (ColumnParallelLinear): Linear transformation for the third layer.
+
+ """
+ super().__init__()
+ hidden_dim = int(2 * hidden_dim / 3)
+ # custom dim factor multiplier
+ if ffn_dim_multiplier is not None:
+ hidden_dim = int(ffn_dim_multiplier * hidden_dim)
+ hidden_dim = multiple_of * ((hidden_dim + multiple_of - 1) // multiple_of)
+
+ self.w1 = nn.Linear(dim, hidden_dim, bias=False)
+ self.w2 = nn.Linear(hidden_dim, dim, bias=False)
+ self.w3 = nn.Linear(dim, hidden_dim, bias=False)
+
+ def forward(self, x):
+ return self.w2(nn.functional.silu(self.w1(x)) * self.w3(x))
+
+
+class DismantledBlock(nn.Module):
+ """
+ A DiT block with gated adaptive layer norm (adaLN) conditioning.
+ """
+
+ ATTENTION_MODES = ("xformers", "torch", "torch-hb", "math", "debug")
+
+ def __init__(
+ self,
+ hidden_size: int,
+ num_heads: int,
+ mlp_ratio: float = 4.0,
+ attn_mode: str = "xformers",
+ qkv_bias: bool = False,
+ pre_only: bool = False,
+ rmsnorm: bool = False,
+ scale_mod_only: bool = False,
+ swiglu: bool = False,
+ qk_norm: Optional[str] = None,
+ x_block_self_attn: bool = False,
+ dtype=None,
+ device=None,
+ operations=None,
+ **block_kwargs,
+ ):
+ super().__init__()
+ assert attn_mode in self.ATTENTION_MODES
+ if not rmsnorm:
+ self.norm1 = operations.LayerNorm(hidden_size, elementwise_affine=False, eps=1e-6, dtype=dtype, device=device)
+ else:
+ self.norm1 = RMSNorm(hidden_size, elementwise_affine=False, eps=1e-6)
+ self.attn = SelfAttention(
+ dim=hidden_size,
+ num_heads=num_heads,
+ qkv_bias=qkv_bias,
+ attn_mode=attn_mode,
+ pre_only=pre_only,
+ qk_norm=qk_norm,
+ rmsnorm=rmsnorm,
+ dtype=dtype,
+ device=device,
+ operations=operations
+ )
+ if x_block_self_attn:
+ assert not pre_only
+ assert not scale_mod_only
+ self.x_block_self_attn = True
+ self.attn2 = SelfAttention(
+ dim=hidden_size,
+ num_heads=num_heads,
+ qkv_bias=qkv_bias,
+ attn_mode=attn_mode,
+ pre_only=False,
+ qk_norm=qk_norm,
+ rmsnorm=rmsnorm,
+ dtype=dtype,
+ device=device,
+ operations=operations
+ )
+ else:
+ self.x_block_self_attn = False
+ if not pre_only:
+ if not rmsnorm:
+ self.norm2 = operations.LayerNorm(
+ hidden_size, elementwise_affine=False, eps=1e-6, dtype=dtype, device=device
+ )
+ else:
+ self.norm2 = RMSNorm(hidden_size, elementwise_affine=False, eps=1e-6)
+ mlp_hidden_dim = int(hidden_size * mlp_ratio)
+ if not pre_only:
+ if not swiglu:
+ self.mlp = Mlp(
+ in_features=hidden_size,
+ hidden_features=mlp_hidden_dim,
+ act_layer=lambda: nn.GELU(approximate="tanh"),
+ drop=0,
+ dtype=dtype,
+ device=device,
+ operations=operations
+ )
+ else:
+ self.mlp = SwiGLUFeedForward(
+ dim=hidden_size,
+ hidden_dim=mlp_hidden_dim,
+ multiple_of=256,
+ )
+ self.scale_mod_only = scale_mod_only
+ if x_block_self_attn:
+ assert not pre_only
+ assert not scale_mod_only
+ n_mods = 9
+ elif not scale_mod_only:
+ n_mods = 6 if not pre_only else 2
+ else:
+ n_mods = 4 if not pre_only else 1
+ self.adaLN_modulation = nn.Sequential(
+ nn.SiLU(), operations.Linear(hidden_size, n_mods * hidden_size, bias=True, dtype=dtype, device=device)
+ )
+ self.pre_only = pre_only
+
+ def pre_attention(self, x: torch.Tensor, c: torch.Tensor) -> torch.Tensor:
+ if not self.pre_only:
+ if not self.scale_mod_only:
+ (
+ shift_msa,
+ scale_msa,
+ gate_msa,
+ shift_mlp,
+ scale_mlp,
+ gate_mlp,
+ ) = self.adaLN_modulation(c).chunk(6, dim=1)
+ else:
+ shift_msa = None
+ shift_mlp = None
+ (
+ scale_msa,
+ gate_msa,
+ scale_mlp,
+ gate_mlp,
+ ) = self.adaLN_modulation(
+ c
+ ).chunk(4, dim=1)
+ qkv = self.attn.pre_attention(modulate(self.norm1(x), shift_msa, scale_msa))
+ return qkv, (
+ x,
+ gate_msa,
+ shift_mlp,
+ scale_mlp,
+ gate_mlp,
+ )
+ else:
+ if not self.scale_mod_only:
+ (
+ shift_msa,
+ scale_msa,
+ ) = self.adaLN_modulation(
+ c
+ ).chunk(2, dim=1)
+ else:
+ shift_msa = None
+ scale_msa = self.adaLN_modulation(c)
+ qkv = self.attn.pre_attention(modulate(self.norm1(x), shift_msa, scale_msa))
+ return qkv, None
+
+ def post_attention(self, attn, x, gate_msa, shift_mlp, scale_mlp, gate_mlp):
+ assert not self.pre_only
+ x = x + gate_msa.unsqueeze(1) * self.attn.post_attention(attn)
+ x = x + gate_mlp.unsqueeze(1) * self.mlp(
+ modulate(self.norm2(x), shift_mlp, scale_mlp)
+ )
+ return x
+
+ def pre_attention_x(self, x: torch.Tensor, c: torch.Tensor) -> torch.Tensor:
+ assert self.x_block_self_attn
+ (
+ shift_msa,
+ scale_msa,
+ gate_msa,
+ shift_mlp,
+ scale_mlp,
+ gate_mlp,
+ shift_msa2,
+ scale_msa2,
+ gate_msa2,
+ ) = self.adaLN_modulation(c).chunk(9, dim=1)
+ x_norm = self.norm1(x)
+ qkv = self.attn.pre_attention(modulate(x_norm, shift_msa, scale_msa))
+ qkv2 = self.attn2.pre_attention(modulate(x_norm, shift_msa2, scale_msa2))
+ return qkv, qkv2, (
+ x,
+ gate_msa,
+ shift_mlp,
+ scale_mlp,
+ gate_mlp,
+ gate_msa2,
+ )
+
+ def post_attention_x(self, attn, attn2, x, gate_msa, shift_mlp, scale_mlp, gate_mlp, gate_msa2):
+ assert not self.pre_only
+ attn1 = self.attn.post_attention(attn)
+ attn2 = self.attn2.post_attention(attn2)
+ x = gate_cat(x, gate_msa, gate_msa2, attn1, attn2)
+ x = x + gate_mlp.unsqueeze(1) * self.mlp(
+ modulate(self.norm2(x), shift_mlp, scale_mlp)
+ )
+ return x
+
+ def forward(self, x: torch.Tensor, c: torch.Tensor) -> torch.Tensor:
+ assert not self.pre_only
+ if self.x_block_self_attn:
+ qkv, qkv2, intermediates = self.pre_attention_x(x, c)
+ attn, _ = optimized_attention(
+ qkv[0], qkv[1], qkv[2],
+ num_heads=self.attn.num_heads,
+ )
+ attn2, _ = optimized_attention(
+ qkv2[0], qkv2[1], qkv2[2],
+ num_heads=self.attn2.num_heads,
+ )
+ return self.post_attention_x(attn, attn2, *intermediates)
+ else:
+ qkv, intermediates = self.pre_attention(x, c)
+ attn = optimized_attention(
+ qkv[0], qkv[1], qkv[2],
+ heads=self.attn.num_heads,
+ )
+ return self.post_attention(attn, *intermediates)
+
+def gate_cat(x, gate_msa, gate_msa2, attn1, attn2):
+ out1 = gate_msa.unsqueeze(1) * attn1
+ out2 = gate_msa2.unsqueeze(1) * attn2
+ x = torch.stack([x, out1, out2], dim=0).sum(dim=0)
+ return x
+
+def block_mixing(*args, use_checkpoint=True, **kwargs):
+ if use_checkpoint:
+ return torch.utils.checkpoint.checkpoint(
+ _block_mixing, *args, use_reentrant=False, **kwargs
+ )
+ else:
+ return _block_mixing(*args, **kwargs)
+
+
+def _block_mixing(context, x, context_block, x_block, c, transformer_options={}):
+ context_qkv, context_intermediates = context_block.pre_attention(context, c)
+
+ if x_block.x_block_self_attn:
+ x_qkv, x_qkv2, x_intermediates = x_block.pre_attention_x(x, c)
+ else:
+ x_qkv, x_intermediates = x_block.pre_attention(x, c)
+
+ o = []
+ for t in range(3):
+ o.append(torch.cat((context_qkv[t], x_qkv[t]), dim=1))
+ qkv = tuple(o)
+
+ attn = optimized_attention(
+ qkv[0], qkv[1], qkv[2],
+ heads=x_block.attn.num_heads,
+ transformer_options=transformer_options,
+ )
+ context_attn, x_attn = (
+ attn[:, : context_qkv[0].shape[1]],
+ attn[:, context_qkv[0].shape[1] :],
+ )
+
+ if not context_block.pre_only:
+ context = context_block.post_attention(context_attn, *context_intermediates)
+
+ else:
+ context = None
+ if x_block.x_block_self_attn:
+ attn2 = optimized_attention(
+ x_qkv2[0], x_qkv2[1], x_qkv2[2],
+ heads=x_block.attn2.num_heads,
+ transformer_options=transformer_options,
+ )
+ x = x_block.post_attention_x(x_attn, attn2, *x_intermediates)
+ else:
+ x = x_block.post_attention(x_attn, *x_intermediates)
+ return context, x
+
+
+class JointBlock(nn.Module):
+ """just a small wrapper to serve as a fsdp unit"""
+
+ def __init__(
+ self,
+ *args,
+ **kwargs,
+ ):
+ super().__init__()
+ pre_only = kwargs.pop("pre_only")
+ qk_norm = kwargs.pop("qk_norm", None)
+ x_block_self_attn = kwargs.pop("x_block_self_attn", False)
+ self.context_block = DismantledBlock(*args, pre_only=pre_only, qk_norm=qk_norm, **kwargs)
+ self.x_block = DismantledBlock(*args,
+ pre_only=False,
+ qk_norm=qk_norm,
+ x_block_self_attn=x_block_self_attn,
+ **kwargs)
+
+ def forward(self, *args, **kwargs):
+ return block_mixing(
+ *args, context_block=self.context_block, x_block=self.x_block, **kwargs
+ )
+
+
+class FinalLayer(nn.Module):
+ """
+ The final layer of DiT.
+ """
+
+ def __init__(
+ self,
+ hidden_size: int,
+ patch_size: int,
+ out_channels: int,
+ total_out_channels: Optional[int] = None,
+ dtype=None,
+ device=None,
+ operations=None,
+ ):
+ super().__init__()
+ self.norm_final = operations.LayerNorm(hidden_size, elementwise_affine=False, eps=1e-6, dtype=dtype, device=device)
+ self.linear = (
+ operations.Linear(hidden_size, patch_size * patch_size * out_channels, bias=True, dtype=dtype, device=device)
+ if (total_out_channels is None)
+ else operations.Linear(hidden_size, total_out_channels, bias=True, dtype=dtype, device=device)
+ )
+ self.adaLN_modulation = nn.Sequential(
+ nn.SiLU(), operations.Linear(hidden_size, 2 * hidden_size, bias=True, dtype=dtype, device=device)
+ )
+
+ def forward(self, x: torch.Tensor, c: torch.Tensor) -> torch.Tensor:
+ shift, scale = self.adaLN_modulation(c).chunk(2, dim=1)
+ x = modulate(self.norm_final(x), shift, scale)
+ x = self.linear(x)
+ return x
+
+class SelfAttentionContext(nn.Module):
+ def __init__(self, dim, heads=8, dim_head=64, dtype=None, device=None, operations=None):
+ super().__init__()
+ dim_head = dim // heads
+ inner_dim = dim
+
+ self.heads = heads
+ self.dim_head = dim_head
+
+ self.qkv = operations.Linear(dim, dim * 3, bias=True, dtype=dtype, device=device)
+
+ self.proj = operations.Linear(inner_dim, dim, dtype=dtype, device=device)
+
+ def forward(self, x):
+ qkv = self.qkv(x)
+ q, k, v = split_qkv(qkv, self.dim_head)
+ x = optimized_attention(q.reshape(q.shape[0], q.shape[1], -1), k, v, heads=self.heads)
+ return self.proj(x)
+
+class ContextProcessorBlock(nn.Module):
+ def __init__(self, context_size, dtype=None, device=None, operations=None):
+ super().__init__()
+ self.norm1 = operations.LayerNorm(context_size, elementwise_affine=False, eps=1e-6, dtype=dtype, device=device)
+ self.attn = SelfAttentionContext(context_size, dtype=dtype, device=device, operations=operations)
+ self.norm2 = operations.LayerNorm(context_size, elementwise_affine=False, eps=1e-6, dtype=dtype, device=device)
+ self.mlp = Mlp(in_features=context_size, hidden_features=(context_size * 4), act_layer=lambda: nn.GELU(approximate="tanh"), drop=0, dtype=dtype, device=device, operations=operations)
+
+ def forward(self, x):
+ x += self.attn(self.norm1(x))
+ x += self.mlp(self.norm2(x))
+ return x
+
+class ContextProcessor(nn.Module):
+ def __init__(self, context_size, num_layers, dtype=None, device=None, operations=None):
+ super().__init__()
+ self.layers = torch.nn.ModuleList([ContextProcessorBlock(context_size, dtype=dtype, device=device, operations=operations) for i in range(num_layers)])
+ self.norm = operations.LayerNorm(context_size, elementwise_affine=False, eps=1e-6, dtype=dtype, device=device)
+
+ def forward(self, x):
+ for i, l in enumerate(self.layers):
+ x = l(x)
+ return self.norm(x)
+
+class MMDiT(nn.Module):
+ """
+ Diffusion model with a Transformer backbone.
+ """
+
+ def __init__(
+ self,
+ input_size: int = 32,
+ patch_size: int = 2,
+ in_channels: int = 4,
+ depth: int = 28,
+ # hidden_size: Optional[int] = None,
+ # num_heads: Optional[int] = None,
+ mlp_ratio: float = 4.0,
+ learn_sigma: bool = False,
+ adm_in_channels: Optional[int] = None,
+ context_embedder_config: Optional[Dict] = None,
+ compile_core: bool = False,
+ use_checkpoint: bool = False,
+ register_length: int = 0,
+ attn_mode: str = "torch",
+ rmsnorm: bool = False,
+ scale_mod_only: bool = False,
+ swiglu: bool = False,
+ out_channels: Optional[int] = None,
+ pos_embed_scaling_factor: Optional[float] = None,
+ pos_embed_offset: Optional[float] = None,
+ pos_embed_max_size: Optional[int] = None,
+ num_patches = None,
+ qk_norm: Optional[str] = None,
+ qkv_bias: bool = True,
+ context_processor_layers = None,
+ x_block_self_attn: bool = False,
+ x_block_self_attn_layers: Optional[List[int]] = [],
+ context_size = 4096,
+ num_blocks = None,
+ final_layer = True,
+ skip_blocks = False,
+ dtype = None, #TODO
+ device = None,
+ operations = None,
+ ):
+ super().__init__()
+ self.dtype = dtype
+ self.learn_sigma = learn_sigma
+ self.in_channels = in_channels
+ default_out_channels = in_channels * 2 if learn_sigma else in_channels
+ self.out_channels = default(out_channels, default_out_channels)
+ self.patch_size = patch_size
+ self.pos_embed_scaling_factor = pos_embed_scaling_factor
+ self.pos_embed_offset = pos_embed_offset
+ self.pos_embed_max_size = pos_embed_max_size
+ self.x_block_self_attn_layers = x_block_self_attn_layers
+
+ # hidden_size = default(hidden_size, 64 * depth)
+ # num_heads = default(num_heads, hidden_size // 64)
+
+ # apply magic --> this defines a head_size of 64
+ self.hidden_size = 64 * depth
+ num_heads = depth
+ if num_blocks is None:
+ num_blocks = depth
+
+ self.depth = depth
+ self.num_heads = num_heads
+
+ self.x_embedder = PatchEmbed(
+ input_size,
+ patch_size,
+ in_channels,
+ self.hidden_size,
+ bias=True,
+ strict_img_size=self.pos_embed_max_size is None,
+ dtype=dtype,
+ device=device,
+ operations=operations
+ )
+ self.t_embedder = TimestepEmbedder(self.hidden_size, dtype=dtype, device=device, operations=operations)
+
+ self.y_embedder = None
+ if adm_in_channels is not None:
+ assert isinstance(adm_in_channels, int)
+ self.y_embedder = VectorEmbedder(adm_in_channels, self.hidden_size, dtype=dtype, device=device, operations=operations)
+
+ if context_processor_layers is not None:
+ self.context_processor = ContextProcessor(context_size, context_processor_layers, dtype=dtype, device=device, operations=operations)
+ else:
+ self.context_processor = None
+
+ self.context_embedder = nn.Identity()
+ if context_embedder_config is not None:
+ if context_embedder_config["target"] == "torch.nn.Linear":
+ self.context_embedder = operations.Linear(**context_embedder_config["params"], dtype=dtype, device=device)
+
+ self.register_length = register_length
+ if self.register_length > 0:
+ self.register = nn.Parameter(torch.randn(1, register_length, self.hidden_size, dtype=dtype, device=device))
+
+ # num_patches = self.x_embedder.num_patches
+ # Will use fixed sin-cos embedding:
+ # just use a buffer already
+ if num_patches is not None:
+ self.register_buffer(
+ "pos_embed",
+ torch.empty(1, num_patches, self.hidden_size, dtype=dtype, device=device),
+ )
+ else:
+ self.pos_embed = None
+
+ self.use_checkpoint = use_checkpoint
+ if not skip_blocks:
+ self.joint_blocks = nn.ModuleList(
+ [
+ JointBlock(
+ self.hidden_size,
+ num_heads,
+ mlp_ratio=mlp_ratio,
+ qkv_bias=qkv_bias,
+ attn_mode=attn_mode,
+ pre_only=(i == num_blocks - 1) and final_layer,
+ rmsnorm=rmsnorm,
+ scale_mod_only=scale_mod_only,
+ swiglu=swiglu,
+ qk_norm=qk_norm,
+ x_block_self_attn=(i in self.x_block_self_attn_layers) or x_block_self_attn,
+ dtype=dtype,
+ device=device,
+ operations=operations,
+ )
+ for i in range(num_blocks)
+ ]
+ )
+
+ if final_layer:
+ self.final_layer = FinalLayer(self.hidden_size, patch_size, self.out_channels, dtype=dtype, device=device, operations=operations)
+
+ if compile_core:
+ assert False
+ self.forward_core_with_concat = torch.compile(self.forward_core_with_concat)
+
+ def cropped_pos_embed(self, hw, device=None):
+ p = self.x_embedder.patch_size[0]
+ h, w = hw
+ # patched size
+ h = (h + 1) // p
+ w = (w + 1) // p
+ if self.pos_embed is None:
+ return get_2d_sincos_pos_embed_torch(self.hidden_size, w, h, device=device)
+ assert self.pos_embed_max_size is not None
+ assert h <= self.pos_embed_max_size, (h, self.pos_embed_max_size)
+ assert w <= self.pos_embed_max_size, (w, self.pos_embed_max_size)
+ top = (self.pos_embed_max_size - h) // 2
+ left = (self.pos_embed_max_size - w) // 2
+ spatial_pos_embed = rearrange(
+ self.pos_embed,
+ "1 (h w) c -> 1 h w c",
+ h=self.pos_embed_max_size,
+ w=self.pos_embed_max_size,
+ )
+ spatial_pos_embed = spatial_pos_embed[:, top : top + h, left : left + w, :]
+ spatial_pos_embed = rearrange(spatial_pos_embed, "1 h w c -> 1 (h w) c")
+ # print(spatial_pos_embed, top, left, h, w)
+ # # t = get_2d_sincos_pos_embed_torch(self.hidden_size, w, h, 7.875, 7.875, device=device) #matches exactly for 1024 res
+ # t = get_2d_sincos_pos_embed_torch(self.hidden_size, w, h, 7.5, 7.5, device=device) #scales better
+ # # print(t)
+ # return t
+ return spatial_pos_embed
+
+ def unpatchify(self, x, hw=None):
+ """
+ x: (N, T, patch_size**2 * C)
+ imgs: (N, H, W, C)
+ """
+ c = self.out_channels
+ p = self.x_embedder.patch_size[0]
+ if hw is None:
+ h = w = int(x.shape[1] ** 0.5)
+ else:
+ h, w = hw
+ h = (h + 1) // p
+ w = (w + 1) // p
+ assert h * w == x.shape[1]
+
+ x = x.reshape(shape=(x.shape[0], h, w, p, p, c))
+ x = torch.einsum("nhwpqc->nchpwq", x)
+ imgs = x.reshape(shape=(x.shape[0], c, h * p, w * p))
+ return imgs
+
+ def forward_core_with_concat(
+ self,
+ x: torch.Tensor,
+ c_mod: torch.Tensor,
+ context: Optional[torch.Tensor] = None,
+ control = None,
+ transformer_options = {},
+ ) -> torch.Tensor:
+ patches_replace = transformer_options.get("patches_replace", {})
+ if self.register_length > 0:
+ context = torch.cat(
+ (
+ repeat(self.register, "1 ... -> b ...", b=x.shape[0]),
+ default(context, torch.Tensor([]).type_as(x)),
+ ),
+ 1,
+ )
+
+ # context is B, L', D
+ # x is B, L, D
+ blocks_replace = patches_replace.get("dit", {})
+ blocks = len(self.joint_blocks)
+ for i in range(blocks):
+ if ("double_block", i) in blocks_replace:
+ def block_wrap(args):
+ out = {}
+ out["txt"], out["img"] = self.joint_blocks[i](args["txt"], args["img"], c=args["vec"], transformer_options=args["transformer_options"])
+ return out
+
+ out = blocks_replace[("double_block", i)]({"img": x, "txt": context, "vec": c_mod, "transformer_options": transformer_options}, {"original_block": block_wrap})
+ context = out["txt"]
+ x = out["img"]
+ else:
+ context, x = self.joint_blocks[i](
+ context,
+ x,
+ c=c_mod,
+ use_checkpoint=self.use_checkpoint,
+ transformer_options=transformer_options,
+ )
+ if control is not None:
+ control_o = control.get("output")
+ if i < len(control_o):
+ add = control_o[i]
+ if add is not None:
+ x += add
+
+ x = self.final_layer(x, c_mod) # (N, T, patch_size ** 2 * out_channels)
+ return x
+
+ def forward(
+ self,
+ x: torch.Tensor,
+ t: torch.Tensor,
+ y: Optional[torch.Tensor] = None,
+ context: Optional[torch.Tensor] = None,
+ control = None,
+ transformer_options = {},
+ ) -> torch.Tensor:
+ """
+ Forward pass of DiT.
+ x: (N, C, H, W) tensor of spatial inputs (images or latent representations of images)
+ t: (N,) tensor of diffusion timesteps
+ y: (N,) tensor of class labels
+ """
+
+ if self.context_processor is not None:
+ context = self.context_processor(context)
+
+ hw = x.shape[-2:]
+ x = self.x_embedder(x) + comfy.ops.cast_to_input(self.cropped_pos_embed(hw, device=x.device), x)
+ c = self.t_embedder(t, dtype=x.dtype) # (N, D)
+ if y is not None and self.y_embedder is not None:
+ y = self.y_embedder(y) # (N, D)
+ c = c + y # (N, D)
+
+ if context is not None:
+ context = self.context_embedder(context)
+
+ x = self.forward_core_with_concat(x, c, context, control, transformer_options)
+
+ x = self.unpatchify(x, hw=hw) # (N, out_channels, H, W)
+ return x[:,:,:hw[-2],:hw[-1]]
+
+
+class OpenAISignatureMMDITWrapper(MMDiT):
+ def forward(
+ self,
+ x: torch.Tensor,
+ timesteps: torch.Tensor,
+ context: Optional[torch.Tensor] = None,
+ y: Optional[torch.Tensor] = None,
+ control = None,
+ transformer_options = {},
+ **kwargs,
+ ) -> torch.Tensor:
+ return super().forward(x, timesteps, context=context, y=y, control=control, transformer_options=transformer_options)
+
diff --git a/ComfyUI/comfy/ldm/modules/diffusionmodules/model.py b/ComfyUI/comfy/ldm/modules/diffusionmodules/model.py
new file mode 100644
index 0000000000000000000000000000000000000000..e752d0ecb03c2abd2a4fb7ea5f42a0ffb8e6be99
--- /dev/null
+++ b/ComfyUI/comfy/ldm/modules/diffusionmodules/model.py
@@ -0,0 +1,827 @@
+# pytorch_diffusion + derived encoder decoder
+import math
+import torch
+import torch.nn as nn
+import numpy as np
+import logging
+
+from comfy import model_management
+import comfy.ops
+ops = comfy.ops.disable_weight_init
+
+if model_management.xformers_enabled_vae():
+ import xformers
+ import xformers.ops
+
+def torch_cat_if_needed(xl, dim):
+ xl = [x for x in xl if x is not None and x.shape[dim] > 0]
+ if len(xl) > 1:
+ return torch.cat(xl, dim)
+ elif len(xl) == 1:
+ return xl[0]
+ else:
+ return None
+
+def get_timestep_embedding(timesteps, embedding_dim, flip_sin_to_cos=False, downscale_freq_shift=1):
+ """
+ This matches the implementation in Denoising Diffusion Probabilistic Models:
+ From Fairseq.
+ Build sinusoidal embeddings.
+ This matches the implementation in tensor2tensor, but differs slightly
+ from the description in Section 3.5 of "Attention Is All You Need".
+ """
+ assert len(timesteps.shape) == 1
+
+ half_dim = embedding_dim // 2
+ emb = math.log(10000) / (half_dim - downscale_freq_shift)
+ emb = torch.exp(torch.arange(half_dim, dtype=torch.float32) * -emb)
+ emb = emb.to(device=timesteps.device)
+ emb = timesteps.float()[:, None] * emb[None, :]
+ emb = torch.cat([torch.sin(emb), torch.cos(emb)], dim=1)
+ if flip_sin_to_cos:
+ emb = torch.cat([emb[:, half_dim:], emb[:, :half_dim]], dim=-1)
+ if embedding_dim % 2 == 1: # zero pad
+ emb = torch.nn.functional.pad(emb, (0,1,0,0))
+ return emb
+
+
+def nonlinearity(x):
+ # swish
+ return torch.nn.functional.silu(x)
+
+
+def Normalize(in_channels, num_groups=32):
+ return ops.GroupNorm(num_groups=num_groups, num_channels=in_channels, eps=1e-6, affine=True)
+
+
+class CarriedConv3d(nn.Module):
+ def __init__(self, n_channels, out_channels, kernel_size, stride=1, dilation=1, padding=0, **kwargs):
+ super().__init__()
+ self.conv = ops.Conv3d(n_channels, out_channels, kernel_size, stride=stride, dilation=dilation, **kwargs)
+
+ def forward(self, x):
+ return self.conv(x)
+
+
+def conv_carry_causal_3d(xl, op, conv_carry_in=None, conv_carry_out=None):
+
+ x = xl[0]
+ xl.clear()
+
+ if isinstance(op, CarriedConv3d):
+ if conv_carry_in is None:
+ x = torch.nn.functional.pad(x, (1, 1, 1, 1, 2, 0), mode = 'replicate')
+ else:
+ carry_len = conv_carry_in[0].shape[2]
+ x = torch.nn.functional.pad(x, (1, 1, 1, 1, 2 - carry_len, 0), mode = 'replicate')
+ x = torch.cat([conv_carry_in.pop(0), x], dim=2)
+
+ if conv_carry_out is not None:
+ to_push = x[:, :, -2:, :, :].clone()
+ conv_carry_out.append(to_push)
+
+ out = op(x)
+
+ return out
+
+
+class VideoConv3d(nn.Module):
+ def __init__(self, n_channels, out_channels, kernel_size, stride=1, dilation=1, padding_mode='replicate', padding=1, **kwargs):
+ super().__init__()
+
+ self.padding_mode = padding_mode
+ if padding != 0:
+ padding = (padding, padding, padding, padding, kernel_size - 1, 0)
+ else:
+ kwargs["padding"] = padding
+
+ self.padding = padding
+ self.conv = ops.Conv3d(n_channels, out_channels, kernel_size, stride=stride, dilation=dilation, **kwargs)
+
+ def forward(self, x):
+ if self.padding != 0:
+ x = torch.nn.functional.pad(x, self.padding, mode=self.padding_mode)
+ return self.conv(x)
+
+def interpolate_up(x, scale_factor):
+ return torch.nn.functional.interpolate(x, scale_factor=scale_factor, mode="nearest")
+
+class Upsample(nn.Module):
+ def __init__(self, in_channels, with_conv, conv_op=ops.Conv2d, scale_factor=2.0):
+ super().__init__()
+ self.with_conv = with_conv
+ self.scale_factor = scale_factor
+
+ if self.with_conv:
+ self.conv = conv_op(in_channels,
+ in_channels,
+ kernel_size=3,
+ stride=1,
+ padding=1)
+
+ def forward(self, x, conv_carry_in=None, conv_carry_out=None):
+ scale_factor = self.scale_factor
+ if isinstance(scale_factor, (int, float)):
+ scale_factor = (scale_factor,) * (x.ndim - 2)
+
+ if x.ndim == 5 and scale_factor[0] > 1.0:
+ results = []
+ if conv_carry_in is None:
+ first = x[:, :, :1, :, :]
+ results.append(interpolate_up(first.squeeze(2), scale_factor=scale_factor[1:]).unsqueeze(2))
+ x = x[:, :, 1:, :, :]
+ if x.shape[2] > 0:
+ results.append(interpolate_up(x, scale_factor))
+ x = torch_cat_if_needed(results, dim=2)
+ else:
+ x = interpolate_up(x, scale_factor)
+ if self.with_conv:
+ x = conv_carry_causal_3d([x], self.conv, conv_carry_in, conv_carry_out)
+ return x
+
+
+class Downsample(nn.Module):
+ def __init__(self, in_channels, with_conv, stride=2, conv_op=ops.Conv2d):
+ super().__init__()
+ self.with_conv = with_conv
+ if self.with_conv:
+ # no asymmetric padding in torch conv, must do it ourselves
+ self.conv = conv_op(in_channels,
+ in_channels,
+ kernel_size=3,
+ stride=stride,
+ padding=0)
+
+ def forward(self, x, conv_carry_in=None, conv_carry_out=None):
+ if self.with_conv:
+ if isinstance(self.conv, CarriedConv3d):
+ x = conv_carry_causal_3d([x], self.conv, conv_carry_in, conv_carry_out)
+ elif x.ndim == 4:
+ pad = (0, 1, 0, 1)
+ mode = "constant"
+ x = torch.nn.functional.pad(x, pad, mode=mode, value=0)
+ x = self.conv(x)
+ elif x.ndim == 5:
+ pad = (1, 1, 1, 1, 2, 0)
+ mode = "replicate"
+ x = torch.nn.functional.pad(x, pad, mode=mode)
+ x = self.conv(x)
+ else:
+ x = torch.nn.functional.avg_pool2d(x, kernel_size=2, stride=2)
+ return x
+
+
+class ResnetBlock(nn.Module):
+ def __init__(self, *, in_channels, out_channels=None, conv_shortcut=False,
+ dropout=0.0, temb_channels=512, conv_op=ops.Conv2d, norm_op=Normalize):
+ super().__init__()
+ self.in_channels = in_channels
+ out_channels = in_channels if out_channels is None else out_channels
+ self.out_channels = out_channels
+ self.use_conv_shortcut = conv_shortcut
+
+ self.swish = torch.nn.SiLU(inplace=True)
+ self.norm1 = norm_op(in_channels)
+ self.conv1 = conv_op(in_channels,
+ out_channels,
+ kernel_size=3,
+ stride=1,
+ padding=1)
+ if temb_channels > 0:
+ self.temb_proj = ops.Linear(temb_channels,
+ out_channels)
+ self.norm2 = norm_op(out_channels)
+ self.dropout = torch.nn.Dropout(dropout, inplace=True)
+ self.conv2 = conv_op(out_channels,
+ out_channels,
+ kernel_size=3,
+ stride=1,
+ padding=1)
+ if self.in_channels != self.out_channels:
+ if self.use_conv_shortcut:
+ self.conv_shortcut = conv_op(in_channels,
+ out_channels,
+ kernel_size=3,
+ stride=1,
+ padding=1)
+ else:
+ self.nin_shortcut = conv_op(in_channels,
+ out_channels,
+ kernel_size=1,
+ stride=1,
+ padding=0)
+
+ def forward(self, x, temb=None, conv_carry_in=None, conv_carry_out=None):
+ h = x
+ h = self.norm1(h)
+ h = [ self.swish(h) ]
+ h = conv_carry_causal_3d(h, self.conv1, conv_carry_in=conv_carry_in, conv_carry_out=conv_carry_out)
+
+ if temb is not None:
+ h = h + self.temb_proj(self.swish(temb))[:,:,None,None]
+
+ h = self.norm2(h)
+ h = self.swish(h)
+ h = [ self.dropout(h) ]
+ h = conv_carry_causal_3d(h, self.conv2, conv_carry_in=conv_carry_in, conv_carry_out=conv_carry_out)
+
+ if self.in_channels != self.out_channels:
+ if self.use_conv_shortcut:
+ x = conv_carry_causal_3d([x], self.conv_shortcut, conv_carry_in=conv_carry_in, conv_carry_out=conv_carry_out)
+ else:
+ x = self.nin_shortcut(x)
+
+ return x+h
+
+def slice_attention(q, k, v):
+ r1 = torch.zeros_like(k, device=q.device)
+ scale = (int(q.shape[-1])**(-0.5))
+
+ mem_free_total = model_management.get_free_memory(q.device)
+
+ tensor_size = q.shape[0] * q.shape[1] * k.shape[2] * q.element_size()
+ modifier = 3 if q.element_size() == 2 else 2.5
+ mem_required = tensor_size * modifier
+ steps = 1
+
+ if mem_required > mem_free_total:
+ steps = 2**(math.ceil(math.log(mem_required / mem_free_total, 2)))
+
+ while True:
+ try:
+ slice_size = q.shape[1] // steps if (q.shape[1] % steps) == 0 else q.shape[1]
+ for i in range(0, q.shape[1], slice_size):
+ end = i + slice_size
+ s1 = torch.bmm(q[:, i:end], k) * scale
+
+ s2 = torch.nn.functional.softmax(s1, dim=2).permute(0,2,1)
+ del s1
+
+ r1[:, :, i:end] = torch.bmm(v, s2)
+ del s2
+ break
+ except Exception as e:
+ model_management.raise_non_oom(e)
+ model_management.soft_empty_cache(True)
+ steps *= 2
+ if steps > 128:
+ raise e
+ logging.warning("out of memory error, increasing steps and trying again {}".format(steps))
+
+ return r1
+
+def normal_attention(q, k, v):
+ # compute attention
+ orig_shape = q.shape
+ b = orig_shape[0]
+ c = orig_shape[1]
+
+ q = q.reshape(b, c, -1)
+ q = q.permute(0, 2, 1) # b,hw,c
+ k = k.reshape(b, c, -1) # b,c,hw
+ v = v.reshape(b, c, -1)
+
+ r1 = slice_attention(q, k, v)
+ h_ = r1.reshape(orig_shape)
+ del r1
+ return h_
+
+def xformers_attention(q, k, v):
+ # compute attention
+ orig_shape = q.shape
+ B = orig_shape[0]
+ C = orig_shape[1]
+ q, k, v = map(
+ lambda t: t.view(B, C, -1).transpose(1, 2).contiguous(),
+ (q, k, v),
+ )
+
+ try:
+ out = xformers.ops.memory_efficient_attention(q, k, v, attn_bias=None)
+ out = out.transpose(1, 2).reshape(orig_shape)
+ except NotImplementedError:
+ out = slice_attention(q.view(B, -1, C), k.view(B, -1, C).transpose(1, 2), v.view(B, -1, C).transpose(1, 2)).reshape(orig_shape)
+ return out
+
+def pytorch_attention(q, k, v):
+ # compute attention
+ orig_shape = q.shape
+ B = orig_shape[0]
+ C = orig_shape[1]
+ oom_fallback = False
+ q, k, v = map(
+ lambda t: t.view(B, 1, C, -1).transpose(2, 3).contiguous(),
+ (q, k, v),
+ )
+
+ try:
+ out = comfy.ops.scaled_dot_product_attention(q, k, v, attn_mask=None, dropout_p=0.0, is_causal=False)
+ out = out.transpose(2, 3).reshape(orig_shape)
+ except Exception as e:
+ model_management.raise_non_oom(e)
+ logging.warning("scaled_dot_product_attention OOMed: switched to slice attention")
+ oom_fallback = True
+ if oom_fallback:
+ out = slice_attention(q.view(B, -1, C), k.view(B, -1, C).transpose(1, 2), v.view(B, -1, C).transpose(1, 2)).reshape(orig_shape)
+ return out
+
+
+def vae_attention():
+ if model_management.xformers_enabled_vae():
+ logging.info("Using xformers attention in VAE")
+ return xformers_attention
+ elif model_management.pytorch_attention_enabled_vae():
+ logging.info("Using pytorch attention in VAE")
+ return pytorch_attention
+ else:
+ logging.info("Using split attention in VAE")
+ return normal_attention
+
+class AttnBlock(nn.Module):
+ def __init__(self, in_channels, conv_op=ops.Conv2d, norm_op=Normalize):
+ super().__init__()
+ self.in_channels = in_channels
+
+ self.norm = norm_op(in_channels)
+ self.q = conv_op(in_channels,
+ in_channels,
+ kernel_size=1,
+ stride=1,
+ padding=0)
+ self.k = conv_op(in_channels,
+ in_channels,
+ kernel_size=1,
+ stride=1,
+ padding=0)
+ self.v = conv_op(in_channels,
+ in_channels,
+ kernel_size=1,
+ stride=1,
+ padding=0)
+ self.proj_out = conv_op(in_channels,
+ in_channels,
+ kernel_size=1,
+ stride=1,
+ padding=0)
+
+ self.optimized_attention = vae_attention()
+
+ def forward(self, x):
+ h_ = x
+ h_ = self.norm(h_)
+ q = self.q(h_)
+ k = self.k(h_)
+ v = self.v(h_)
+
+ h_ = self.optimized_attention(q, k, v)
+
+ h_ = self.proj_out(h_)
+
+ return x+h_
+
+
+def make_attn(in_channels, attn_type="vanilla", attn_kwargs=None, conv_op=ops.Conv2d):
+ return AttnBlock(in_channels, conv_op=conv_op)
+
+
+class Model(nn.Module):
+ def __init__(self, *, ch, out_ch, ch_mult=(1,2,4,8), num_res_blocks,
+ attn_resolutions, dropout=0.0, resamp_with_conv=True, in_channels,
+ resolution, use_timestep=True, use_linear_attn=False, attn_type="vanilla"):
+ super().__init__()
+ if use_linear_attn:
+ attn_type = "linear"
+ self.ch = ch
+ self.temb_ch = self.ch*4
+ self.num_resolutions = len(ch_mult)
+ self.num_res_blocks = num_res_blocks
+ self.resolution = resolution
+ self.in_channels = in_channels
+
+ self.use_timestep = use_timestep
+ if self.use_timestep:
+ # timestep embedding
+ self.temb = nn.Module()
+ self.temb.dense = nn.ModuleList([
+ ops.Linear(self.ch,
+ self.temb_ch),
+ ops.Linear(self.temb_ch,
+ self.temb_ch),
+ ])
+
+ # downsampling
+ self.conv_in = ops.Conv2d(in_channels,
+ self.ch,
+ kernel_size=3,
+ stride=1,
+ padding=1)
+
+ curr_res = resolution
+ in_ch_mult = (1,)+tuple(ch_mult)
+ self.down = nn.ModuleList()
+ for i_level in range(self.num_resolutions):
+ block = nn.ModuleList()
+ attn = nn.ModuleList()
+ block_in = ch*in_ch_mult[i_level]
+ block_out = ch*ch_mult[i_level]
+ for i_block in range(self.num_res_blocks):
+ block.append(ResnetBlock(in_channels=block_in,
+ out_channels=block_out,
+ temb_channels=self.temb_ch,
+ dropout=dropout))
+ block_in = block_out
+ if curr_res in attn_resolutions:
+ attn.append(make_attn(block_in, attn_type=attn_type))
+ down = nn.Module()
+ down.block = block
+ down.attn = attn
+ if i_level != self.num_resolutions-1:
+ down.downsample = Downsample(block_in, resamp_with_conv)
+ curr_res = curr_res // 2
+ self.down.append(down)
+
+ # middle
+ self.mid = nn.Module()
+ self.mid.block_1 = ResnetBlock(in_channels=block_in,
+ out_channels=block_in,
+ temb_channels=self.temb_ch,
+ dropout=dropout)
+ self.mid.attn_1 = make_attn(block_in, attn_type=attn_type)
+ self.mid.block_2 = ResnetBlock(in_channels=block_in,
+ out_channels=block_in,
+ temb_channels=self.temb_ch,
+ dropout=dropout)
+
+ # upsampling
+ self.up = nn.ModuleList()
+ for i_level in reversed(range(self.num_resolutions)):
+ block = nn.ModuleList()
+ attn = nn.ModuleList()
+ block_out = ch*ch_mult[i_level]
+ skip_in = ch*ch_mult[i_level]
+ for i_block in range(self.num_res_blocks+1):
+ if i_block == self.num_res_blocks:
+ skip_in = ch*in_ch_mult[i_level]
+ block.append(ResnetBlock(in_channels=block_in+skip_in,
+ out_channels=block_out,
+ temb_channels=self.temb_ch,
+ dropout=dropout))
+ block_in = block_out
+ if curr_res in attn_resolutions:
+ attn.append(make_attn(block_in, attn_type=attn_type))
+ up = nn.Module()
+ up.block = block
+ up.attn = attn
+ if i_level != 0:
+ up.upsample = Upsample(block_in, resamp_with_conv)
+ curr_res = curr_res * 2
+ self.up.insert(0, up) # prepend to get consistent order
+
+ # end
+ self.norm_out = Normalize(block_in)
+ self.conv_out = ops.Conv2d(block_in,
+ out_ch,
+ kernel_size=3,
+ stride=1,
+ padding=1)
+
+ def forward(self, x, t=None, context=None):
+ #assert x.shape[2] == x.shape[3] == self.resolution
+ if context is not None:
+ # assume aligned context, cat along channel axis
+ x = torch.cat((x, context), dim=1)
+ if self.use_timestep:
+ # timestep embedding
+ assert t is not None
+ temb = get_timestep_embedding(t, self.ch)
+ temb = self.temb.dense[0](temb)
+ temb = nonlinearity(temb)
+ temb = self.temb.dense[1](temb)
+ else:
+ temb = None
+
+ # downsampling
+ hs = [self.conv_in(x)]
+ for i_level in range(self.num_resolutions):
+ for i_block in range(self.num_res_blocks):
+ h = self.down[i_level].block[i_block](hs[-1], temb)
+ if len(self.down[i_level].attn) > 0:
+ h = self.down[i_level].attn[i_block](h)
+ hs.append(h)
+ if i_level != self.num_resolutions-1:
+ hs.append(self.down[i_level].downsample(hs[-1]))
+
+ # middle
+ h = hs[-1]
+ h = self.mid.block_1(h, temb)
+ h = self.mid.attn_1(h)
+ h = self.mid.block_2(h, temb)
+
+ # upsampling
+ for i_level in reversed(range(self.num_resolutions)):
+ for i_block in range(self.num_res_blocks+1):
+ h = self.up[i_level].block[i_block](
+ torch.cat([h, hs.pop()], dim=1), temb)
+ if len(self.up[i_level].attn) > 0:
+ h = self.up[i_level].attn[i_block](h)
+ if i_level != 0:
+ h = self.up[i_level].upsample(h)
+
+ # end
+ h = self.norm_out(h)
+ h = nonlinearity(h)
+ h = self.conv_out(h)
+ return h
+
+ def get_last_layer(self):
+ return self.conv_out.weight
+
+
+class Encoder(nn.Module):
+ def __init__(self, *, ch, out_ch, ch_mult=(1,2,4,8), num_res_blocks,
+ attn_resolutions, dropout=0.0, resamp_with_conv=True, in_channels,
+ resolution, z_channels, double_z=True, use_linear_attn=False, attn_type="vanilla",
+ conv3d=False, time_compress=None,
+ **ignore_kwargs):
+ super().__init__()
+ if use_linear_attn:
+ attn_type = "linear"
+ self.ch = ch
+ self.temb_ch = 0
+ self.num_resolutions = len(ch_mult)
+ self.num_res_blocks = num_res_blocks
+ self.resolution = resolution
+ self.in_channels = in_channels
+ self.carried = False
+
+ if conv3d:
+ if not attn_resolutions:
+ conv_op = CarriedConv3d
+ self.carried = True
+ else:
+ conv_op = VideoConv3d
+ mid_attn_conv_op = ops.Conv3d
+ else:
+ conv_op = ops.Conv2d
+ mid_attn_conv_op = ops.Conv2d
+
+ # downsampling
+ self.conv_in = conv_op(in_channels,
+ self.ch,
+ kernel_size=3,
+ stride=1,
+ padding=1)
+
+ self.time_compress = 1
+ curr_res = resolution
+ in_ch_mult = (1,)+tuple(ch_mult)
+ self.in_ch_mult = in_ch_mult
+ self.down = nn.ModuleList()
+ for i_level in range(self.num_resolutions):
+ block = nn.ModuleList()
+ attn = nn.ModuleList()
+ block_in = ch*in_ch_mult[i_level]
+ block_out = ch*ch_mult[i_level]
+ for i_block in range(self.num_res_blocks):
+ block.append(ResnetBlock(in_channels=block_in,
+ out_channels=block_out,
+ temb_channels=self.temb_ch,
+ dropout=dropout,
+ conv_op=conv_op))
+ block_in = block_out
+ if curr_res in attn_resolutions:
+ attn.append(make_attn(block_in, attn_type=attn_type, conv_op=conv_op))
+ down = nn.Module()
+ down.block = block
+ down.attn = attn
+ if i_level != self.num_resolutions-1:
+ stride = 2
+ if time_compress is not None:
+ if (self.num_resolutions - 1 - i_level) > math.log2(time_compress):
+ stride = (1, 2, 2)
+ else:
+ self.time_compress *= 2
+ down.downsample = Downsample(block_in, resamp_with_conv, stride=stride, conv_op=conv_op)
+ curr_res = curr_res // 2
+ self.down.append(down)
+
+ if time_compress is not None:
+ self.time_compress = time_compress
+
+ # middle
+ self.mid = nn.Module()
+ self.mid.block_1 = ResnetBlock(in_channels=block_in,
+ out_channels=block_in,
+ temb_channels=self.temb_ch,
+ dropout=dropout,
+ conv_op=conv_op)
+ self.mid.attn_1 = make_attn(block_in, attn_type=attn_type, conv_op=mid_attn_conv_op)
+ self.mid.block_2 = ResnetBlock(in_channels=block_in,
+ out_channels=block_in,
+ temb_channels=self.temb_ch,
+ dropout=dropout,
+ conv_op=conv_op)
+
+ # end
+ self.norm_out = Normalize(block_in)
+ self.conv_out = conv_op(block_in,
+ 2*z_channels if double_z else z_channels,
+ kernel_size=3,
+ stride=1,
+ padding=1)
+
+ def forward(self, x):
+ # timestep embedding
+ temb = None
+
+ if self.carried:
+ xl = [x[:, :, :1, :, :]]
+ if x.shape[2] > self.time_compress:
+ tc = self.time_compress
+ xl += torch.split(x[:, :, 1: 1 + ((x.shape[2] - 1) // tc) * tc, :, :], tc * 2, dim = 2)
+ x = xl
+ else:
+ x = [x]
+ out = []
+
+ conv_carry_in = None
+
+ for i, x1 in enumerate(x):
+ conv_carry_out = []
+ if i == len(x) - 1:
+ conv_carry_out = None
+
+ # downsampling
+ x1 = [ x1 ]
+ h1 = conv_carry_causal_3d(x1, self.conv_in, conv_carry_in, conv_carry_out)
+
+ for i_level in range(self.num_resolutions):
+ for i_block in range(self.num_res_blocks):
+ h1 = self.down[i_level].block[i_block](h1, temb, conv_carry_in, conv_carry_out)
+ if len(self.down[i_level].attn) > 0:
+ assert i == 0 #carried should not happen if attn exists
+ h1 = self.down[i_level].attn[i_block](h1)
+ if i_level != self.num_resolutions-1:
+ h1 = self.down[i_level].downsample(h1, conv_carry_in, conv_carry_out)
+
+ out.append(h1)
+ conv_carry_in = conv_carry_out
+
+ h = torch_cat_if_needed(out, dim=2)
+ del out
+
+ # middle
+ h = self.mid.block_1(h, temb)
+ h = self.mid.attn_1(h)
+ h = self.mid.block_2(h, temb)
+
+ # end
+ h = self.norm_out(h)
+ h = [ nonlinearity(h) ]
+ h = conv_carry_causal_3d(h, self.conv_out)
+ return h
+
+
+class Decoder(nn.Module):
+ def __init__(self, *, ch, out_ch, ch_mult=(1,2,4,8), num_res_blocks,
+ attn_resolutions, dropout=0.0, resamp_with_conv=True, in_channels,
+ resolution, z_channels, tanh_out=False, use_linear_attn=False,
+ conv_out_op=ops.Conv2d,
+ resnet_op=ResnetBlock,
+ attn_op=AttnBlock,
+ conv3d=False,
+ time_compress=None,
+ **ignorekwargs):
+ super().__init__()
+ self.ch = ch
+ self.temb_ch = 0
+ self.num_resolutions = len(ch_mult)
+ self.num_res_blocks = num_res_blocks
+ self.resolution = resolution
+ self.in_channels = in_channels
+ self.tanh_out = tanh_out
+ self.carried = False
+
+ if conv3d:
+ if not attn_resolutions and resnet_op == ResnetBlock:
+ conv_op = CarriedConv3d
+ conv_out_op = CarriedConv3d
+ self.carried = True
+ else:
+ conv_op = VideoConv3d
+ conv_out_op = VideoConv3d
+
+ mid_attn_conv_op = ops.Conv3d
+ else:
+ conv_op = ops.Conv2d
+ mid_attn_conv_op = ops.Conv2d
+
+ # compute block_in and curr_res at lowest res
+ block_in = ch*ch_mult[self.num_resolutions-1]
+ curr_res = resolution // 2**(self.num_resolutions-1)
+ self.z_shape = (1,z_channels,curr_res,curr_res)
+ logging.debug("Working with z of shape {} = {} dimensions.".format(
+ self.z_shape, np.prod(self.z_shape)))
+
+ # z to block_in
+ self.conv_in = conv_op(z_channels,
+ block_in,
+ kernel_size=3,
+ stride=1,
+ padding=1)
+
+ # middle
+ self.mid = nn.Module()
+ self.mid.block_1 = resnet_op(in_channels=block_in,
+ out_channels=block_in,
+ temb_channels=self.temb_ch,
+ dropout=dropout,
+ conv_op=conv_op)
+ self.mid.attn_1 = attn_op(block_in, conv_op=mid_attn_conv_op)
+ self.mid.block_2 = resnet_op(in_channels=block_in,
+ out_channels=block_in,
+ temb_channels=self.temb_ch,
+ dropout=dropout,
+ conv_op=conv_op)
+
+ # upsampling
+ self.up = nn.ModuleList()
+ for i_level in reversed(range(self.num_resolutions)):
+ block = nn.ModuleList()
+ attn = nn.ModuleList()
+ block_out = ch*ch_mult[i_level]
+ for i_block in range(self.num_res_blocks+1):
+ block.append(resnet_op(in_channels=block_in,
+ out_channels=block_out,
+ temb_channels=self.temb_ch,
+ dropout=dropout,
+ conv_op=conv_op))
+ block_in = block_out
+ if curr_res in attn_resolutions:
+ attn.append(attn_op(block_in, conv_op=conv_op))
+ up = nn.Module()
+ up.block = block
+ up.attn = attn
+ if i_level != 0:
+ scale_factor = 2.0
+ if time_compress is not None:
+ if i_level > math.log2(time_compress):
+ scale_factor = (1.0, 2.0, 2.0)
+
+ up.upsample = Upsample(block_in, resamp_with_conv, conv_op=conv_op, scale_factor=scale_factor)
+ curr_res = curr_res * 2
+ self.up.insert(0, up) # prepend to get consistent order
+
+ # end
+ self.norm_out = Normalize(block_in)
+ self.conv_out = conv_out_op(block_in,
+ out_ch,
+ kernel_size=3,
+ stride=1,
+ padding=1)
+
+ def forward(self, z, **kwargs):
+ # timestep embedding
+ temb = None
+
+ # z to block_in
+ h = conv_carry_causal_3d([z], self.conv_in)
+
+ # middle
+ h = self.mid.block_1(h, temb, **kwargs)
+ h = self.mid.attn_1(h, **kwargs)
+ h = self.mid.block_2(h, temb, **kwargs)
+
+ if self.carried:
+ h = torch.split(h, 2, dim=2)
+ else:
+ h = [ h ]
+ out = []
+
+ conv_carry_in = None
+
+ # upsampling
+ for i, h1 in enumerate(h):
+ conv_carry_out = []
+ if i == len(h) - 1:
+ conv_carry_out = None
+ for i_level in reversed(range(self.num_resolutions)):
+ for i_block in range(self.num_res_blocks+1):
+ h1 = self.up[i_level].block[i_block](h1, temb, conv_carry_in, conv_carry_out, **kwargs)
+ if len(self.up[i_level].attn) > 0:
+ assert i == 0 #carried should not happen if attn exists
+ h1 = self.up[i_level].attn[i_block](h1, **kwargs)
+ if i_level != 0:
+ h1 = self.up[i_level].upsample(h1, conv_carry_in, conv_carry_out)
+
+ h1 = self.norm_out(h1)
+ h1 = [ nonlinearity(h1) ]
+ h1 = conv_carry_causal_3d(h1, self.conv_out, conv_carry_in, conv_carry_out)
+ if self.tanh_out:
+ h1 = torch.tanh(h1)
+ out.append(h1)
+ conv_carry_in = conv_carry_out
+
+ out = torch_cat_if_needed(out, dim=2)
+
+ return out
diff --git a/ComfyUI/comfy/ldm/modules/diffusionmodules/openaimodel.py b/ComfyUI/comfy/ldm/modules/diffusionmodules/openaimodel.py
new file mode 100644
index 0000000000000000000000000000000000000000..4b92c44cf0e42dbe70fb5787cd6404b0f22ceddf
--- /dev/null
+++ b/ComfyUI/comfy/ldm/modules/diffusionmodules/openaimodel.py
@@ -0,0 +1,927 @@
+from abc import abstractmethod
+
+import torch as th
+import torch.nn as nn
+import torch.nn.functional as F
+from einops import rearrange
+import logging
+
+from .util import (
+ checkpoint,
+ avg_pool_nd,
+ timestep_embedding,
+ AlphaBlender,
+)
+from ..attention import SpatialTransformer, SpatialVideoTransformer, default
+from comfy.ldm.util import exists
+import comfy.patcher_extension
+import comfy.ops
+ops = comfy.ops.disable_weight_init
+
+from ..sdpose import HeatmapHead
+
+class TimestepBlock(nn.Module):
+ """
+ Any module where forward() takes timestep embeddings as a second argument.
+ """
+
+ @abstractmethod
+ def forward(self, x, emb):
+ """
+ Apply the module to `x` given `emb` timestep embeddings.
+ """
+
+#This is needed because accelerate makes a copy of transformer_options which breaks "transformer_index"
+def forward_timestep_embed(ts, x, emb, context=None, transformer_options={}, output_shape=None, time_context=None, num_video_frames=None, image_only_indicator=None):
+ for layer in ts:
+ if "patches" in transformer_options and "forward_timestep_embed_patch" in transformer_options["patches"]:
+ found_patched = False
+ for class_type, handler in transformer_options["patches"]["forward_timestep_embed_patch"]:
+ if isinstance(layer, class_type):
+ x = handler(layer, x, emb, context, transformer_options, output_shape, time_context, num_video_frames, image_only_indicator)
+ found_patched = True
+ break
+ if found_patched:
+ continue
+
+ if isinstance(layer, VideoResBlock):
+ x = layer(x, emb, num_video_frames, image_only_indicator)
+ elif isinstance(layer, TimestepBlock):
+ x = layer(x, emb)
+ elif isinstance(layer, SpatialVideoTransformer):
+ x = layer(x, context, time_context, num_video_frames, image_only_indicator, transformer_options)
+ if "transformer_index" in transformer_options:
+ transformer_options["transformer_index"] += 1
+ elif isinstance(layer, SpatialTransformer):
+ x = layer(x, context, transformer_options)
+ if "transformer_index" in transformer_options:
+ transformer_options["transformer_index"] += 1
+ elif isinstance(layer, Upsample):
+ x = layer(x, output_shape=output_shape)
+ else:
+ x = layer(x)
+ return x
+
+class TimestepEmbedSequential(nn.Sequential, TimestepBlock):
+ """
+ A sequential module that passes timestep embeddings to the children that
+ support it as an extra input.
+ """
+
+ def forward(self, *args, **kwargs):
+ return forward_timestep_embed(self, *args, **kwargs)
+
+class Upsample(nn.Module):
+ """
+ An upsampling layer with an optional convolution.
+ :param channels: channels in the inputs and outputs.
+ :param use_conv: a bool determining if a convolution is applied.
+ :param dims: determines if the signal is 1D, 2D, or 3D. If 3D, then
+ upsampling occurs in the inner-two dimensions.
+ """
+
+ def __init__(self, channels, use_conv, dims=2, out_channels=None, padding=1, dtype=None, device=None, operations=ops):
+ super().__init__()
+ self.channels = channels
+ self.out_channels = out_channels or channels
+ self.use_conv = use_conv
+ self.dims = dims
+ if use_conv:
+ self.conv = operations.conv_nd(dims, self.channels, self.out_channels, 3, padding=padding, dtype=dtype, device=device)
+
+ def forward(self, x, output_shape=None):
+ assert x.shape[1] == self.channels
+ if self.dims == 3:
+ shape = [x.shape[2], x.shape[3] * 2, x.shape[4] * 2]
+ if output_shape is not None:
+ shape[1] = output_shape[3]
+ shape[2] = output_shape[4]
+ else:
+ shape = [x.shape[2] * 2, x.shape[3] * 2]
+ if output_shape is not None:
+ shape[0] = output_shape[2]
+ shape[1] = output_shape[3]
+
+ x = F.interpolate(x, size=shape, mode="nearest")
+ if self.use_conv:
+ x = self.conv(x)
+ return x
+
+class Downsample(nn.Module):
+ """
+ A downsampling layer with an optional convolution.
+ :param channels: channels in the inputs and outputs.
+ :param use_conv: a bool determining if a convolution is applied.
+ :param dims: determines if the signal is 1D, 2D, or 3D. If 3D, then
+ downsampling occurs in the inner-two dimensions.
+ """
+
+ def __init__(self, channels, use_conv, dims=2, out_channels=None, padding=1, dtype=None, device=None, operations=ops):
+ super().__init__()
+ self.channels = channels
+ self.out_channels = out_channels or channels
+ self.use_conv = use_conv
+ self.dims = dims
+ stride = 2 if dims != 3 else (1, 2, 2)
+ if use_conv:
+ self.op = operations.conv_nd(
+ dims, self.channels, self.out_channels, 3, stride=stride, padding=padding, dtype=dtype, device=device
+ )
+ else:
+ assert self.channels == self.out_channels
+ self.op = avg_pool_nd(dims, kernel_size=stride, stride=stride)
+
+ def forward(self, x):
+ assert x.shape[1] == self.channels
+ return self.op(x)
+
+
+class ResBlock(TimestepBlock):
+ """
+ A residual block that can optionally change the number of channels.
+ :param channels: the number of input channels.
+ :param emb_channels: the number of timestep embedding channels.
+ :param dropout: the rate of dropout.
+ :param out_channels: if specified, the number of out channels.
+ :param use_conv: if True and out_channels is specified, use a spatial
+ convolution instead of a smaller 1x1 convolution to change the
+ channels in the skip connection.
+ :param dims: determines if the signal is 1D, 2D, or 3D.
+ :param use_checkpoint: if True, use gradient checkpointing on this module.
+ :param up: if True, use this block for upsampling.
+ :param down: if True, use this block for downsampling.
+ """
+
+ def __init__(
+ self,
+ channels,
+ emb_channels,
+ dropout,
+ out_channels=None,
+ use_conv=False,
+ use_scale_shift_norm=False,
+ dims=2,
+ use_checkpoint=False,
+ up=False,
+ down=False,
+ kernel_size=3,
+ exchange_temb_dims=False,
+ skip_t_emb=False,
+ dtype=None,
+ device=None,
+ operations=ops
+ ):
+ super().__init__()
+ self.channels = channels
+ self.emb_channels = emb_channels
+ self.dropout = dropout
+ self.out_channels = out_channels or channels
+ self.use_conv = use_conv
+ self.use_checkpoint = use_checkpoint
+ self.use_scale_shift_norm = use_scale_shift_norm
+ self.exchange_temb_dims = exchange_temb_dims
+
+ if isinstance(kernel_size, list):
+ padding = [k // 2 for k in kernel_size]
+ else:
+ padding = kernel_size // 2
+
+ self.in_layers = nn.Sequential(
+ operations.GroupNorm(32, channels, dtype=dtype, device=device),
+ nn.SiLU(),
+ operations.conv_nd(dims, channels, self.out_channels, kernel_size, padding=padding, dtype=dtype, device=device),
+ )
+
+ self.updown = up or down
+
+ if up:
+ self.h_upd = Upsample(channels, False, dims, dtype=dtype, device=device)
+ self.x_upd = Upsample(channels, False, dims, dtype=dtype, device=device)
+ elif down:
+ self.h_upd = Downsample(channels, False, dims, dtype=dtype, device=device)
+ self.x_upd = Downsample(channels, False, dims, dtype=dtype, device=device)
+ else:
+ self.h_upd = self.x_upd = nn.Identity()
+
+ self.skip_t_emb = skip_t_emb
+ if self.skip_t_emb:
+ self.emb_layers = None
+ self.exchange_temb_dims = False
+ else:
+ self.emb_layers = nn.Sequential(
+ nn.SiLU(),
+ operations.Linear(
+ emb_channels,
+ 2 * self.out_channels if use_scale_shift_norm else self.out_channels, dtype=dtype, device=device
+ ),
+ )
+ self.out_layers = nn.Sequential(
+ operations.GroupNorm(32, self.out_channels, dtype=dtype, device=device),
+ nn.SiLU(),
+ nn.Dropout(p=dropout),
+ operations.conv_nd(dims, self.out_channels, self.out_channels, kernel_size, padding=padding, dtype=dtype, device=device)
+ ,
+ )
+
+ if self.out_channels == channels:
+ self.skip_connection = nn.Identity()
+ elif use_conv:
+ self.skip_connection = operations.conv_nd(
+ dims, channels, self.out_channels, kernel_size, padding=padding, dtype=dtype, device=device
+ )
+ else:
+ self.skip_connection = operations.conv_nd(dims, channels, self.out_channels, 1, dtype=dtype, device=device)
+
+ def forward(self, x, emb):
+ """
+ Apply the block to a Tensor, conditioned on a timestep embedding.
+ :param x: an [N x C x ...] Tensor of features.
+ :param emb: an [N x emb_channels] Tensor of timestep embeddings.
+ :return: an [N x C x ...] Tensor of outputs.
+ """
+ return checkpoint(
+ self._forward, (x, emb), self.parameters(), self.use_checkpoint
+ )
+
+
+ def _forward(self, x, emb):
+ if self.updown:
+ in_rest, in_conv = self.in_layers[:-1], self.in_layers[-1]
+ h = in_rest(x)
+ h = self.h_upd(h)
+ x = self.x_upd(x)
+ h = in_conv(h)
+ else:
+ h = self.in_layers(x)
+
+ emb_out = None
+ if not self.skip_t_emb:
+ emb_out = self.emb_layers(emb).type(h.dtype)
+ while len(emb_out.shape) < len(h.shape):
+ emb_out = emb_out[..., None]
+ if self.use_scale_shift_norm:
+ out_norm, out_rest = self.out_layers[0], self.out_layers[1:]
+ h = out_norm(h)
+ if emb_out is not None:
+ scale, shift = th.chunk(emb_out, 2, dim=1)
+ h *= (1 + scale)
+ h += shift
+ h = out_rest(h)
+ else:
+ if emb_out is not None:
+ if self.exchange_temb_dims:
+ emb_out = emb_out.movedim(1, 2)
+ h = h + emb_out
+ h = self.out_layers(h)
+ return self.skip_connection(x) + h
+
+
+class VideoResBlock(ResBlock):
+ def __init__(
+ self,
+ channels: int,
+ emb_channels: int,
+ dropout: float,
+ video_kernel_size=3,
+ merge_strategy: str = "fixed",
+ merge_factor: float = 0.5,
+ out_channels=None,
+ use_conv: bool = False,
+ use_scale_shift_norm: bool = False,
+ dims: int = 2,
+ use_checkpoint: bool = False,
+ up: bool = False,
+ down: bool = False,
+ dtype=None,
+ device=None,
+ operations=ops
+ ):
+ super().__init__(
+ channels,
+ emb_channels,
+ dropout,
+ out_channels=out_channels,
+ use_conv=use_conv,
+ use_scale_shift_norm=use_scale_shift_norm,
+ dims=dims,
+ use_checkpoint=use_checkpoint,
+ up=up,
+ down=down,
+ dtype=dtype,
+ device=device,
+ operations=operations
+ )
+
+ self.time_stack = ResBlock(
+ default(out_channels, channels),
+ emb_channels,
+ dropout=dropout,
+ dims=3,
+ out_channels=default(out_channels, channels),
+ use_scale_shift_norm=False,
+ use_conv=False,
+ up=False,
+ down=False,
+ kernel_size=video_kernel_size,
+ use_checkpoint=use_checkpoint,
+ exchange_temb_dims=True,
+ dtype=dtype,
+ device=device,
+ operations=operations
+ )
+ self.time_mixer = AlphaBlender(
+ alpha=merge_factor,
+ merge_strategy=merge_strategy,
+ rearrange_pattern="b t -> b 1 t 1 1",
+ )
+
+ def forward(
+ self,
+ x: th.Tensor,
+ emb: th.Tensor,
+ num_video_frames: int,
+ image_only_indicator = None,
+ ) -> th.Tensor:
+ x = super().forward(x, emb)
+
+ x_mix = rearrange(x, "(b t) c h w -> b c t h w", t=num_video_frames)
+ x = rearrange(x, "(b t) c h w -> b c t h w", t=num_video_frames)
+
+ x = self.time_stack(
+ x, rearrange(emb, "(b t) ... -> b t ...", t=num_video_frames)
+ )
+ x = self.time_mixer(
+ x_spatial=x_mix, x_temporal=x, image_only_indicator=image_only_indicator
+ )
+ x = rearrange(x, "b c t h w -> (b t) c h w")
+ return x
+
+
+class Timestep(nn.Module):
+ def __init__(self, dim):
+ super().__init__()
+ self.dim = dim
+
+ def forward(self, t):
+ return timestep_embedding(t, self.dim)
+
+def apply_control(h, control, name):
+ if control is not None and name in control and len(control[name]) > 0:
+ ctrl = control[name].pop()
+ if ctrl is not None:
+ try:
+ h += ctrl
+ except:
+ logging.warning("warning control could not be applied {} {}".format(h.shape, ctrl.shape))
+ return h
+
+class UNetModel(nn.Module):
+ """
+ The full UNet model with attention and timestep embedding.
+ :param in_channels: channels in the input Tensor.
+ :param model_channels: base channel count for the model.
+ :param out_channels: channels in the output Tensor.
+ :param num_res_blocks: number of residual blocks per downsample.
+ :param dropout: the dropout probability.
+ :param channel_mult: channel multiplier for each level of the UNet.
+ :param conv_resample: if True, use learned convolutions for upsampling and
+ downsampling.
+ :param dims: determines if the signal is 1D, 2D, or 3D.
+ :param num_classes: if specified (as an int), then this model will be
+ class-conditional with `num_classes` classes.
+ :param use_checkpoint: use gradient checkpointing to reduce memory usage.
+ :param num_heads: the number of attention heads in each attention layer.
+ :param num_heads_channels: if specified, ignore num_heads and instead use
+ a fixed channel width per attention head.
+ :param num_heads_upsample: works with num_heads to set a different number
+ of heads for upsampling. Deprecated.
+ :param use_scale_shift_norm: use a FiLM-like conditioning mechanism.
+ :param resblock_updown: use residual blocks for up/downsampling.
+ :param use_new_attention_order: use a different attention pattern for potentially
+ increased efficiency.
+ """
+
+ def __init__(
+ self,
+ image_size,
+ in_channels,
+ model_channels,
+ out_channels,
+ num_res_blocks,
+ dropout=0,
+ channel_mult=(1, 2, 4, 8),
+ conv_resample=True,
+ dims=2,
+ num_classes=None,
+ use_checkpoint=False,
+ dtype=th.float32,
+ num_heads=-1,
+ num_head_channels=-1,
+ num_heads_upsample=-1,
+ use_scale_shift_norm=False,
+ resblock_updown=False,
+ use_new_attention_order=False,
+ use_spatial_transformer=False, # custom transformer support
+ transformer_depth=1, # custom transformer support
+ context_dim=None, # custom transformer support
+ n_embed=None, # custom support for prediction of discrete ids into codebook of first stage vq model
+ legacy=True,
+ disable_self_attentions=None,
+ num_attention_blocks=None,
+ disable_middle_self_attn=False,
+ use_linear_in_transformer=False,
+ adm_in_channels=None,
+ transformer_depth_middle=None,
+ transformer_depth_output=None,
+ use_temporal_resblock=False,
+ use_temporal_attention=False,
+ time_context_dim=None,
+ extra_ff_mix_layer=False,
+ use_spatial_context=False,
+ merge_strategy=None,
+ merge_factor=0.0,
+ video_kernel_size=None,
+ disable_temporal_crossattention=False,
+ max_ddpm_temb_period=10000,
+ attn_precision=None,
+ heatmap_head=False,
+ device=None,
+ operations=ops,
+ ):
+ super().__init__()
+
+ if context_dim is not None:
+ assert use_spatial_transformer, 'Fool!! You forgot to use the spatial transformer for your cross-attention conditioning...'
+ # from omegaconf.listconfig import ListConfig
+ # if type(context_dim) == ListConfig:
+ # context_dim = list(context_dim)
+
+ if num_heads_upsample == -1:
+ num_heads_upsample = num_heads
+
+ if num_heads == -1:
+ assert num_head_channels != -1, 'Either num_heads or num_head_channels has to be set'
+
+ if num_head_channels == -1:
+ assert num_heads != -1, 'Either num_heads or num_head_channels has to be set'
+
+ self.in_channels = in_channels
+ self.model_channels = model_channels
+ self.out_channels = out_channels
+
+ if isinstance(num_res_blocks, int):
+ self.num_res_blocks = len(channel_mult) * [num_res_blocks]
+ else:
+ if len(num_res_blocks) != len(channel_mult):
+ raise ValueError("provide num_res_blocks either as an int (globally constant) or "
+ "as a list/tuple (per-level) with the same length as channel_mult")
+ self.num_res_blocks = num_res_blocks
+
+ if disable_self_attentions is not None:
+ # should be a list of booleans, indicating whether to disable self-attention in TransformerBlocks or not
+ assert len(disable_self_attentions) == len(channel_mult)
+ if num_attention_blocks is not None:
+ assert len(num_attention_blocks) == len(self.num_res_blocks)
+
+ transformer_depth = transformer_depth[:]
+ transformer_depth_output = transformer_depth_output[:]
+
+ self.dropout = dropout
+ self.channel_mult = channel_mult
+ self.conv_resample = conv_resample
+ self.num_classes = num_classes
+ self.use_checkpoint = use_checkpoint
+ self.dtype = dtype
+ self.num_heads = num_heads
+ self.num_head_channels = num_head_channels
+ self.num_heads_upsample = num_heads_upsample
+ self.use_temporal_resblocks = use_temporal_resblock
+ self.predict_codebook_ids = n_embed is not None
+
+ self.default_num_video_frames = None
+
+ time_embed_dim = model_channels * 4
+ self.time_embed = nn.Sequential(
+ operations.Linear(model_channels, time_embed_dim, dtype=self.dtype, device=device),
+ nn.SiLU(),
+ operations.Linear(time_embed_dim, time_embed_dim, dtype=self.dtype, device=device),
+ )
+
+ if self.num_classes is not None:
+ if isinstance(self.num_classes, int):
+ self.label_emb = nn.Embedding(num_classes, time_embed_dim, dtype=self.dtype, device=device)
+ elif self.num_classes == "continuous":
+ logging.debug("setting up linear c_adm embedding layer")
+ self.label_emb = nn.Linear(1, time_embed_dim)
+ elif self.num_classes == "sequential":
+ assert adm_in_channels is not None
+ self.label_emb = nn.Sequential(
+ nn.Sequential(
+ operations.Linear(adm_in_channels, time_embed_dim, dtype=self.dtype, device=device),
+ nn.SiLU(),
+ operations.Linear(time_embed_dim, time_embed_dim, dtype=self.dtype, device=device),
+ )
+ )
+ else:
+ raise ValueError()
+
+ self.input_blocks = nn.ModuleList(
+ [
+ TimestepEmbedSequential(
+ operations.conv_nd(dims, in_channels, model_channels, 3, padding=1, dtype=self.dtype, device=device)
+ )
+ ]
+ )
+ self._feature_size = model_channels
+ input_block_chans = [model_channels]
+ ch = model_channels
+ ds = 1
+
+ def get_attention_layer(
+ ch,
+ num_heads,
+ dim_head,
+ depth=1,
+ context_dim=None,
+ use_checkpoint=False,
+ disable_self_attn=False,
+ ):
+ if use_temporal_attention:
+ return SpatialVideoTransformer(
+ ch,
+ num_heads,
+ dim_head,
+ depth=depth,
+ context_dim=context_dim,
+ time_context_dim=time_context_dim,
+ dropout=dropout,
+ ff_in=extra_ff_mix_layer,
+ use_spatial_context=use_spatial_context,
+ merge_strategy=merge_strategy,
+ merge_factor=merge_factor,
+ checkpoint=use_checkpoint,
+ use_linear=use_linear_in_transformer,
+ disable_self_attn=disable_self_attn,
+ disable_temporal_crossattention=disable_temporal_crossattention,
+ max_time_embed_period=max_ddpm_temb_period,
+ attn_precision=attn_precision,
+ dtype=self.dtype, device=device, operations=operations
+ )
+ else:
+ return SpatialTransformer(
+ ch, num_heads, dim_head, depth=depth, context_dim=context_dim,
+ disable_self_attn=disable_self_attn, use_linear=use_linear_in_transformer,
+ use_checkpoint=use_checkpoint, attn_precision=attn_precision, dtype=self.dtype, device=device, operations=operations
+ )
+
+ def get_resblock(
+ merge_factor,
+ merge_strategy,
+ video_kernel_size,
+ ch,
+ time_embed_dim,
+ dropout,
+ out_channels,
+ dims,
+ use_checkpoint,
+ use_scale_shift_norm,
+ down=False,
+ up=False,
+ dtype=None,
+ device=None,
+ operations=ops
+ ):
+ if self.use_temporal_resblocks:
+ return VideoResBlock(
+ merge_factor=merge_factor,
+ merge_strategy=merge_strategy,
+ video_kernel_size=video_kernel_size,
+ channels=ch,
+ emb_channels=time_embed_dim,
+ dropout=dropout,
+ out_channels=out_channels,
+ dims=dims,
+ use_checkpoint=use_checkpoint,
+ use_scale_shift_norm=use_scale_shift_norm,
+ down=down,
+ up=up,
+ dtype=dtype,
+ device=device,
+ operations=operations
+ )
+ else:
+ return ResBlock(
+ channels=ch,
+ emb_channels=time_embed_dim,
+ dropout=dropout,
+ out_channels=out_channels,
+ use_checkpoint=use_checkpoint,
+ dims=dims,
+ use_scale_shift_norm=use_scale_shift_norm,
+ down=down,
+ up=up,
+ dtype=dtype,
+ device=device,
+ operations=operations
+ )
+
+ for level, mult in enumerate(channel_mult):
+ for nr in range(self.num_res_blocks[level]):
+ layers = [
+ get_resblock(
+ merge_factor=merge_factor,
+ merge_strategy=merge_strategy,
+ video_kernel_size=video_kernel_size,
+ ch=ch,
+ time_embed_dim=time_embed_dim,
+ dropout=dropout,
+ out_channels=mult * model_channels,
+ dims=dims,
+ use_checkpoint=use_checkpoint,
+ use_scale_shift_norm=use_scale_shift_norm,
+ dtype=self.dtype,
+ device=device,
+ operations=operations,
+ )
+ ]
+ ch = mult * model_channels
+ num_transformers = transformer_depth.pop(0)
+ if num_transformers > 0:
+ if num_head_channels == -1:
+ dim_head = ch // num_heads
+ else:
+ num_heads = ch // num_head_channels
+ dim_head = num_head_channels
+ if legacy:
+ #num_heads = 1
+ dim_head = ch // num_heads if use_spatial_transformer else num_head_channels
+ if exists(disable_self_attentions):
+ disabled_sa = disable_self_attentions[level]
+ else:
+ disabled_sa = False
+
+ if not exists(num_attention_blocks) or nr < num_attention_blocks[level]:
+ layers.append(get_attention_layer(
+ ch, num_heads, dim_head, depth=num_transformers, context_dim=context_dim,
+ disable_self_attn=disabled_sa, use_checkpoint=use_checkpoint)
+ )
+ self.input_blocks.append(TimestepEmbedSequential(*layers))
+ self._feature_size += ch
+ input_block_chans.append(ch)
+ if level != len(channel_mult) - 1:
+ out_ch = ch
+ self.input_blocks.append(
+ TimestepEmbedSequential(
+ get_resblock(
+ merge_factor=merge_factor,
+ merge_strategy=merge_strategy,
+ video_kernel_size=video_kernel_size,
+ ch=ch,
+ time_embed_dim=time_embed_dim,
+ dropout=dropout,
+ out_channels=out_ch,
+ dims=dims,
+ use_checkpoint=use_checkpoint,
+ use_scale_shift_norm=use_scale_shift_norm,
+ down=True,
+ dtype=self.dtype,
+ device=device,
+ operations=operations
+ )
+ if resblock_updown
+ else Downsample(
+ ch, conv_resample, dims=dims, out_channels=out_ch, dtype=self.dtype, device=device, operations=operations
+ )
+ )
+ )
+ ch = out_ch
+ input_block_chans.append(ch)
+ ds *= 2
+ self._feature_size += ch
+
+ if num_head_channels == -1:
+ dim_head = ch // num_heads
+ else:
+ num_heads = ch // num_head_channels
+ dim_head = num_head_channels
+ if legacy:
+ #num_heads = 1
+ dim_head = ch // num_heads if use_spatial_transformer else num_head_channels
+ mid_block = [
+ get_resblock(
+ merge_factor=merge_factor,
+ merge_strategy=merge_strategy,
+ video_kernel_size=video_kernel_size,
+ ch=ch,
+ time_embed_dim=time_embed_dim,
+ dropout=dropout,
+ out_channels=None,
+ dims=dims,
+ use_checkpoint=use_checkpoint,
+ use_scale_shift_norm=use_scale_shift_norm,
+ dtype=self.dtype,
+ device=device,
+ operations=operations
+ )]
+
+ self.middle_block = None
+ if transformer_depth_middle >= -1:
+ if transformer_depth_middle >= 0:
+ mid_block += [get_attention_layer( # always uses a self-attn
+ ch, num_heads, dim_head, depth=transformer_depth_middle, context_dim=context_dim,
+ disable_self_attn=disable_middle_self_attn, use_checkpoint=use_checkpoint
+ ),
+ get_resblock(
+ merge_factor=merge_factor,
+ merge_strategy=merge_strategy,
+ video_kernel_size=video_kernel_size,
+ ch=ch,
+ time_embed_dim=time_embed_dim,
+ dropout=dropout,
+ out_channels=None,
+ dims=dims,
+ use_checkpoint=use_checkpoint,
+ use_scale_shift_norm=use_scale_shift_norm,
+ dtype=self.dtype,
+ device=device,
+ operations=operations
+ )]
+ self.middle_block = TimestepEmbedSequential(*mid_block)
+ self._feature_size += ch
+
+ self.output_blocks = nn.ModuleList([])
+ for level, mult in list(enumerate(channel_mult))[::-1]:
+ for i in range(self.num_res_blocks[level] + 1):
+ ich = input_block_chans.pop()
+ layers = [
+ get_resblock(
+ merge_factor=merge_factor,
+ merge_strategy=merge_strategy,
+ video_kernel_size=video_kernel_size,
+ ch=ch + ich,
+ time_embed_dim=time_embed_dim,
+ dropout=dropout,
+ out_channels=model_channels * mult,
+ dims=dims,
+ use_checkpoint=use_checkpoint,
+ use_scale_shift_norm=use_scale_shift_norm,
+ dtype=self.dtype,
+ device=device,
+ operations=operations
+ )
+ ]
+ ch = model_channels * mult
+ num_transformers = transformer_depth_output.pop()
+ if num_transformers > 0:
+ if num_head_channels == -1:
+ dim_head = ch // num_heads
+ else:
+ num_heads = ch // num_head_channels
+ dim_head = num_head_channels
+ if legacy:
+ #num_heads = 1
+ dim_head = ch // num_heads if use_spatial_transformer else num_head_channels
+ if exists(disable_self_attentions):
+ disabled_sa = disable_self_attentions[level]
+ else:
+ disabled_sa = False
+
+ if not exists(num_attention_blocks) or i < num_attention_blocks[level]:
+ layers.append(
+ get_attention_layer(
+ ch, num_heads, dim_head, depth=num_transformers, context_dim=context_dim,
+ disable_self_attn=disabled_sa, use_checkpoint=use_checkpoint
+ )
+ )
+ if level and i == self.num_res_blocks[level]:
+ out_ch = ch
+ layers.append(
+ get_resblock(
+ merge_factor=merge_factor,
+ merge_strategy=merge_strategy,
+ video_kernel_size=video_kernel_size,
+ ch=ch,
+ time_embed_dim=time_embed_dim,
+ dropout=dropout,
+ out_channels=out_ch,
+ dims=dims,
+ use_checkpoint=use_checkpoint,
+ use_scale_shift_norm=use_scale_shift_norm,
+ up=True,
+ dtype=self.dtype,
+ device=device,
+ operations=operations
+ )
+ if resblock_updown
+ else Upsample(ch, conv_resample, dims=dims, out_channels=out_ch, dtype=self.dtype, device=device, operations=operations)
+ )
+ ds //= 2
+ self.output_blocks.append(TimestepEmbedSequential(*layers))
+ self._feature_size += ch
+
+ self.out = nn.Sequential(
+ operations.GroupNorm(32, ch, dtype=self.dtype, device=device),
+ nn.SiLU(),
+ operations.conv_nd(dims, model_channels, out_channels, 3, padding=1, dtype=self.dtype, device=device),
+ )
+ if self.predict_codebook_ids:
+ self.id_predictor = nn.Sequential(
+ operations.GroupNorm(32, ch, dtype=self.dtype, device=device),
+ operations.conv_nd(dims, model_channels, n_embed, 1, dtype=self.dtype, device=device),
+ #nn.LogSoftmax(dim=1) # change to cross_entropy and produce non-normalized logits
+ )
+
+ if heatmap_head:
+ self.heatmap_head = HeatmapHead(device=device, dtype=self.dtype, operations=operations)
+
+ def forward(self, x, timesteps=None, context=None, y=None, control=None, transformer_options={}, **kwargs):
+ return comfy.patcher_extension.WrapperExecutor.new_class_executor(
+ self._forward,
+ self,
+ comfy.patcher_extension.get_all_wrappers(comfy.patcher_extension.WrappersMP.DIFFUSION_MODEL, transformer_options)
+ ).execute(x, timesteps, context, y, control, transformer_options, **kwargs)
+
+ def _forward(self, x, timesteps=None, context=None, y=None, control=None, transformer_options={}, **kwargs):
+ """
+ Apply the model to an input batch.
+ :param x: an [N x C x ...] Tensor of inputs.
+ :param timesteps: a 1-D batch of timesteps.
+ :param context: conditioning plugged in via crossattn
+ :param y: an [N] Tensor of labels, if class-conditional.
+ :return: an [N x C x ...] Tensor of outputs.
+ """
+ transformer_options["original_shape"] = list(x.shape)
+ transformer_options["transformer_index"] = 0
+ transformer_patches = transformer_options.get("patches", {})
+
+ num_video_frames = kwargs.get("num_video_frames", self.default_num_video_frames)
+ image_only_indicator = kwargs.get("image_only_indicator", None)
+ time_context = kwargs.get("time_context", None)
+
+ assert (y is not None) == (
+ self.num_classes is not None
+ ), "must specify y if and only if the model is class-conditional"
+ hs = []
+ t_emb = timestep_embedding(timesteps, self.model_channels, repeat_only=False).to(x.dtype)
+ emb = self.time_embed(t_emb)
+
+ if "emb_patch" in transformer_patches:
+ patch = transformer_patches["emb_patch"]
+ for p in patch:
+ emb = p(emb, self.model_channels, transformer_options)
+
+ if self.num_classes is not None:
+ assert y.shape[0] == x.shape[0]
+ emb = emb + self.label_emb(y)
+
+ h = x
+ for id, module in enumerate(self.input_blocks):
+ transformer_options["block"] = ("input", id)
+ h = forward_timestep_embed(module, h, emb, context, transformer_options, time_context=time_context, num_video_frames=num_video_frames, image_only_indicator=image_only_indicator)
+ h = apply_control(h, control, 'input')
+ if "input_block_patch" in transformer_patches:
+ patch = transformer_patches["input_block_patch"]
+ for p in patch:
+ h = p(h, transformer_options)
+
+ hs.append(h)
+ if "input_block_patch_after_skip" in transformer_patches:
+ patch = transformer_patches["input_block_patch_after_skip"]
+ for p in patch:
+ h = p(h, transformer_options)
+
+ transformer_options["block"] = ("middle", 0)
+ if self.middle_block is not None:
+ h = forward_timestep_embed(self.middle_block, h, emb, context, transformer_options, time_context=time_context, num_video_frames=num_video_frames, image_only_indicator=image_only_indicator)
+ h = apply_control(h, control, 'middle')
+
+ if "middle_block_after_patch" in transformer_patches:
+ patch = transformer_patches["middle_block_after_patch"]
+ for p in patch:
+ out = p({"h": h, "x": x, "emb": emb, "context": context, "y": y,
+ "timesteps": timesteps, "transformer_options": transformer_options})
+ h = out["h"]
+
+ for id, module in enumerate(self.output_blocks):
+ transformer_options["block"] = ("output", id)
+ hsp = hs.pop()
+ hsp = apply_control(hsp, control, 'output')
+
+ if "output_block_patch" in transformer_patches:
+ patch = transformer_patches["output_block_patch"]
+ for p in patch:
+ h, hsp = p(h, hsp, transformer_options)
+
+ if hsp is not None:
+ h = th.cat([h, hsp], dim=1)
+ del hsp
+ if len(hs) > 0:
+ output_shape = hs[-1].shape
+ else:
+ output_shape = None
+ h = forward_timestep_embed(module, h, emb, context, transformer_options, output_shape, time_context=time_context, num_video_frames=num_video_frames, image_only_indicator=image_only_indicator)
+ h = h.type(x.dtype)
+ if self.predict_codebook_ids:
+ return self.id_predictor(h)
+ else:
+ return self.out(h)
diff --git a/ComfyUI/comfy/ldm/modules/diffusionmodules/upscaling.py b/ComfyUI/comfy/ldm/modules/diffusionmodules/upscaling.py
new file mode 100644
index 0000000000000000000000000000000000000000..9dbf1fe7b93b0c7f1a9e8cbf8e89d0b33c282a08
--- /dev/null
+++ b/ComfyUI/comfy/ldm/modules/diffusionmodules/upscaling.py
@@ -0,0 +1,84 @@
+import torch
+import torch.nn as nn
+import numpy as np
+from functools import partial
+
+from .util import extract_into_tensor, make_beta_schedule
+
+
+class AbstractLowScaleModel(nn.Module):
+ # for concatenating a downsampled image to the latent representation
+ def __init__(self, noise_schedule_config=None):
+ super(AbstractLowScaleModel, self).__init__()
+ if noise_schedule_config is not None:
+ self.register_schedule(**noise_schedule_config)
+
+ def register_schedule(self, beta_schedule="linear", timesteps=1000,
+ linear_start=1e-4, linear_end=2e-2, cosine_s=8e-3):
+ betas = make_beta_schedule(beta_schedule, timesteps, linear_start=linear_start, linear_end=linear_end,
+ cosine_s=cosine_s)
+ alphas = 1. - betas
+ alphas_cumprod = np.cumprod(alphas, axis=0)
+ alphas_cumprod_prev = np.append(1., alphas_cumprod[:-1])
+
+ timesteps, = betas.shape
+ self.num_timesteps = int(timesteps)
+ self.linear_start = linear_start
+ self.linear_end = linear_end
+ assert alphas_cumprod.shape[0] == self.num_timesteps, 'alphas have to be defined for each timestep'
+
+ to_torch = partial(torch.tensor, dtype=torch.float32)
+
+ self.register_buffer('betas', to_torch(betas))
+ self.register_buffer('alphas_cumprod', to_torch(alphas_cumprod))
+ self.register_buffer('alphas_cumprod_prev', to_torch(alphas_cumprod_prev))
+
+ # calculations for diffusion q(x_t | x_{t-1}) and others
+ self.register_buffer('sqrt_alphas_cumprod', to_torch(np.sqrt(alphas_cumprod)))
+ self.register_buffer('sqrt_one_minus_alphas_cumprod', to_torch(np.sqrt(1. - alphas_cumprod)))
+ self.register_buffer('log_one_minus_alphas_cumprod', to_torch(np.log(1. - alphas_cumprod)))
+ self.register_buffer('sqrt_recip_alphas_cumprod', to_torch(np.sqrt(1. / alphas_cumprod)))
+ self.register_buffer('sqrt_recipm1_alphas_cumprod', to_torch(np.sqrt(1. / alphas_cumprod - 1)))
+
+ def q_sample(self, x_start, t, noise=None, seed=None):
+ if noise is None:
+ if seed is None:
+ noise = torch.randn_like(x_start)
+ else:
+ noise = torch.randn(x_start.size(), dtype=x_start.dtype, layout=x_start.layout, generator=torch.manual_seed(seed)).to(x_start.device)
+ return (extract_into_tensor(self.sqrt_alphas_cumprod.to(x_start.device), t, x_start.shape) * x_start +
+ extract_into_tensor(self.sqrt_one_minus_alphas_cumprod.to(x_start.device), t, x_start.shape) * noise)
+
+ def forward(self, x):
+ return x, None
+
+ def decode(self, x):
+ return x
+
+
+class SimpleImageConcat(AbstractLowScaleModel):
+ # no noise level conditioning
+ def __init__(self):
+ super(SimpleImageConcat, self).__init__(noise_schedule_config=None)
+ self.max_noise_level = 0
+
+ def forward(self, x):
+ # fix to constant noise level
+ return x, torch.zeros(x.shape[0], device=x.device).long()
+
+
+class ImageConcatWithNoiseAugmentation(AbstractLowScaleModel):
+ def __init__(self, noise_schedule_config, max_noise_level=1000, to_cuda=False):
+ super().__init__(noise_schedule_config=noise_schedule_config)
+ self.max_noise_level = max_noise_level
+
+ def forward(self, x, noise_level=None, seed=None):
+ if noise_level is None:
+ noise_level = torch.randint(0, self.max_noise_level, (x.shape[0],), device=x.device).long()
+ else:
+ assert isinstance(noise_level, torch.Tensor)
+ z = self.q_sample(x, noise_level, seed=seed)
+ return z, noise_level
+
+
+
diff --git a/ComfyUI/comfy/ldm/modules/diffusionmodules/util.py b/ComfyUI/comfy/ldm/modules/diffusionmodules/util.py
new file mode 100644
index 0000000000000000000000000000000000000000..aed5c149c580b947eb2c20b03cbfe073f3d7abe8
--- /dev/null
+++ b/ComfyUI/comfy/ldm/modules/diffusionmodules/util.py
@@ -0,0 +1,306 @@
+# adopted from
+# https://github.com/openai/improved-diffusion/blob/main/improved_diffusion/gaussian_diffusion.py
+# and
+# https://github.com/lucidrains/denoising-diffusion-pytorch/blob/7706bdfc6f527f58d33f84b7b522e61e6e3164b3/denoising_diffusion_pytorch/denoising_diffusion_pytorch.py
+# and
+# https://github.com/openai/guided-diffusion/blob/0ba878e517b276c45d1195eb29f6f5f72659a05b/guided_diffusion/nn.py
+#
+# thanks!
+
+
+import math
+import logging
+import torch
+import torch.nn as nn
+import numpy as np
+from einops import repeat, rearrange
+
+from comfy.ldm.util import instantiate_from_config
+
+class AlphaBlender(nn.Module):
+ strategies = ["learned", "fixed", "learned_with_images"]
+
+ def __init__(
+ self,
+ alpha: float,
+ merge_strategy: str = "learned_with_images",
+ rearrange_pattern: str = "b t -> (b t) 1 1",
+ ):
+ super().__init__()
+ self.merge_strategy = merge_strategy
+ self.rearrange_pattern = rearrange_pattern
+
+ assert (
+ merge_strategy in self.strategies
+ ), f"merge_strategy needs to be in {self.strategies}"
+
+ if self.merge_strategy == "fixed":
+ self.register_buffer("mix_factor", torch.Tensor([alpha]))
+ elif (
+ self.merge_strategy == "learned"
+ or self.merge_strategy == "learned_with_images"
+ ):
+ self.register_parameter(
+ "mix_factor", torch.nn.Parameter(torch.Tensor([alpha]))
+ )
+ else:
+ raise ValueError(f"unknown merge strategy {self.merge_strategy}")
+
+ def get_alpha(self, image_only_indicator: torch.Tensor, device) -> torch.Tensor:
+ # skip_time_mix = rearrange(repeat(skip_time_mix, 'b -> (b t) () () ()', t=t), '(b t) 1 ... -> b 1 t ...', t=t)
+ if self.merge_strategy == "fixed":
+ # make shape compatible
+ # alpha = repeat(self.mix_factor, '1 -> b () t () ()', t=t, b=bs)
+ alpha = self.mix_factor.to(device)
+ elif self.merge_strategy == "learned":
+ alpha = torch.sigmoid(self.mix_factor.to(device))
+ # make shape compatible
+ # alpha = repeat(alpha, '1 -> s () ()', s = t * bs)
+ elif self.merge_strategy == "learned_with_images":
+ if image_only_indicator is None:
+ alpha = rearrange(torch.sigmoid(self.mix_factor.to(device)), "... -> ... 1")
+ else:
+ alpha = torch.where(
+ image_only_indicator.bool(),
+ torch.ones(1, 1, device=image_only_indicator.device),
+ rearrange(torch.sigmoid(self.mix_factor.to(image_only_indicator.device)), "... -> ... 1"),
+ )
+ alpha = rearrange(alpha, self.rearrange_pattern)
+ # make shape compatible
+ # alpha = repeat(alpha, '1 -> s () ()', s = t * bs)
+ else:
+ raise NotImplementedError()
+ return alpha
+
+ def forward(
+ self,
+ x_spatial,
+ x_temporal,
+ image_only_indicator=None,
+ ) -> torch.Tensor:
+ alpha = self.get_alpha(image_only_indicator, x_spatial.device)
+ x = (
+ alpha.to(x_spatial.dtype) * x_spatial
+ + (1.0 - alpha).to(x_spatial.dtype) * x_temporal
+ )
+ return x
+
+
+def make_beta_schedule(schedule, n_timestep, linear_start=1e-4, linear_end=2e-2, cosine_s=8e-3):
+ if schedule == "linear":
+ betas = (
+ torch.linspace(linear_start ** 0.5, linear_end ** 0.5, n_timestep, dtype=torch.float64) ** 2
+ )
+
+ elif schedule == "cosine":
+ timesteps = (
+ torch.arange(n_timestep + 1, dtype=torch.float64) / n_timestep + cosine_s
+ )
+ alphas = timesteps / (1 + cosine_s) * np.pi / 2
+ alphas = torch.cos(alphas).pow(2)
+ alphas = alphas / alphas[0]
+ betas = 1 - alphas[1:] / alphas[:-1]
+ betas = torch.clamp(betas, min=0, max=0.999)
+
+ elif schedule == "squaredcos_cap_v2": # used for karlo prior
+ # return early
+ return betas_for_alpha_bar(
+ n_timestep,
+ lambda t: math.cos((t + 0.008) / 1.008 * math.pi / 2) ** 2,
+ )
+
+ elif schedule == "sqrt_linear":
+ betas = torch.linspace(linear_start, linear_end, n_timestep, dtype=torch.float64)
+ elif schedule == "sqrt":
+ betas = torch.linspace(linear_start, linear_end, n_timestep, dtype=torch.float64) ** 0.5
+ else:
+ raise ValueError(f"schedule '{schedule}' unknown.")
+ return betas
+
+
+def make_ddim_timesteps(ddim_discr_method, num_ddim_timesteps, num_ddpm_timesteps, verbose=True):
+ if ddim_discr_method == 'uniform':
+ c = num_ddpm_timesteps // num_ddim_timesteps
+ ddim_timesteps = np.asarray(list(range(0, num_ddpm_timesteps, c)))
+ elif ddim_discr_method == 'quad':
+ ddim_timesteps = ((np.linspace(0, np.sqrt(num_ddpm_timesteps * .8), num_ddim_timesteps)) ** 2).astype(int)
+ else:
+ raise NotImplementedError(f'There is no ddim discretization method called "{ddim_discr_method}"')
+
+ # assert ddim_timesteps.shape[0] == num_ddim_timesteps
+ # add one to get the final alpha values right (the ones from first scale to data during sampling)
+ steps_out = ddim_timesteps + 1
+ if verbose:
+ logging.info(f'Selected timesteps for ddim sampler: {steps_out}')
+ return steps_out
+
+
+def make_ddim_sampling_parameters(alphacums, ddim_timesteps, eta, verbose=True):
+ # select alphas for computing the variance schedule
+ alphas = alphacums[ddim_timesteps]
+ alphas_prev = np.asarray([alphacums[0]] + alphacums[ddim_timesteps[:-1]].tolist())
+
+ # according to the formula provided in https://arxiv.org/abs/2010.02502
+ sigmas = eta * np.sqrt((1 - alphas_prev) / (1 - alphas) * (1 - alphas / alphas_prev))
+ if verbose:
+ logging.info(f'Selected alphas for ddim sampler: a_t: {alphas}; a_(t-1): {alphas_prev}')
+ logging.info(f'For the chosen value of eta, which is {eta}, '
+ f'this results in the following sigma_t schedule for ddim sampler {sigmas}')
+ return sigmas, alphas, alphas_prev
+
+
+def betas_for_alpha_bar(num_diffusion_timesteps, alpha_bar, max_beta=0.999):
+ """
+ Create a beta schedule that discretizes the given alpha_t_bar function,
+ which defines the cumulative product of (1-beta) over time from t = [0,1].
+ :param num_diffusion_timesteps: the number of betas to produce.
+ :param alpha_bar: a lambda that takes an argument t from 0 to 1 and
+ produces the cumulative product of (1-beta) up to that
+ part of the diffusion process.
+ :param max_beta: the maximum beta to use; use values lower than 1 to
+ prevent singularities.
+ """
+ betas = []
+ for i in range(num_diffusion_timesteps):
+ t1 = i / num_diffusion_timesteps
+ t2 = (i + 1) / num_diffusion_timesteps
+ betas.append(min(1 - alpha_bar(t2) / alpha_bar(t1), max_beta))
+ return np.array(betas)
+
+
+def extract_into_tensor(a, t, x_shape):
+ b, *_ = t.shape
+ out = a.gather(-1, t)
+ return out.reshape(b, *((1,) * (len(x_shape) - 1)))
+
+
+def checkpoint(func, inputs, params, flag):
+ """
+ Evaluate a function without caching intermediate activations, allowing for
+ reduced memory at the expense of extra compute in the backward pass.
+ :param func: the function to evaluate.
+ :param inputs: the argument sequence to pass to `func`.
+ :param params: a sequence of parameters `func` depends on but does not
+ explicitly take as arguments.
+ :param flag: if False, disable gradient checkpointing.
+ """
+ if flag:
+ args = tuple(inputs) + tuple(params)
+ return CheckpointFunction.apply(func, len(inputs), *args)
+ else:
+ return func(*inputs)
+
+
+class CheckpointFunction(torch.autograd.Function):
+ @staticmethod
+ def forward(ctx, run_function, length, *args):
+ ctx.run_function = run_function
+ ctx.input_tensors = list(args[:length])
+ ctx.input_params = list(args[length:])
+ ctx.gpu_autocast_kwargs = {"enabled": torch.is_autocast_enabled(),
+ "dtype": torch.get_autocast_gpu_dtype(),
+ "cache_enabled": torch.is_autocast_cache_enabled()}
+ with torch.no_grad():
+ output_tensors = ctx.run_function(*ctx.input_tensors)
+ return output_tensors
+
+ @staticmethod
+ def backward(ctx, *output_grads):
+ ctx.input_tensors = [x.detach().requires_grad_(True) for x in ctx.input_tensors]
+ with torch.enable_grad(), \
+ torch.cuda.amp.autocast(**ctx.gpu_autocast_kwargs):
+ # Fixes a bug where the first op in run_function modifies the
+ # Tensor storage in place, which is not allowed for detach()'d
+ # Tensors.
+ shallow_copies = [x.view_as(x) for x in ctx.input_tensors]
+ output_tensors = ctx.run_function(*shallow_copies)
+ input_grads = torch.autograd.grad(
+ output_tensors,
+ ctx.input_tensors + ctx.input_params,
+ output_grads,
+ allow_unused=True,
+ )
+ del ctx.input_tensors
+ del ctx.input_params
+ del output_tensors
+ return (None, None) + input_grads
+
+
+def timestep_embedding(timesteps, dim, max_period=10000, repeat_only=False):
+ """
+ Create sinusoidal timestep embeddings.
+ :param timesteps: a 1-D Tensor of N indices, one per batch element.
+ These may be fractional.
+ :param dim: the dimension of the output.
+ :param max_period: controls the minimum frequency of the embeddings.
+ :return: an [N x dim] Tensor of positional embeddings.
+ """
+ if not repeat_only:
+ half = dim // 2
+ freqs = torch.exp(
+ -math.log(max_period) * torch.arange(start=0, end=half, dtype=torch.float32, device=timesteps.device) / half
+ )
+ args = timesteps[:, None].float() * freqs[None]
+ embedding = torch.cat([torch.cos(args), torch.sin(args)], dim=-1)
+ if dim % 2:
+ embedding = torch.cat([embedding, torch.zeros_like(embedding[:, :1])], dim=-1)
+ else:
+ embedding = repeat(timesteps, 'b -> b d', d=dim)
+ return embedding
+
+
+def zero_module(module):
+ """
+ Zero out the parameters of a module and return it.
+ """
+ for p in module.parameters():
+ p.detach().zero_()
+ return module
+
+
+def scale_module(module, scale):
+ """
+ Scale the parameters of a module and return it.
+ """
+ for p in module.parameters():
+ p.detach().mul_(scale)
+ return module
+
+
+def mean_flat(tensor):
+ """
+ Take the mean over all non-batch dimensions.
+ """
+ return tensor.mean(dim=list(range(1, len(tensor.shape))))
+
+
+def avg_pool_nd(dims, *args, **kwargs):
+ """
+ Create a 1D, 2D, or 3D average pooling module.
+ """
+ if dims == 1:
+ return nn.AvgPool1d(*args, **kwargs)
+ elif dims == 2:
+ return nn.AvgPool2d(*args, **kwargs)
+ elif dims == 3:
+ return nn.AvgPool3d(*args, **kwargs)
+ raise ValueError(f"unsupported dimensions: {dims}")
+
+
+class HybridConditioner(nn.Module):
+
+ def __init__(self, c_concat_config, c_crossattn_config):
+ super().__init__()
+ self.concat_conditioner = instantiate_from_config(c_concat_config)
+ self.crossattn_conditioner = instantiate_from_config(c_crossattn_config)
+
+ def forward(self, c_concat, c_crossattn):
+ c_concat = self.concat_conditioner(c_concat)
+ c_crossattn = self.crossattn_conditioner(c_crossattn)
+ return {'c_concat': [c_concat], 'c_crossattn': [c_crossattn]}
+
+
+def noise_like(shape, device, repeat=False):
+ repeat_noise = lambda: torch.randn((1, *shape[1:]), device=device).repeat(shape[0], *((1,) * (len(shape) - 1)))
+ noise = lambda: torch.randn(shape, device=device)
+ return repeat_noise() if repeat else noise()
diff --git a/ComfyUI/comfy/ldm/modules/distributions/__init__.py b/ComfyUI/comfy/ldm/modules/distributions/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/ComfyUI/comfy/ldm/modules/distributions/__pycache__/__init__.cpython-312.pyc b/ComfyUI/comfy/ldm/modules/distributions/__pycache__/__init__.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..5b963632408c60937389f793a395ecc4abf95666
Binary files /dev/null and b/ComfyUI/comfy/ldm/modules/distributions/__pycache__/__init__.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/modules/distributions/__pycache__/distributions.cpython-312.pyc b/ComfyUI/comfy/ldm/modules/distributions/__pycache__/distributions.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..6b3a59b4faf10b7ce18f4ee7afd4f7b14441b9cb
Binary files /dev/null and b/ComfyUI/comfy/ldm/modules/distributions/__pycache__/distributions.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/modules/distributions/distributions.py b/ComfyUI/comfy/ldm/modules/distributions/distributions.py
new file mode 100644
index 0000000000000000000000000000000000000000..df987c5ec3faaba7da2b02029ad413134bfa08ad
--- /dev/null
+++ b/ComfyUI/comfy/ldm/modules/distributions/distributions.py
@@ -0,0 +1,92 @@
+import torch
+import numpy as np
+
+
+class AbstractDistribution:
+ def sample(self):
+ raise NotImplementedError()
+
+ def mode(self):
+ raise NotImplementedError()
+
+
+class DiracDistribution(AbstractDistribution):
+ def __init__(self, value):
+ self.value = value
+
+ def sample(self):
+ return self.value
+
+ def mode(self):
+ return self.value
+
+
+class DiagonalGaussianDistribution(object):
+ def __init__(self, parameters, deterministic=False):
+ self.parameters = parameters
+ self.mean, self.logvar = torch.chunk(parameters, 2, dim=1)
+ self.logvar = torch.clamp(self.logvar, -30.0, 20.0)
+ self.deterministic = deterministic
+ self.std = torch.exp(0.5 * self.logvar)
+ self.var = torch.exp(self.logvar)
+ if self.deterministic:
+ self.var = self.std = torch.zeros_like(self.mean, device=self.parameters.device)
+
+ def sample(self):
+ x = self.mean + self.std * torch.randn(self.mean.shape, device=self.parameters.device)
+ return x
+
+ def kl(self, other=None):
+ if self.deterministic:
+ return torch.Tensor([0.])
+ else:
+ if other is None:
+ return 0.5 * torch.sum(torch.pow(self.mean, 2)
+ + self.var - 1.0 - self.logvar,
+ dim=[1, 2, 3])
+ else:
+ return 0.5 * torch.sum(
+ torch.pow(self.mean - other.mean, 2) / other.var
+ + self.var / other.var - 1.0 - self.logvar + other.logvar,
+ dim=[1, 2, 3])
+
+ def nll(self, sample, dims=[1,2,3]):
+ if self.deterministic:
+ return torch.Tensor([0.])
+ logtwopi = np.log(2.0 * np.pi)
+ return 0.5 * torch.sum(
+ logtwopi + self.logvar + torch.pow(sample - self.mean, 2) / self.var,
+ dim=dims)
+
+ def mode(self):
+ return self.mean
+
+
+def normal_kl(mean1, logvar1, mean2, logvar2):
+ """
+ source: https://github.com/openai/guided-diffusion/blob/27c20a8fab9cb472df5d6bdd6c8d11c8f430b924/guided_diffusion/losses.py#L12
+ Compute the KL divergence between two gaussians.
+ Shapes are automatically broadcasted, so batches can be compared to
+ scalars, among other use cases.
+ """
+ tensor = None
+ for obj in (mean1, logvar1, mean2, logvar2):
+ if isinstance(obj, torch.Tensor):
+ tensor = obj
+ break
+ assert tensor is not None, "at least one argument must be a Tensor"
+
+ # Force variances to be Tensors. Broadcasting helps convert scalars to
+ # Tensors, but it does not work for torch.exp().
+ logvar1, logvar2 = [
+ x if isinstance(x, torch.Tensor) else torch.tensor(x).to(tensor)
+ for x in (logvar1, logvar2)
+ ]
+
+ return 0.5 * (
+ -1.0
+ + logvar2
+ - logvar1
+ + torch.exp(logvar1 - logvar2)
+ + ((mean1 - mean2) ** 2) * torch.exp(-logvar2)
+ )
diff --git a/ComfyUI/comfy/ldm/modules/ema.py b/ComfyUI/comfy/ldm/modules/ema.py
new file mode 100644
index 0000000000000000000000000000000000000000..96ee6e89549fc95fe270af19458d4c17f6b1982c
--- /dev/null
+++ b/ComfyUI/comfy/ldm/modules/ema.py
@@ -0,0 +1,80 @@
+import torch
+from torch import nn
+
+
+class LitEma(nn.Module):
+ def __init__(self, model, decay=0.9999, use_num_upates=True):
+ super().__init__()
+ if decay < 0.0 or decay > 1.0:
+ raise ValueError('Decay must be between 0 and 1')
+
+ self.m_name2s_name = {}
+ self.register_buffer('decay', torch.tensor(decay, dtype=torch.float32))
+ self.register_buffer('num_updates', torch.tensor(0, dtype=torch.int) if use_num_upates
+ else torch.tensor(-1, dtype=torch.int))
+
+ for name, p in model.named_parameters():
+ if p.requires_grad:
+ # remove as '.'-character is not allowed in buffers
+ s_name = name.replace('.', '')
+ self.m_name2s_name.update({name: s_name})
+ self.register_buffer(s_name, p.clone().detach().data)
+
+ self.collected_params = []
+
+ def reset_num_updates(self):
+ del self.num_updates
+ self.register_buffer('num_updates', torch.tensor(0, dtype=torch.int))
+
+ def forward(self, model):
+ decay = self.decay
+
+ if self.num_updates >= 0:
+ self.num_updates += 1
+ decay = min(self.decay, (1 + self.num_updates) / (10 + self.num_updates))
+
+ one_minus_decay = 1.0 - decay
+
+ with torch.no_grad():
+ m_param = dict(model.named_parameters())
+ shadow_params = dict(self.named_buffers())
+
+ for key in m_param:
+ if m_param[key].requires_grad:
+ sname = self.m_name2s_name[key]
+ shadow_params[sname] = shadow_params[sname].type_as(m_param[key])
+ shadow_params[sname].sub_(one_minus_decay * (shadow_params[sname] - m_param[key]))
+ else:
+ assert key not in self.m_name2s_name
+
+ def copy_to(self, model):
+ m_param = dict(model.named_parameters())
+ shadow_params = dict(self.named_buffers())
+ for key in m_param:
+ if m_param[key].requires_grad:
+ m_param[key].data.copy_(shadow_params[self.m_name2s_name[key]].data)
+ else:
+ assert key not in self.m_name2s_name
+
+ def store(self, parameters):
+ """
+ Save the current parameters for restoring later.
+ Args:
+ parameters: Iterable of `torch.nn.Parameter`; the parameters to be
+ temporarily stored.
+ """
+ self.collected_params = [param.clone() for param in parameters]
+
+ def restore(self, parameters):
+ """
+ Restore the parameters stored with the `store` method.
+ Useful to validate the model with EMA parameters without affecting the
+ original optimization process. Store the parameters before the
+ `copy_to` method. After validation (or model saving), use this to
+ restore the former parameters.
+ Args:
+ parameters: Iterable of `torch.nn.Parameter`; the parameters to be
+ updated with the stored parameters.
+ """
+ for c_param, param in zip(self.collected_params, parameters):
+ param.data.copy_(c_param.data)
diff --git a/ComfyUI/comfy/ldm/modules/encoders/__init__.py b/ComfyUI/comfy/ldm/modules/encoders/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/ComfyUI/comfy/ldm/modules/encoders/__pycache__/__init__.cpython-312.pyc b/ComfyUI/comfy/ldm/modules/encoders/__pycache__/__init__.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..25b0fe732a8a46b3dc8ab5bc6a1c6d60031b2289
Binary files /dev/null and b/ComfyUI/comfy/ldm/modules/encoders/__pycache__/__init__.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/modules/encoders/__pycache__/noise_aug_modules.cpython-312.pyc b/ComfyUI/comfy/ldm/modules/encoders/__pycache__/noise_aug_modules.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..81470c29f628493e49b5414f19163621fba635c4
Binary files /dev/null and b/ComfyUI/comfy/ldm/modules/encoders/__pycache__/noise_aug_modules.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/modules/encoders/noise_aug_modules.py b/ComfyUI/comfy/ldm/modules/encoders/noise_aug_modules.py
new file mode 100644
index 0000000000000000000000000000000000000000..c853e4298c095008dffe15286133771c4443d9fa
--- /dev/null
+++ b/ComfyUI/comfy/ldm/modules/encoders/noise_aug_modules.py
@@ -0,0 +1,32 @@
+from ..diffusionmodules.upscaling import ImageConcatWithNoiseAugmentation
+from ..diffusionmodules.openaimodel import Timestep
+import torch
+
+class CLIPEmbeddingNoiseAugmentation(ImageConcatWithNoiseAugmentation):
+ def __init__(self, *args, timestep_dim=256, **kwargs):
+ super().__init__(*args, **kwargs)
+ clip_mean, clip_std = torch.zeros(timestep_dim), torch.ones(timestep_dim)
+ self.register_buffer("data_mean", clip_mean[None, :], persistent=False)
+ self.register_buffer("data_std", clip_std[None, :], persistent=False)
+ self.time_embed = Timestep(timestep_dim)
+
+ def scale(self, x):
+ # re-normalize to centered mean and unit variance
+ x = (x - self.data_mean.to(x.device)) * 1. / self.data_std.to(x.device)
+ return x
+
+ def unscale(self, x):
+ # back to original data stats
+ x = (x * self.data_std.to(x.device)) + self.data_mean.to(x.device)
+ return x
+
+ def forward(self, x, noise_level=None, seed=None):
+ if noise_level is None:
+ noise_level = torch.randint(0, self.max_noise_level, (x.shape[0],), device=x.device).long()
+ else:
+ assert isinstance(noise_level, torch.Tensor)
+ x = self.scale(x)
+ z = self.q_sample(x, noise_level, seed=seed)
+ z = self.unscale(z)
+ noise_level = self.time_embed(noise_level)
+ return z, noise_level
diff --git a/ComfyUI/comfy/ldm/modules/sdpose.py b/ComfyUI/comfy/ldm/modules/sdpose.py
new file mode 100644
index 0000000000000000000000000000000000000000..1a9585fc257066ba4ed34a188a62c29588c9c743
--- /dev/null
+++ b/ComfyUI/comfy/ldm/modules/sdpose.py
@@ -0,0 +1,130 @@
+import torch
+import numpy as np
+from scipy.ndimage import gaussian_filter
+
+class HeatmapHead(torch.nn.Module):
+ def __init__(
+ self,
+ in_channels=640,
+ out_channels=133,
+ input_size=(768, 1024),
+ heatmap_scale=4,
+ deconv_out_channels=(640,),
+ deconv_kernel_sizes=(4,),
+ conv_out_channels=(640,),
+ conv_kernel_sizes=(1,),
+ final_layer_kernel_size=1,
+ device=None, dtype=None, operations=None
+ ):
+ super().__init__()
+
+ self.heatmap_size = (input_size[0] // heatmap_scale, input_size[1] // heatmap_scale)
+ self.scale_factor = ((np.array(input_size) - 1) / (np.array(self.heatmap_size) - 1)).astype(np.float32)
+
+ # Deconv layers
+ if deconv_out_channels:
+ deconv_layers = []
+ for out_ch, kernel_size in zip(deconv_out_channels, deconv_kernel_sizes):
+ if kernel_size == 4:
+ padding, output_padding = 1, 0
+ elif kernel_size == 3:
+ padding, output_padding = 1, 1
+ elif kernel_size == 2:
+ padding, output_padding = 0, 0
+ else:
+ raise ValueError(f'Unsupported kernel size {kernel_size}')
+
+ deconv_layers.extend([
+ operations.ConvTranspose2d(in_channels, out_ch, kernel_size,
+ stride=2, padding=padding, output_padding=output_padding, bias=False, device=device, dtype=dtype),
+ torch.nn.InstanceNorm2d(out_ch, device=device, dtype=dtype),
+ torch.nn.SiLU(inplace=True)
+ ])
+ in_channels = out_ch
+ self.deconv_layers = torch.nn.Sequential(*deconv_layers)
+ else:
+ self.deconv_layers = torch.nn.Identity()
+
+ # Conv layers
+ if conv_out_channels:
+ conv_layers = []
+ for out_ch, kernel_size in zip(conv_out_channels, conv_kernel_sizes):
+ padding = (kernel_size - 1) // 2
+ conv_layers.extend([
+ operations.Conv2d(in_channels, out_ch, kernel_size,
+ stride=1, padding=padding, device=device, dtype=dtype),
+ torch.nn.InstanceNorm2d(out_ch, device=device, dtype=dtype),
+ torch.nn.SiLU(inplace=True)
+ ])
+ in_channels = out_ch
+ self.conv_layers = torch.nn.Sequential(*conv_layers)
+ else:
+ self.conv_layers = torch.nn.Identity()
+
+ self.final_layer = operations.Conv2d(in_channels, out_channels, kernel_size=final_layer_kernel_size, padding=final_layer_kernel_size // 2, device=device, dtype=dtype)
+
+ def forward(self, x): # Decode heatmaps to keypoints
+ heatmaps = self.final_layer(self.conv_layers(self.deconv_layers(x)))
+ heatmaps_np = heatmaps.float().cpu().numpy() # (B, K, H, W)
+ B, K, H, W = heatmaps_np.shape
+
+ batch_keypoints = []
+ batch_scores = []
+
+ for b in range(B):
+ hm = heatmaps_np[b].copy() # (K, H, W)
+
+ # --- vectorised argmax ---
+ flat = hm.reshape(K, -1)
+ idx = np.argmax(flat, axis=1)
+ scores = flat[np.arange(K), idx].copy()
+ y_locs, x_locs = np.unravel_index(idx, (H, W))
+ keypoints = np.stack([x_locs, y_locs], axis=-1).astype(np.float32) # (K, 2) in heatmap space
+ invalid = scores <= 0.
+ keypoints[invalid] = -1
+
+ # --- DARK sub-pixel refinement (UDP) ---
+ # 1. Gaussian blur with max-preserving normalisation
+ border = 5 # (kernel-1)//2 for kernel=11
+ for k in range(K):
+ origin_max = np.max(hm[k])
+ dr = np.zeros((H + 2 * border, W + 2 * border), dtype=np.float32)
+ dr[border:-border, border:-border] = hm[k].copy()
+ dr = gaussian_filter(dr, sigma=2.0, truncate=2.5)
+ hm[k] = dr[border:-border, border:-border].copy()
+ cur_max = np.max(hm[k])
+ if cur_max > 0:
+ hm[k] *= origin_max / cur_max
+ # 2. Log-space for Taylor expansion
+ np.clip(hm, 1e-3, 50., hm)
+ np.log(hm, hm)
+ # 3. Hessian-based Newton step
+ hm_pad = np.pad(hm, ((0, 0), (1, 1), (1, 1)), mode='edge').flatten()
+ index = keypoints[:, 0] + 1 + (keypoints[:, 1] + 1) * (W + 2)
+ index += (W + 2) * (H + 2) * np.arange(0, K)
+ index = index.astype(int).reshape(-1, 1)
+ i_ = hm_pad[index]
+ ix1 = hm_pad[index + 1]
+ iy1 = hm_pad[index + W + 2]
+ ix1y1 = hm_pad[index + W + 3]
+ ix1_y1_ = hm_pad[index - W - 3]
+ ix1_ = hm_pad[index - 1]
+ iy1_ = hm_pad[index - 2 - W]
+ dx = 0.5 * (ix1 - ix1_)
+ dy = 0.5 * (iy1 - iy1_)
+ derivative = np.concatenate([dx, dy], axis=1).reshape(K, 2, 1)
+ dxx = ix1 - 2 * i_ + ix1_
+ dyy = iy1 - 2 * i_ + iy1_
+ dxy = 0.5 * (ix1y1 - ix1 - iy1 + i_ + i_ - ix1_ - iy1_ + ix1_y1_)
+ hessian = np.concatenate([dxx, dxy, dxy, dyy], axis=1).reshape(K, 2, 2)
+ hessian = np.linalg.inv(hessian + np.finfo(np.float32).eps * np.eye(2))
+ keypoints -= np.einsum('imn,ink->imk', hessian, derivative).squeeze(axis=-1)
+
+ # --- restore to input image space ---
+ keypoints = keypoints * self.scale_factor
+ keypoints[invalid] = -1
+
+ batch_keypoints.append(keypoints)
+ batch_scores.append(scores)
+
+ return batch_keypoints, batch_scores
diff --git a/ComfyUI/comfy/ldm/modules/sub_quadratic_attention.py b/ComfyUI/comfy/ldm/modules/sub_quadratic_attention.py
new file mode 100644
index 0000000000000000000000000000000000000000..f982afc2b0e06a962a137f065aead08be246b9df
--- /dev/null
+++ b/ComfyUI/comfy/ldm/modules/sub_quadratic_attention.py
@@ -0,0 +1,276 @@
+# original source:
+# https://github.com/AminRezaei0x443/memory-efficient-attention/blob/1bc0d9e6ac5f82ea43a375135c4e1d3896ee1694/memory_efficient_attention/attention_torch.py
+# license:
+# MIT
+# credit:
+# Amin Rezaei (original author)
+# Alex Birch (optimized algorithm for 3D tensors, at the expense of removing bias, masking and callbacks)
+# implementation of:
+# Self-attention Does Not Need O(n2) Memory":
+# https://arxiv.org/abs/2112.05682v2
+
+from functools import partial
+import torch
+from torch import Tensor
+from torch.utils.checkpoint import checkpoint
+import math
+import logging
+
+try:
+ from typing import Optional, NamedTuple, List, Protocol
+except ImportError:
+ from typing import Optional, NamedTuple, List
+ from typing_extensions import Protocol
+
+from typing import List
+
+from comfy import model_management
+
+def dynamic_slice(
+ x: Tensor,
+ starts: List[int],
+ sizes: List[int],
+) -> Tensor:
+ slicing = tuple(slice(start, start + size) for start, size in zip(starts, sizes))
+ return x[slicing]
+
+class AttnChunk(NamedTuple):
+ exp_values: Tensor
+ exp_weights_sum: Tensor
+ max_score: Tensor
+
+class SummarizeChunk(Protocol):
+ @staticmethod
+ def __call__(
+ query: Tensor,
+ key_t: Tensor,
+ value: Tensor,
+ ) -> AttnChunk: ...
+
+class ComputeQueryChunkAttn(Protocol):
+ @staticmethod
+ def __call__(
+ query: Tensor,
+ key_t: Tensor,
+ value: Tensor,
+ ) -> Tensor: ...
+
+def _summarize_chunk(
+ query: Tensor,
+ key_t: Tensor,
+ value: Tensor,
+ scale: float,
+ upcast_attention: bool,
+ mask,
+) -> AttnChunk:
+ if upcast_attention:
+ with torch.autocast(enabled=False, device_type = 'cuda'):
+ query = query.float()
+ key_t = key_t.float()
+ attn_weights = torch.baddbmm(
+ torch.empty(1, 1, 1, device=query.device, dtype=query.dtype),
+ query,
+ key_t,
+ alpha=scale,
+ beta=0,
+ )
+ else:
+ attn_weights = torch.baddbmm(
+ torch.empty(1, 1, 1, device=query.device, dtype=query.dtype),
+ query,
+ key_t,
+ alpha=scale,
+ beta=0,
+ )
+ max_score, _ = torch.max(attn_weights, -1, keepdim=True)
+ max_score = max_score.detach()
+ attn_weights -= max_score
+ if mask is not None:
+ attn_weights += mask
+ torch.exp(attn_weights, out=attn_weights)
+ exp_weights = attn_weights.to(value.dtype)
+ exp_values = torch.bmm(exp_weights, value)
+ max_score = max_score.squeeze(-1)
+ return AttnChunk(exp_values, exp_weights.sum(dim=-1), max_score)
+
+def _query_chunk_attention(
+ query: Tensor,
+ key_t: Tensor,
+ value: Tensor,
+ summarize_chunk: SummarizeChunk,
+ kv_chunk_size: int,
+ mask,
+) -> Tensor:
+ batch_x_heads, k_channels_per_head, k_tokens = key_t.shape
+ _, _, v_channels_per_head = value.shape
+
+ def chunk_scanner(chunk_idx: int, mask) -> AttnChunk:
+ key_chunk = dynamic_slice(
+ key_t,
+ (0, 0, chunk_idx),
+ (batch_x_heads, k_channels_per_head, kv_chunk_size)
+ )
+ value_chunk = dynamic_slice(
+ value,
+ (0, chunk_idx, 0),
+ (batch_x_heads, kv_chunk_size, v_channels_per_head)
+ )
+ if mask is not None:
+ mask = mask[:,:,chunk_idx:chunk_idx + kv_chunk_size]
+
+ return summarize_chunk(query, key_chunk, value_chunk, mask=mask)
+
+ chunks: List[AttnChunk] = [
+ chunk_scanner(chunk, mask) for chunk in torch.arange(0, k_tokens, kv_chunk_size)
+ ]
+ acc_chunk = AttnChunk(*map(torch.stack, zip(*chunks)))
+ chunk_values, chunk_weights, chunk_max = acc_chunk
+
+ global_max, _ = torch.max(chunk_max, 0, keepdim=True)
+ max_diffs = torch.exp(chunk_max - global_max)
+ chunk_values *= torch.unsqueeze(max_diffs, -1)
+ chunk_weights *= max_diffs
+
+ all_values = chunk_values.sum(dim=0)
+ all_weights = torch.unsqueeze(chunk_weights, -1).sum(dim=0)
+ return all_values / all_weights
+
+# TODO: refactor CrossAttention#get_attention_scores to share code with this
+def _get_attention_scores_no_kv_chunking(
+ query: Tensor,
+ key_t: Tensor,
+ value: Tensor,
+ scale: float,
+ upcast_attention: bool,
+ mask,
+) -> Tensor:
+ if upcast_attention:
+ with torch.autocast(enabled=False, device_type = 'cuda'):
+ query = query.float()
+ key_t = key_t.float()
+ attn_scores = torch.baddbmm(
+ torch.empty(1, 1, 1, device=query.device, dtype=query.dtype),
+ query,
+ key_t,
+ alpha=scale,
+ beta=0,
+ )
+ else:
+ attn_scores = torch.baddbmm(
+ torch.empty(1, 1, 1, device=query.device, dtype=query.dtype),
+ query,
+ key_t,
+ alpha=scale,
+ beta=0,
+ )
+
+ if mask is not None:
+ attn_scores += mask
+ try:
+ attn_probs = attn_scores.softmax(dim=-1)
+ del attn_scores
+ except Exception as e:
+ model_management.raise_non_oom(e)
+ logging.warning("ran out of memory while running softmax in _get_attention_scores_no_kv_chunking, trying slower in place softmax instead")
+ attn_scores -= attn_scores.max(dim=-1, keepdim=True).values # noqa: F821 attn_scores is not defined
+ torch.exp(attn_scores, out=attn_scores)
+ summed = torch.sum(attn_scores, dim=-1, keepdim=True)
+ attn_scores /= summed
+ attn_probs = attn_scores
+
+ hidden_states_slice = torch.bmm(attn_probs.to(value.dtype), value)
+ return hidden_states_slice
+
+class ScannedChunk(NamedTuple):
+ chunk_idx: int
+ attn_chunk: AttnChunk
+
+def efficient_dot_product_attention(
+ query: Tensor,
+ key_t: Tensor,
+ value: Tensor,
+ query_chunk_size=1024,
+ kv_chunk_size: Optional[int] = None,
+ kv_chunk_size_min: Optional[int] = None,
+ use_checkpoint=True,
+ upcast_attention=False,
+ mask = None,
+):
+ """Computes efficient dot-product attention given query, transposed key, and value.
+ This is efficient version of attention presented in
+ https://arxiv.org/abs/2112.05682v2 which comes with O(sqrt(n)) memory requirements.
+ Args:
+ query: queries for calculating attention with shape of
+ `[batch * num_heads, tokens, channels_per_head]`.
+ key_t: keys for calculating attention with shape of
+ `[batch * num_heads, channels_per_head, tokens]`.
+ value: values to be used in attention with shape of
+ `[batch * num_heads, tokens, channels_per_head]`.
+ query_chunk_size: int: query chunks size
+ kv_chunk_size: Optional[int]: key/value chunks size. if None: defaults to sqrt(key_tokens)
+ kv_chunk_size_min: Optional[int]: key/value minimum chunk size. only considered when kv_chunk_size is None. changes `sqrt(key_tokens)` into `max(sqrt(key_tokens), kv_chunk_size_min)`, to ensure our chunk sizes don't get too small (smaller chunks = more chunks = less concurrent work done).
+ use_checkpoint: bool: whether to use checkpointing (recommended True for training, False for inference)
+ Returns:
+ Output of shape `[batch * num_heads, query_tokens, channels_per_head]`.
+ """
+ batch_x_heads, q_tokens, q_channels_per_head = query.shape
+ _, _, k_tokens = key_t.shape
+ scale = q_channels_per_head ** -0.5
+
+ kv_chunk_size = min(kv_chunk_size or int(math.sqrt(k_tokens)), k_tokens)
+ if kv_chunk_size_min is not None:
+ kv_chunk_size = max(kv_chunk_size, kv_chunk_size_min)
+
+ if mask is not None and len(mask.shape) == 2:
+ mask = mask.unsqueeze(0)
+
+ def get_query_chunk(chunk_idx: int) -> Tensor:
+ return dynamic_slice(
+ query,
+ (0, chunk_idx, 0),
+ (batch_x_heads, min(query_chunk_size, q_tokens), q_channels_per_head)
+ )
+
+ def get_mask_chunk(chunk_idx: int) -> Tensor:
+ if mask is None:
+ return None
+ if mask.shape[1] == 1:
+ return mask
+ chunk = min(query_chunk_size, q_tokens)
+ return mask[:,chunk_idx:chunk_idx + chunk]
+
+ summarize_chunk: SummarizeChunk = partial(_summarize_chunk, scale=scale, upcast_attention=upcast_attention)
+ summarize_chunk: SummarizeChunk = partial(checkpoint, summarize_chunk) if use_checkpoint else summarize_chunk
+ compute_query_chunk_attn: ComputeQueryChunkAttn = partial(
+ _get_attention_scores_no_kv_chunking,
+ scale=scale,
+ upcast_attention=upcast_attention
+ ) if k_tokens <= kv_chunk_size else (
+ # fast-path for when there's just 1 key-value chunk per query chunk (this is just sliced attention btw)
+ partial(
+ _query_chunk_attention,
+ kv_chunk_size=kv_chunk_size,
+ summarize_chunk=summarize_chunk,
+ )
+ )
+
+ if q_tokens <= query_chunk_size:
+ # fast-path for when there's just 1 query chunk
+ return compute_query_chunk_attn(
+ query=query,
+ key_t=key_t,
+ value=value,
+ mask=mask,
+ )
+
+ # TODO: maybe we should use torch.empty_like(query) to allocate storage in-advance,
+ # and pass slices to be mutated, instead of torch.cat()ing the returned slices
+ res = torch.cat([
+ compute_query_chunk_attn(
+ query=get_query_chunk(i * query_chunk_size),
+ key_t=key_t,
+ value=value,
+ mask=get_mask_chunk(i * query_chunk_size)
+ ) for i in range(math.ceil(q_tokens / query_chunk_size))
+ ], dim=1)
+ return res
diff --git a/ComfyUI/comfy/ldm/modules/temporal_ae.py b/ComfyUI/comfy/ldm/modules/temporal_ae.py
new file mode 100644
index 0000000000000000000000000000000000000000..e0f78bf66b7b06b3f49f5add7a8a502384a9f445
--- /dev/null
+++ b/ComfyUI/comfy/ldm/modules/temporal_ae.py
@@ -0,0 +1,246 @@
+import functools
+from typing import Iterable, Union
+
+import torch
+from einops import rearrange, repeat
+
+import comfy.ops
+ops = comfy.ops.disable_weight_init
+
+from .diffusionmodules.model import (
+ AttnBlock,
+ Decoder,
+ ResnetBlock,
+)
+from .diffusionmodules.openaimodel import ResBlock, timestep_embedding
+from .attention import BasicTransformerBlock
+
+def partialclass(cls, *args, **kwargs):
+ class NewCls(cls):
+ __init__ = functools.partialmethod(cls.__init__, *args, **kwargs)
+
+ return NewCls
+
+
+class VideoResBlock(ResnetBlock):
+ def __init__(
+ self,
+ out_channels,
+ *args,
+ dropout=0.0,
+ video_kernel_size=3,
+ alpha=0.0,
+ merge_strategy="learned",
+ **kwargs,
+ ):
+ super().__init__(out_channels=out_channels, dropout=dropout, *args, **kwargs)
+ if video_kernel_size is None:
+ video_kernel_size = [3, 1, 1]
+ self.time_stack = ResBlock(
+ channels=out_channels,
+ emb_channels=0,
+ dropout=dropout,
+ dims=3,
+ use_scale_shift_norm=False,
+ use_conv=False,
+ up=False,
+ down=False,
+ kernel_size=video_kernel_size,
+ use_checkpoint=False,
+ skip_t_emb=True,
+ )
+
+ self.merge_strategy = merge_strategy
+ if self.merge_strategy == "fixed":
+ self.register_buffer("mix_factor", torch.Tensor([alpha]))
+ elif self.merge_strategy == "learned":
+ self.register_parameter(
+ "mix_factor", torch.nn.Parameter(torch.Tensor([alpha]))
+ )
+ else:
+ raise ValueError(f"unknown merge strategy {self.merge_strategy}")
+
+ def get_alpha(self, bs):
+ if self.merge_strategy == "fixed":
+ return self.mix_factor
+ elif self.merge_strategy == "learned":
+ return torch.sigmoid(self.mix_factor)
+ else:
+ raise NotImplementedError()
+
+ def forward(self, x, temb, skip_video=False, timesteps=None):
+ b, c, h, w = x.shape
+ if timesteps is None:
+ timesteps = b
+
+ x = super().forward(x, temb)
+
+ if not skip_video:
+ x_mix = rearrange(x, "(b t) c h w -> b c t h w", t=timesteps)
+
+ x = rearrange(x, "(b t) c h w -> b c t h w", t=timesteps)
+
+ x = self.time_stack(x, temb)
+
+ alpha = self.get_alpha(bs=b // timesteps).to(x.device)
+ x = alpha * x + (1.0 - alpha) * x_mix
+
+ x = rearrange(x, "b c t h w -> (b t) c h w")
+ return x
+
+
+class AE3DConv(ops.Conv2d):
+ def __init__(self, in_channels, out_channels, video_kernel_size=3, *args, **kwargs):
+ super().__init__(in_channels, out_channels, *args, **kwargs)
+ if isinstance(video_kernel_size, Iterable):
+ padding = [int(k // 2) for k in video_kernel_size]
+ else:
+ padding = int(video_kernel_size // 2)
+
+ self.time_mix_conv = ops.Conv3d(
+ in_channels=out_channels,
+ out_channels=out_channels,
+ kernel_size=video_kernel_size,
+ padding=padding,
+ )
+
+ def forward(self, input, timesteps=None, skip_video=False):
+ if timesteps is None:
+ timesteps = input.shape[0]
+ x = super().forward(input)
+ if skip_video:
+ return x
+ x = rearrange(x, "(b t) c h w -> b c t h w", t=timesteps)
+ x = self.time_mix_conv(x)
+ return rearrange(x, "b c t h w -> (b t) c h w")
+
+
+class AttnVideoBlock(AttnBlock):
+ def __init__(
+ self, in_channels: int, alpha: float = 0, merge_strategy: str = "learned"
+ ):
+ super().__init__(in_channels)
+ # no context, single headed, as in base class
+ self.time_mix_block = BasicTransformerBlock(
+ dim=in_channels,
+ n_heads=1,
+ d_head=in_channels,
+ checkpoint=False,
+ ff_in=True,
+ )
+
+ time_embed_dim = self.in_channels * 4
+ self.video_time_embed = torch.nn.Sequential(
+ ops.Linear(self.in_channels, time_embed_dim),
+ torch.nn.SiLU(),
+ ops.Linear(time_embed_dim, self.in_channels),
+ )
+
+ self.merge_strategy = merge_strategy
+ if self.merge_strategy == "fixed":
+ self.register_buffer("mix_factor", torch.Tensor([alpha]))
+ elif self.merge_strategy == "learned":
+ self.register_parameter(
+ "mix_factor", torch.nn.Parameter(torch.Tensor([alpha]))
+ )
+ else:
+ raise ValueError(f"unknown merge strategy {self.merge_strategy}")
+
+ def forward(self, x, timesteps=None, skip_time_block=False):
+ if skip_time_block:
+ return super().forward(x)
+
+ if timesteps is None:
+ timesteps = x.shape[0]
+
+ x_in = x
+ x = self.attention(x)
+ h, w = x.shape[2:]
+ x = rearrange(x, "b c h w -> b (h w) c")
+
+ x_mix = x
+ num_frames = torch.arange(timesteps, device=x.device)
+ num_frames = repeat(num_frames, "t -> b t", b=x.shape[0] // timesteps)
+ num_frames = rearrange(num_frames, "b t -> (b t)")
+ t_emb = timestep_embedding(num_frames, self.in_channels, repeat_only=False)
+ emb = self.video_time_embed(t_emb) # b, n_channels
+ emb = emb[:, None, :]
+ x_mix = x_mix + emb
+
+ alpha = self.get_alpha().to(x.device)
+ x_mix = self.time_mix_block(x_mix, timesteps=timesteps)
+ x = alpha * x + (1.0 - alpha) * x_mix # alpha merge
+
+ x = rearrange(x, "b (h w) c -> b c h w", h=h, w=w)
+ x = self.proj_out(x)
+
+ return x_in + x
+
+ def get_alpha(
+ self,
+ ):
+ if self.merge_strategy == "fixed":
+ return self.mix_factor
+ elif self.merge_strategy == "learned":
+ return torch.sigmoid(self.mix_factor)
+ else:
+ raise NotImplementedError(f"unknown merge strategy {self.merge_strategy}")
+
+
+
+def make_time_attn(
+ in_channels,
+ attn_type="vanilla",
+ attn_kwargs=None,
+ alpha: float = 0,
+ merge_strategy: str = "learned",
+ conv_op=ops.Conv2d,
+):
+ return partialclass(
+ AttnVideoBlock, in_channels, alpha=alpha, merge_strategy=merge_strategy
+ )
+
+
+class Conv2DWrapper(torch.nn.Conv2d):
+ def forward(self, input: torch.Tensor, **kwargs) -> torch.Tensor:
+ return super().forward(input)
+
+
+class VideoDecoder(Decoder):
+ available_time_modes = ["all", "conv-only", "attn-only"]
+
+ def __init__(
+ self,
+ *args,
+ video_kernel_size: Union[int, list] = 3,
+ alpha: float = 0.0,
+ merge_strategy: str = "learned",
+ time_mode: str = "conv-only",
+ **kwargs,
+ ):
+ self.video_kernel_size = video_kernel_size
+ self.alpha = alpha
+ self.merge_strategy = merge_strategy
+ self.time_mode = time_mode
+ assert (
+ self.time_mode in self.available_time_modes
+ ), f"time_mode parameter has to be in {self.available_time_modes}"
+
+ if self.time_mode != "attn-only":
+ kwargs["conv_out_op"] = partialclass(AE3DConv, video_kernel_size=self.video_kernel_size)
+ if self.time_mode not in ["conv-only", "only-last-conv"]:
+ kwargs["attn_op"] = partialclass(make_time_attn, alpha=self.alpha, merge_strategy=self.merge_strategy)
+ if self.time_mode not in ["attn-only", "only-last-conv"]:
+ kwargs["resnet_op"] = partialclass(VideoResBlock, video_kernel_size=self.video_kernel_size, alpha=self.alpha, merge_strategy=self.merge_strategy)
+
+ super().__init__(*args, **kwargs)
+
+ def get_last_layer(self, skip_time_mix=False, **kwargs):
+ if self.time_mode == "attn-only":
+ raise NotImplementedError("TODO")
+ else:
+ return (
+ self.conv_out.time_mix_conv.weight
+ if not skip_time_mix
+ else self.conv_out.weight
+ )
diff --git a/ComfyUI/comfy/ldm/moge/__pycache__/geometry.cpython-312.pyc b/ComfyUI/comfy/ldm/moge/__pycache__/geometry.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..138c2e1253d7e3126699ec9e02510e27d5aa4998
Binary files /dev/null and b/ComfyUI/comfy/ldm/moge/__pycache__/geometry.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/moge/__pycache__/model.cpython-312.pyc b/ComfyUI/comfy/ldm/moge/__pycache__/model.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..df29477d97673c5843abd860c98f1fe8138f34fa
Binary files /dev/null and b/ComfyUI/comfy/ldm/moge/__pycache__/model.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/moge/__pycache__/modules.cpython-312.pyc b/ComfyUI/comfy/ldm/moge/__pycache__/modules.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..ac9bca042b65ee7020a53ee6c24c03c8de1e84ce
Binary files /dev/null and b/ComfyUI/comfy/ldm/moge/__pycache__/modules.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/moge/__pycache__/panorama.cpython-312.pyc b/ComfyUI/comfy/ldm/moge/__pycache__/panorama.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..299723e8fb2e76fc87ce3e709bdf7241f60eaa9c
Binary files /dev/null and b/ComfyUI/comfy/ldm/moge/__pycache__/panorama.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/moge/geometry.py b/ComfyUI/comfy/ldm/moge/geometry.py
new file mode 100644
index 0000000000000000000000000000000000000000..d1a1e445f3136c92da57c439f858f4de1983be24
--- /dev/null
+++ b/ComfyUI/comfy/ldm/moge/geometry.py
@@ -0,0 +1,188 @@
+"""Pure-torch + scipy geometry helpers for MoGe inference and mesh export."""
+
+
+from typing import Optional, Tuple
+
+import numpy as np
+import torch
+import torch.nn.functional as F
+
+from scipy.optimize import least_squares
+
+def normalized_view_plane_uv(width: int, height: int, aspect_ratio: Optional[float] = None,
+ dtype: Optional[torch.dtype] = None, device: Optional[torch.device] = None) -> torch.Tensor:
+ """Normalized view-plane UV coordinates with corners at +/-(W, H)/diagonal."""
+ if aspect_ratio is None:
+ aspect_ratio = width / height
+ span_x = aspect_ratio / (1 + aspect_ratio ** 2) ** 0.5
+ span_y = 1.0 / (1 + aspect_ratio ** 2) ** 0.5
+ u = torch.linspace(-span_x * (width - 1) / width, span_x * (width - 1) / width, width, dtype=dtype, device=device)
+ v = torch.linspace(-span_y * (height - 1) / height, span_y * (height - 1) / height, height, dtype=dtype, device=device)
+ u, v = torch.meshgrid(u, v, indexing="xy")
+ return torch.stack([u, v], dim=-1)
+
+
+def intrinsics_from_focal_center(fx: torch.Tensor, fy: torch.Tensor, cx: torch.Tensor, cy: torch.Tensor) -> torch.Tensor:
+ """Assemble (..., 3, 3) intrinsics from broadcastable fx, fy, cx, cy."""
+ fx, fy, cx, cy = [torch.as_tensor(v) for v in (fx, fy, cx, cy)]
+ fx, fy, cx, cy = torch.broadcast_tensors(fx, fy, cx, cy)
+ zero = torch.zeros_like(fx)
+ one = torch.ones_like(fx)
+ return torch.stack([
+ torch.stack([fx, zero, cx], dim=-1),
+ torch.stack([zero, fy, cy], dim=-1),
+ torch.stack([zero, zero, one], dim=-1),
+ ], dim=-2)
+
+
+def depth_map_to_point_map(depth: torch.Tensor, intrinsics: torch.Tensor) -> torch.Tensor:
+ """Back-project a (..., H, W) depth map through K^-1 to (..., H, W, 3) camera-space points.
+
+ Intrinsics use normalized image coords (x in [0, 1] left->right, y in [0, 1] top->bottom).
+ """
+ H, W = depth.shape[-2:]
+ device, dtype = depth.device, depth.dtype
+ u = (torch.arange(W, dtype=dtype, device=device) + 0.5) / W
+ v = (torch.arange(H, dtype=dtype, device=device) + 0.5) / H
+ grid_v, grid_u = torch.meshgrid(v, u, indexing="ij")
+ pix = torch.stack([grid_u, grid_v, torch.ones_like(grid_u)], dim=-1)
+ K_inv = torch.linalg.inv(intrinsics)
+ rays = torch.einsum("...ij,hwj->...hwi", K_inv, pix)
+ return rays * depth.unsqueeze(-1)
+
+
+def _solve_optimal_shift(uv: np.ndarray, xyz: np.ndarray,
+ focal: Optional[float] = None) -> Tuple[float, float]:
+ """LM-solve for z-shift; when focal is None, also recovers the optimal focal."""
+ uv = uv.reshape(-1, 2)
+ xy = xyz[..., :2].reshape(-1, 2)
+ z = xyz[..., 2].reshape(-1)
+
+ def fn(shift):
+ xy_proj = xy / (z + shift)[:, None]
+ f = focal if focal is not None else (xy_proj * uv).sum() / np.square(xy_proj).sum()
+ return (f * xy_proj - uv).ravel()
+
+ sol = least_squares(fn, x0=0.0, ftol=1e-3, method="lm")
+ shift = float(np.asarray(sol["x"]).squeeze())
+ if focal is None:
+ xy_proj = xy / (z + shift)[:, None]
+ focal = float((xy_proj * uv).sum() / np.square(xy_proj).sum())
+ return shift, focal
+
+
+def recover_focal_shift(points: torch.Tensor, mask: Optional[torch.Tensor] = None,
+ focal: Optional[torch.Tensor] = None, downsample_size: Tuple[int, int] = (64, 64)
+ ) -> Tuple[torch.Tensor, torch.Tensor]:
+ """Recover the focal length and z-shift that turn points into a metric point map.
+
+ Optical center is at the image center; returned focal is relative to half the image diagonal.
+ Returns (focal, shift) on the same device/dtype as points.
+ """
+ shape = points.shape
+ H, W = shape[-3], shape[-2]
+ points_b = points.reshape(-1, H, W, 3)
+ mask_b = None if mask is None else mask.reshape(-1, H, W)
+ focal_b = None if focal is None else focal.reshape(-1)
+
+ uv = normalized_view_plane_uv(W, H, dtype=points.dtype, device=points.device)
+
+ points_lr = F.interpolate(points_b.permute(0, 3, 1, 2), downsample_size, mode="nearest").permute(0, 2, 3, 1)
+ uv_lr = F.interpolate(uv.unsqueeze(0).permute(0, 3, 1, 2), downsample_size, mode="nearest").squeeze(0).permute(1, 2, 0)
+ mask_lr = None
+ if mask_b is not None:
+ mask_lr = F.interpolate(mask_b.to(torch.float32).unsqueeze(1), downsample_size, mode="nearest").squeeze(1) > 0
+
+ uv_np = uv_lr.detach().cpu().numpy()
+ points_np = points_lr.detach().cpu().numpy()
+ mask_np = None if mask_lr is None else mask_lr.detach().cpu().numpy()
+ focal_np = None if focal_b is None else focal_b.detach().cpu().numpy()
+
+ out_focal: list = []
+ out_shift: list = []
+ for i in range(points_b.shape[0]):
+ if mask_np is None:
+ xyz_i = points_np[i].reshape(-1, 3)
+ uv_i = uv_np.reshape(-1, 2)
+ else:
+ sel = mask_np[i]
+ if sel.sum() < 2:
+ out_focal.append(1.0)
+ out_shift.append(0.0)
+ continue
+ xyz_i = points_np[i][sel]
+ uv_i = uv_np[sel]
+ if focal_np is None:
+ shift_i, focal_i = _solve_optimal_shift(uv_i, xyz_i)
+ out_focal.append(focal_i)
+ else:
+ shift_i, _ = _solve_optimal_shift(uv_i, xyz_i, focal=float(focal_np[i]))
+ out_shift.append(shift_i)
+
+ shift_t = torch.tensor(out_shift, device=points.device, dtype=points.dtype).reshape(shape[:-3])
+ if focal is None:
+ focal_t = torch.tensor(out_focal, device=points.device, dtype=points.dtype).reshape(shape[:-3])
+ else:
+ focal_t = focal.reshape(shape[:-3])
+ return focal_t, shift_t
+
+
+def depth_map_edge(depth: torch.Tensor, atol: Optional[float] = None, rtol: Optional[float] = None, kernel_size: int = 3) -> torch.Tensor:
+ """Per-pixel boolean: True where the local depth window's max-min span exceeds atol or rtol*depth."""
+ shape = depth.shape
+ d = depth.reshape(-1, 1, *shape[-2:])
+ pad = kernel_size // 2
+ diff = F.max_pool2d(d, kernel_size, stride=1, padding=pad) + F.max_pool2d(-d, kernel_size, stride=1, padding=pad)
+ edge = torch.zeros_like(d, dtype=torch.bool)
+ if atol is not None:
+ edge |= diff > atol
+ if rtol is not None:
+ edge |= (diff / d.clamp_min(1e-6)).nan_to_num_() > rtol
+ return edge.reshape(*shape)
+
+
+def triangulate_grid_mesh(points: torch.Tensor, mask: Optional[torch.Tensor] = None, decimation: int = 1, discontinuity_threshold: float = 0.04,
+ depth: Optional[torch.Tensor] = None) -> Tuple[torch.Tensor, torch.Tensor, torch.Tensor]:
+ """Triangulate a (H, W, 3) point map into (vertices, faces, uvs) on CPU.
+
+ Vertices: pixels with finite coords (passing optional mask). Quads with four valid corners
+ become two triangles. depth overrides the scalar used for the rtol edge check; pass radial
+ depth for panoramas (the default points[..., 2] goes negative below the equator).
+ """
+ points = points.detach().cpu()
+ finite = torch.isfinite(points).all(dim=-1)
+ if mask is None:
+ mask = finite
+ else:
+ mask = mask.detach().cpu().to(torch.bool) & finite
+
+ if discontinuity_threshold > 0:
+ d = depth.detach().cpu() if depth is not None else points[..., 2]
+ # Replace inf with 0 so max-pool doesn't poison neighbourhoods (mask above already excludes those pixels).
+ d_finite = torch.where(finite, d, torch.zeros_like(d))
+ edge = depth_map_edge(d_finite, rtol=discontinuity_threshold)
+ mask = mask & ~edge
+
+ if decimation > 1:
+ points = points[::decimation, ::decimation].contiguous()
+ mask = mask[::decimation, ::decimation].contiguous()
+ H, W = points.shape[:2]
+
+ flat_mask = mask.reshape(-1)
+ idx = torch.full((H * W,), -1, dtype=torch.long)
+ n_valid = int(flat_mask.sum().item())
+ idx[flat_mask] = torch.arange(n_valid, dtype=torch.long)
+ idx = idx.reshape(H, W)
+
+ vertices = points.reshape(-1, 3)[flat_mask].contiguous()
+
+ yy, xx = torch.meshgrid(torch.arange(H), torch.arange(W), indexing="ij")
+ u = xx.float() / max(W - 1, 1)
+ v = yy.float() / max(H - 1, 1)
+ uvs = torch.stack([u, v], dim=-1).reshape(-1, 2)[flat_mask].contiguous()
+
+ a, b, c, d = idx[:-1, :-1], idx[:-1, 1:], idx[1:, 1:], idx[1:, :-1]
+ quad_ok = (a >= 0) & (b >= 0) & (c >= 0) & (d >= 0)
+ a, b, c, d = a[quad_ok], b[quad_ok], c[quad_ok], d[quad_ok]
+ faces = torch.cat([torch.stack([a, b, c], dim=-1), torch.stack([a, c, d], dim=-1)], dim=0).contiguous()
+ return vertices, faces, uvs
diff --git a/ComfyUI/comfy/ldm/moge/model.py b/ComfyUI/comfy/ldm/moge/model.py
new file mode 100644
index 0000000000000000000000000000000000000000..1695626bcb73c91644738d7ab2328ac44f3844d8
--- /dev/null
+++ b/ComfyUI/comfy/ldm/moge/model.py
@@ -0,0 +1,346 @@
+"""MoGe v1 / v2 inference modules and a state-dict-driven builder.
+
+V1: DINOv2 backbone + multi-output head (points, mask).
+V2: DINOv2 encoder + neck + per-output heads (points, mask, normal, optional metric-scale MLP).
+"""
+
+
+from numbers import Number
+from typing import Any, Dict, List, Optional, Tuple, Union
+
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+
+import comfy.ops
+import comfy.model_management
+import comfy.model_patcher
+
+from comfy.image_encoders.dino2 import Dinov2Model
+
+from .geometry import depth_map_to_point_map, intrinsics_from_focal_center, recover_focal_shift
+from .modules import ConvStack, DINOv2Encoder, HeadV1, MLP, _view_plane_uv_grid
+
+
+def _remap_points(points: torch.Tensor) -> torch.Tensor:
+ """Apply the exp remap: z -> exp(z), xy stays linear and gets scaled by the new z."""
+ xy, z = points.split([2, 1], dim=-1)
+ z = torch.exp(z)
+ return torch.cat([xy * z, z], dim=-1)
+
+
+def _detect_dinov2(sd: dict, prefix: str) -> Dict[str, Any]:
+ # All shipped MoGe checkpoints use plain DINOv2
+ hidden = sd[prefix + "embeddings.cls_token"].shape[-1]
+ layer_prefix = prefix + "encoder.layer."
+ depth = 1 + max(int(k[len(layer_prefix):].split(".")[0]) for k in sd if k.startswith(layer_prefix))
+ return {
+ "hidden_size": hidden,
+ "num_attention_heads": hidden // 64,
+ "num_hidden_layers": depth,
+ "layer_norm_eps": 1e-6,
+ "use_swiglu_ffn": False,
+ }
+
+
+class MoGeModelV1(nn.Module):
+ """MoGe v1: DINOv2 backbone + HeadV1 (points, mask)."""
+
+ image_mean: torch.Tensor
+ image_std: torch.Tensor
+
+ intermediate_layers = 4
+ num_tokens_range: Tuple[Number, Number] = (1200, 2500)
+ mask_threshold = 0.5
+
+ def __init__(self, backbone: Dict[str, Any], dim_upsample: List[int] = (256, 128, 128),
+ num_res_blocks: int = 1, dim_times_res_block_hidden: int = 1,
+ dtype=None, device=None, operations=comfy.ops.manual_cast):
+ super().__init__()
+ self.backbone = Dinov2Model(backbone, dtype, device, operations)
+ self.head = HeadV1(dim_in=backbone["hidden_size"], dim_upsample=list(dim_upsample),
+ num_res_blocks=num_res_blocks, dim_times_res_block_hidden=dim_times_res_block_hidden,
+ dtype=dtype, device=device, operations=operations)
+ self.register_buffer("image_mean", torch.tensor([0.485, 0.456, 0.406]).view(1, 3, 1, 1))
+ self.register_buffer("image_std", torch.tensor([0.229, 0.224, 0.225]).view(1, 3, 1, 1))
+
+ def forward(self, image: torch.Tensor, num_tokens: int) -> Dict[str, torch.Tensor]:
+ H, W = image.shape[-2:]
+ resize = ((num_tokens * 14 ** 2) / (H * W)) ** 0.5
+ rh, rw = int(H * resize), int(W * resize)
+ x = F.interpolate(image, (rh, rw), mode="bicubic", align_corners=False, antialias=True)
+ x = (x - self.image_mean) / self.image_std
+ x14 = F.interpolate(x, (rh // 14 * 14, rw // 14 * 14), mode="bilinear", align_corners=False, antialias=True)
+
+ n_layers = len(self.backbone.encoder.layer)
+ indices = list(range(n_layers - self.intermediate_layers, n_layers))
+ feats = self.backbone.get_intermediate_layers(x14, indices, apply_norm=True)
+
+ points, mask = self.head(feats, x)
+ points = F.interpolate(points.float(), (H, W), mode="bilinear", align_corners=False)
+ points = _remap_points(points.permute(0, 2, 3, 1))
+
+ mask = F.interpolate(mask.float(), (H, W), mode="bilinear", align_corners=False).squeeze(1)
+
+ return {"points": points, "mask": mask}
+
+ @classmethod
+ def from_state_dict(cls, sd, dtype=None, device=None, operations=comfy.ops.manual_cast):
+ """Detect the v1 head config from sd, build a model, and load weights."""
+ n_up = 1 + max(int(k.split(".")[2]) for k in sd if k.startswith("head.upsample_blocks."))
+ dim_upsample = [sd[f"head.upsample_blocks.{i}.0.0.weight"].shape[1] for i in range(n_up)]
+ # Each upsample stage is Sequential[upsampler, *res_blocks]; count res blocks at level 0.
+ num_res_blocks = max({int(k.split(".")[3]) for k in sd if k.startswith("head.upsample_blocks.0.")})
+ hidden_out = sd["head.upsample_blocks.0.1.layers.2.weight"].shape[0]
+ dim_times = max(hidden_out // dim_upsample[0], 1)
+ model = cls(backbone=_detect_dinov2(sd, prefix="backbone."),
+ dim_upsample=dim_upsample, num_res_blocks=num_res_blocks, dim_times_res_block_hidden=dim_times,
+ dtype=dtype, device=device, operations=operations)
+ model.load_state_dict(sd, strict=True)
+ return model
+
+
+class MoGeModelV2(nn.Module):
+ """MoGe v2: DINOv2 encoder + neck + per-output heads (points/mask/normal/metric-scale)."""
+
+ intermediate_layers = 4
+ num_tokens_range: Tuple[Number, Number] = (1200, 3600)
+
+ def __init__(self,
+ encoder: Dict[str, Any],
+ neck: Dict[str, Any],
+ points_head: Dict[str, Any],
+ mask_head: Dict[str, Any],
+ scale_head: Dict[str, Any],
+ normal_head: Optional[Dict[str, Any]] = None,
+ dtype=None, device=None, operations=comfy.ops.manual_cast):
+ super().__init__()
+ self.encoder = DINOv2Encoder(**encoder, dtype=dtype, device=device, operations=operations)
+ self.neck = ConvStack(**neck, dtype=dtype, device=device, operations=operations)
+ self.points_head = ConvStack(**points_head, dtype=dtype, device=device, operations=operations)
+ self.mask_head = ConvStack(**mask_head, dtype=dtype, device=device, operations=operations)
+ self.scale_head = MLP(**scale_head, dtype=dtype, device=device, operations=operations)
+ if normal_head is not None:
+ self.normal_head = ConvStack(**normal_head, dtype=dtype, device=device, operations=operations)
+
+ def forward(self, image: torch.Tensor, num_tokens: int) -> Dict[str, torch.Tensor]:
+ B, _, H, W = image.shape
+ device, dtype = image.device, image.dtype
+ aspect_ratio = W / H
+ base_h = round((num_tokens / aspect_ratio) ** 0.5)
+ base_w = round((num_tokens * aspect_ratio) ** 0.5)
+
+ feat_top, cls_token = self.encoder(image, base_h, base_w, return_class_token=True)
+
+ # 5-level pyramid: feat at level 0 concatenated with UV, other levels UV-only.
+ levels = [_view_plane_uv_grid(B, base_h * (2 ** L), base_w * (2 ** L), aspect_ratio, dtype, device)
+ for L in range(5)]
+ levels[0] = torch.cat([feat_top, levels[0]], dim=1)
+
+ feats = self.neck(levels)
+
+ def _resize(v):
+ return F.interpolate(v, (H, W), mode="bilinear", align_corners=False)
+
+ points = _remap_points(_resize(self.points_head(feats)[-1]).permute(0, 2, 3, 1))
+ mask = _resize(self.mask_head(feats)[-1]).squeeze(1).sigmoid()
+ metric_scale = self.scale_head(cls_token).squeeze(1).exp()
+
+ result = {"points": points, "mask": mask, "metric_scale": metric_scale}
+ if hasattr(self, "normal_head"):
+ normal = _resize(self.normal_head(feats)[-1])
+ result["normal"] = F.normalize(normal.permute(0, 2, 3, 1), dim=-1)
+ return result
+
+ @classmethod
+ def from_state_dict(cls, sd, dtype=None, device=None, operations=comfy.ops.manual_cast):
+ """Detect the v2 encoder/neck/heads config from sd, build a model, and load weights."""
+ backbone = _detect_dinov2(sd, prefix="encoder.backbone.")
+ depth = backbone["num_hidden_layers"]
+ n = cls.intermediate_layers
+ encoder = {
+ "backbone": backbone,
+ "intermediate_layers": [(depth // n) * (i + 1) - 1 for i in range(n)],
+ "dim_out": sd["encoder.output_projections.0.weight"].shape[0],
+ }
+ # scale_head is an MLP: Sequential of [Linear, ReLU, ..., Linear]; Linear weight is (out, in).
+ scale_idxs = sorted({int(k.split(".")[1]) for k in sd if k.startswith("scale_head.")})
+ scale_first = sd[f"scale_head.{scale_idxs[0]}.weight"]
+ cfg: Dict[str, Any] = {
+ "encoder": encoder,
+ "neck": cls._detect_convstack(sd, "neck."),
+ "points_head": cls._detect_convstack(sd, "points_head."),
+ "mask_head": cls._detect_convstack(sd, "mask_head."),
+ "scale_head": {"dims": [scale_first.shape[1]] + [sd[f"scale_head.{i}.weight"].shape[0] for i in scale_idxs]},
+ }
+ if any(k.startswith("normal_head.") for k in sd):
+ cfg["normal_head"] = cls._detect_convstack(sd, "normal_head.")
+ model = cls(**cfg, dtype=dtype, device=device, operations=operations)
+ model.load_state_dict(sd, strict=True)
+ return model
+
+ @staticmethod
+ def _detect_convstack(sd: dict, prefix: str) -> Dict[str, Any]:
+ """Reconstruct a ConvStack config from the keys under prefix"""
+ in_keys = [k for k in sd if k.startswith(f"{prefix}input_blocks.") and k.endswith(".weight")]
+ n = 1 + max(int(k[len(f"{prefix}input_blocks."):].split(".")[0]) for k in in_keys)
+
+ in_shapes = [sd[f"{prefix}input_blocks.{i}.weight"].shape for i in range(n)]
+ has_out = lambda i: f"{prefix}output_blocks.{i}.weight" in sd
+ has_norm = f"{prefix}res_blocks.0.0.layers.0.weight" in sd
+
+ def num_res_at(i):
+ rb_prefix = f"{prefix}res_blocks.{i}."
+ return len({int(k[len(rb_prefix):].split(".")[0]) for k in sd if k.startswith(rb_prefix)})
+
+ return {
+ "dim_in": [s[1] for s in in_shapes],
+ "dim_res_blocks": [s[0] for s in in_shapes],
+ "dim_out": [sd[f"{prefix}output_blocks.{i}.weight"].shape[0] if has_out(i) else None for i in range(n)],
+ "num_res_blocks": [num_res_at(i) for i in range(n)],
+ "resamplers": ["conv_transpose" if f"{prefix}resamplers.{i}.0.weight" in sd else "bilinear"
+ for i in range(n - 1)],
+ "res_block_in_norm": "layer_norm" if has_norm else "none",
+ "res_block_hidden_norm": "group_norm" if has_norm else "none",
+ }
+
+
+# Translate the Meta-style DINOv2 keys MoGe ships to the naming ComfyUI DINOv2 port expects,
+# and split each fused qkv tensor into Q/K/V.
+_DINOV2_TOPLEVEL_RENAMES = {
+ "patch_embed.proj.weight": "embeddings.patch_embeddings.projection.weight",
+ "patch_embed.proj.bias": "embeddings.patch_embeddings.projection.bias",
+ "cls_token": "embeddings.cls_token",
+ "pos_embed": "embeddings.position_embeddings",
+ "register_tokens": "embeddings.register_tokens",
+ "mask_token": "embeddings.mask_token",
+ "norm.weight": "layernorm.weight",
+ "norm.bias": "layernorm.bias",
+}
+_DINOV2_BLOCK_RENAMES = [
+ ("ls1.gamma", "layer_scale1.lambda1"),
+ ("ls2.gamma", "layer_scale2.lambda1"),
+ ("attn.proj.", "attention.output.dense."),
+ ("mlp.w12.", "mlp.weights_in."),
+ ("mlp.w3.", "mlp.weights_out."),
+]
+
+
+def _remap_state_dict(sd: dict) -> dict:
+ if "model" in sd and "model_config" in sd:
+ sd = sd["model"]
+ prefix = "encoder.backbone." if any(k.startswith("encoder.backbone.") for k in sd) else "backbone."
+ out: dict = {}
+ for k, v in sd.items():
+ if not k.startswith(prefix):
+ out[k] = v
+ continue
+ rel = k[len(prefix):]
+ if rel in _DINOV2_TOPLEVEL_RENAMES:
+ out[prefix + _DINOV2_TOPLEVEL_RENAMES[rel]] = v
+ continue
+ if not rel.startswith("blocks."):
+ out[k] = v
+ continue
+ _, idx, sub = rel.split(".", 2)
+ if sub in ("attn.qkv.weight", "attn.qkv.bias"):
+ tail = sub.rsplit(".", 1)[1]
+ q, kw, vw = v.chunk(3, dim=0)
+ base = f"{prefix}encoder.layer.{idx}.attention.attention"
+ out[f"{base}.query.{tail}"] = q
+ out[f"{base}.key.{tail}"] = kw
+ out[f"{base}.value.{tail}"] = vw
+ continue
+ for old, new in _DINOV2_BLOCK_RENAMES:
+ sub = sub.replace(old, new)
+ out[f"{prefix}encoder.layer.{idx}.{sub}"] = v
+ return out
+
+
+def build_from_state_dict(sd: dict, dtype=None, device=None, operations=comfy.ops.manual_cast) -> nn.Module:
+ """Dispatch to v1 or v2 based on the DINOv2 backbone prefix."""
+ sd = _remap_state_dict(sd)
+ cls = MoGeModelV2 if any(k.startswith("encoder.backbone.") for k in sd) else MoGeModelV1
+ return cls.from_state_dict(sd, dtype=dtype, device=device, operations=operations)
+
+
+class MoGeModel:
+ """Loaded MoGe model + ComfyUI memory management."""
+
+ def __init__(self, state_dict: dict):
+ # text encoder dtype closest match
+ self.load_device = comfy.model_management.text_encoder_device()
+ offload_device = comfy.model_management.text_encoder_offload_device()
+ self.dtype = comfy.model_management.text_encoder_dtype(self.load_device)
+
+ self.model = build_from_state_dict(state_dict, dtype=self.dtype, device=offload_device, operations=comfy.ops.manual_cast).eval()
+ self.patcher = comfy.model_patcher.CoreModelPatcher(self.model, load_device=self.load_device, offload_device=offload_device)
+ self.version = "v2" if hasattr(self.model, "encoder") else "v1"
+ self.mask_threshold = float(getattr(self.model, "mask_threshold", 0.5))
+ nt = getattr(self.model, "num_tokens_range", (1200, 2500 if self.version == "v1" else 3600))
+ self.num_tokens_range = (int(nt[0]), int(nt[1]))
+
+ def infer(self, image: torch.Tensor, num_tokens: Optional[int] = None,
+ resolution_level: int = 9, fov_x: Optional[Union[Number, torch.Tensor]] = None,
+ force_projection: bool = True, apply_mask: bool = True,
+ apply_metric_scale: bool = True
+ ) -> Dict[str, torch.Tensor]:
+ """Run a single MoGe forward + post-process pass. image is (B, 3, H, W) in [0, 1]."""
+ comfy.model_management.load_model_gpu(self.patcher)
+ image = image.to(device=self.load_device, dtype=self.dtype)
+ H, W = image.shape[-2:]
+ aspect_ratio = W / H
+
+ if num_tokens is None:
+ lo, hi = self.num_tokens_range
+ num_tokens = int(lo + (resolution_level / 9) * (hi - lo))
+
+ out = self.model.forward(image, num_tokens=num_tokens)
+ points = out["points"].float() # recover_focal_shift goes through scipy on CPU; needs fp32.
+ mask_binary = out["mask"] > self.mask_threshold
+ normal = out.get("normal")
+ metric_scale = out.get("metric_scale")
+
+ diag = (1 + aspect_ratio ** 2) ** 0.5
+
+ def focal_from_fov_deg(deg):
+ fov = torch.as_tensor(deg, device=points.device, dtype=points.dtype)
+ return aspect_ratio / diag / torch.tan(torch.deg2rad(fov / 2))
+
+ if fov_x is None:
+ focal, shift = recover_focal_shift(points, mask_binary)
+ # Fall back to 60 deg FoV when the least-squares solver flips the focal sign.
+ bad = ~torch.isfinite(focal) | (focal <= 0)
+ if bool(bad.any()):
+ focal = torch.where(bad, focal_from_fov_deg(60.0), focal)
+ _, shift = recover_focal_shift(points, mask_binary, focal=focal)
+ else:
+ focal = focal_from_fov_deg(fov_x).expand(points.shape[0])
+ _, shift = recover_focal_shift(points, mask_binary, focal=focal)
+
+ f_diag = focal / 2 * diag
+ half = torch.tensor(0.5, device=points.device, dtype=points.dtype)
+ intrinsics = intrinsics_from_focal_center(f_diag / aspect_ratio, f_diag, half, half)
+ points[..., 2] = points[..., 2] + shift[..., None, None]
+ # v2 only: filter mask by depth>0 to drop metric-scale negative-depth artifacts.
+ if self.version == "v2":
+ mask_binary = mask_binary & (points[..., 2] > 0)
+ depth = points[..., 2].clone()
+
+ if force_projection:
+ points = depth_map_to_point_map(depth, intrinsics=intrinsics)
+
+ if apply_metric_scale and metric_scale is not None:
+ points = points * metric_scale[:, None, None, None]
+ depth = depth * metric_scale[:, None, None]
+
+ if apply_mask:
+ points = torch.where(mask_binary[..., None], points, torch.full_like(points, float("inf")))
+ depth = torch.where(mask_binary, depth, torch.full_like(depth, float("inf")))
+ if normal is not None:
+ normal = torch.where(mask_binary[..., None], normal, torch.zeros_like(normal))
+
+ result = {"points": points, "depth": depth, "intrinsics": intrinsics, "mask": mask_binary}
+ if normal is not None:
+ result["normal"] = normal
+ return result
diff --git a/ComfyUI/comfy/ldm/moge/modules.py b/ComfyUI/comfy/ldm/moge/modules.py
new file mode 100644
index 0000000000000000000000000000000000000000..f6443d65ae7bf4324bef105546bac6583f7342de
--- /dev/null
+++ b/ComfyUI/comfy/ldm/moge/modules.py
@@ -0,0 +1,203 @@
+"""Building blocks for MoGe: residual conv stack, resamplers, MLP, DINOv2 encoder, v1 head."""
+
+
+from typing import List, Optional, Sequence, Tuple, Union
+
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+
+import comfy.ops
+from comfy.image_encoders.dino2 import Dinov2Model
+
+from .geometry import normalized_view_plane_uv
+
+
+def _conv2d(operations, c_in: int, c_out: int, k: int = 3, *, dtype=None, device=None):
+ return operations.Conv2d(c_in, c_out, kernel_size=k, padding=k // 2, padding_mode="replicate", dtype=dtype, device=device)
+
+
+def _view_plane_uv_grid(batch: int, height: int, width: int, aspect_ratio: float, dtype, device) -> torch.Tensor:
+ """Batched normalized view-plane UV grid as a (B, 2, H, W) tensor."""
+ uv = normalized_view_plane_uv(width, height, aspect_ratio=aspect_ratio, dtype=dtype, device=device)
+ return uv.permute(2, 0, 1).unsqueeze(0).expand(batch, -1, -1, -1)
+
+
+def _concat_view_plane_uv(x: torch.Tensor, aspect_ratio: float) -> torch.Tensor:
+ """Append a 2-channel normalized view-plane UV grid to x along the channel dim."""
+ uv = _view_plane_uv_grid(x.shape[0], x.shape[-2], x.shape[-1], aspect_ratio, x.dtype, x.device)
+ return torch.cat([x, uv], dim=1)
+
+
+class ResidualConvBlock(nn.Module):
+ def __init__(self, channels: int, hidden_channels: Optional[int] = None, in_norm: str = "layer_norm", hidden_norm: str = "group_norm",
+ dtype=None, device=None, operations=comfy.ops.manual_cast):
+ super().__init__()
+ hidden_channels = hidden_channels if hidden_channels is not None else channels
+
+ in_norm_layer = operations.GroupNorm(1, channels, dtype=dtype, device=device) if in_norm == "layer_norm" else nn.Identity()
+ hidden_norm_layer = (operations.GroupNorm(max(hidden_channels // 32, 1), hidden_channels, dtype=dtype, device=device)
+ if hidden_norm == "group_norm" else nn.Identity())
+
+ self.layers = nn.Sequential(
+ in_norm_layer, nn.ReLU(), _conv2d(operations, channels, hidden_channels, dtype=dtype, device=device),
+ hidden_norm_layer, nn.ReLU(), _conv2d(operations, hidden_channels, channels, dtype=dtype, device=device),
+ )
+
+ def forward(self, x):
+ return self.layers(x) + x
+
+
+class Resampler(nn.Sequential):
+ """2x upsampler: ConvTranspose2d(2x2) or bilinear upsample, followed by a 3x3 conv."""
+
+ def __init__(self, in_channels: int, out_channels: int, type_: str, dtype=None, device=None, operations=comfy.ops.manual_cast):
+ if type_ == "conv_transpose":
+ up = operations.ConvTranspose2d(in_channels, out_channels, kernel_size=2, stride=2, dtype=dtype, device=device)
+ conv_in = out_channels
+ else: # "bilinear"
+ up = nn.Upsample(scale_factor=2, mode="bilinear", align_corners=False)
+ conv_in = in_channels
+ super().__init__(up, _conv2d(operations, conv_in, out_channels, dtype=dtype, device=device))
+
+
+class MLP(nn.Sequential):
+ def __init__(self, dims: Sequence[int], dtype=None, device=None, operations=comfy.ops.manual_cast):
+ layers = []
+ for d_in, d_out in zip(dims[:-2], dims[1:-1]):
+ layers.append(operations.Linear(d_in, d_out, dtype=dtype, device=device))
+ layers.append(nn.ReLU(inplace=True))
+ layers.append(operations.Linear(dims[-2], dims[-1], dtype=dtype, device=device))
+ super().__init__(*layers)
+
+
+class ConvStack(nn.Module):
+ def __init__(self, dim_in: List[Optional[int]], dim_res_blocks: List[int], dim_out: List[Optional[int]], resamplers: List[str],
+ num_res_blocks: List[int], dim_times_res_block_hidden: int = 1, res_block_in_norm: str = "layer_norm", res_block_hidden_norm: str = "group_norm",
+ dtype=None, device=None, operations=comfy.ops.manual_cast):
+ super().__init__()
+
+ self.input_blocks = nn.ModuleList([
+ (_conv2d(operations, d_in, d_res, k=1, dtype=dtype, device=device)
+ if d_in is not None else nn.Identity())
+ for d_in, d_res in zip(dim_in, dim_res_blocks)
+ ])
+
+ self.resamplers = nn.ModuleList([
+ Resampler(prev, succ, type_=r, dtype=dtype, device=device, operations=operations)
+ for prev, succ, r in zip(dim_res_blocks[:-1], dim_res_blocks[1:], resamplers)
+ ])
+
+ self.res_blocks = nn.ModuleList([
+ nn.Sequential(*[
+ ResidualConvBlock(d_res, dim_times_res_block_hidden * d_res, in_norm=res_block_in_norm, hidden_norm=res_block_hidden_norm, dtype=dtype, device=device, operations=operations)
+ for _ in range(num_res_blocks[i])
+ ])
+ for i, d_res in enumerate(dim_res_blocks)
+ ])
+
+ self.output_blocks = nn.ModuleList([
+ (_conv2d(operations, d_res, d_out, k=1, dtype=dtype, device=device)
+ if d_out is not None else nn.Identity())
+ for d_out, d_res in zip(dim_out, dim_res_blocks)
+ ])
+
+ def forward(self, in_features: List[Optional[torch.Tensor]]):
+ out_features = []
+ x = None
+ for i in range(len(self.res_blocks)):
+ feat = self.input_blocks[i](in_features[i]) if in_features[i] is not None else None
+ if i == 0:
+ x = feat
+ elif feat is not None:
+ x = x + feat
+ x = self.res_blocks[i](x)
+ out_features.append(self.output_blocks[i](x))
+ if i < len(self.res_blocks) - 1:
+ x = self.resamplers[i](x)
+ return out_features
+
+
+class DINOv2Encoder(nn.Module):
+ """Comfy DINOv2 backbone with per-layer 1x1 projection heads."""
+
+ def __init__(self, backbone: dict, intermediate_layers: List[int], dim_out: int, dtype=None, device=None, operations=comfy.ops.manual_cast):
+ super().__init__()
+ self.intermediate_layers = list(intermediate_layers)
+ dim_features = backbone["hidden_size"]
+ self.backbone = Dinov2Model(backbone, dtype, device, operations)
+ self.output_projections = nn.ModuleList([
+ _conv2d(operations, dim_features, dim_out, k=1, dtype=dtype, device=device)
+ for _ in range(len(self.intermediate_layers))
+ ])
+ self.register_buffer("image_mean", torch.tensor([0.485, 0.456, 0.406]).view(1, 3, 1, 1))
+ self.register_buffer("image_std", torch.tensor([0.229, 0.224, 0.225]).view(1, 3, 1, 1))
+
+ def forward(self, image: torch.Tensor, token_rows: int, token_cols: int,
+ return_class_token: bool = False) -> Union[torch.Tensor, Tuple[torch.Tensor, torch.Tensor]]:
+ image_14 = F.interpolate(image, (token_rows * 14, token_cols * 14), mode="bilinear", align_corners=False, antialias=True)
+ image_14 = (image_14 - self.image_mean) / self.image_std
+ feats = self.backbone.get_intermediate_layers(image_14, self.intermediate_layers, apply_norm=True)
+ x = torch.stack([
+ proj(feat.permute(0, 2, 1).unflatten(2, (token_rows, token_cols)).contiguous())
+ for proj, (feat, _cls) in zip(self.output_projections, feats)
+ ], dim=1).sum(dim=1)
+ if return_class_token:
+ return x, feats[-1][1]
+ return x
+
+
+class HeadV1(nn.Module):
+ """v1 head: 4 backbone-feature projections -> shared upsample stack -> per-target output convs (points, mask)."""
+
+ NUM_FEATURES = 4
+ DIM_PROJ = 512
+ DIM_OUT = (3, 1) # 3 channels for points, 1 for mask
+ LAST_CONV_CHANNELS = 32
+
+ def __init__(self, dim_in: int, dim_upsample: List[int] = (256, 128, 128), num_res_blocks: int = 1, dim_times_res_block_hidden: int = 1,
+ dtype=None, device=None, operations=comfy.ops.manual_cast):
+ super().__init__()
+ self.projects = nn.ModuleList([
+ _conv2d(operations, dim_in, self.DIM_PROJ, k=1, dtype=dtype, device=device)
+ for _ in range(self.NUM_FEATURES)
+ ])
+ def upsampler(in_ch, out_ch):
+ return nn.Sequential(
+ operations.ConvTranspose2d(in_ch, out_ch, kernel_size=2, stride=2, dtype=dtype, device=device),
+ _conv2d(operations, out_ch, out_ch, dtype=dtype, device=device),
+ )
+
+ in_chs = [self.DIM_PROJ] + list(dim_upsample[:-1])
+ self.upsample_blocks = nn.ModuleList([
+ nn.Sequential(
+ upsampler(in_ch + 2, out_ch),
+ *(ResidualConvBlock(out_ch, dim_times_res_block_hidden * out_ch, dtype=dtype, device=device, operations=operations)
+ for _ in range(num_res_blocks))
+ )
+ for in_ch, out_ch in zip(in_chs, dim_upsample)
+ ])
+ self.output_block = nn.ModuleList([
+ nn.Sequential(
+ _conv2d(operations, dim_upsample[-1] + 2, self.LAST_CONV_CHANNELS, dtype=dtype, device=device),
+ nn.ReLU(inplace=True),
+ _conv2d(operations, self.LAST_CONV_CHANNELS, d_out, k=1, dtype=dtype, device=device),
+ )
+ for d_out in self.DIM_OUT
+ ])
+
+ def forward(self, hidden_states, image: torch.Tensor):
+ img_h, img_w = image.shape[-2:]
+ patch_h, patch_w = img_h // 14, img_w // 14
+ aspect = img_w / img_h
+ x = torch.stack([
+ proj(feat.permute(0, 2, 1).unflatten(2, (patch_h, patch_w)).contiguous())
+ for proj, (feat, _cls) in zip(self.projects, hidden_states)
+ ], dim=1).sum(dim=1)
+
+ for block in self.upsample_blocks:
+ x = block(_concat_view_plane_uv(x, aspect))
+
+ x = F.interpolate(x, (img_h, img_w), mode="bilinear", align_corners=False)
+ x = _concat_view_plane_uv(x, aspect)
+ return [block(x) for block in self.output_block]
diff --git a/ComfyUI/comfy/ldm/moge/panorama.py b/ComfyUI/comfy/ldm/moge/panorama.py
new file mode 100644
index 0000000000000000000000000000000000000000..18d0cb665bacebbb1a29ebfa94fccd561d361d5e
--- /dev/null
+++ b/ComfyUI/comfy/ldm/moge/panorama.py
@@ -0,0 +1,312 @@
+"""Panorama (equirectangular) inference helpers for MoGe.
+
+Splits an equirect into 12 perspective views via an icosahedron camera rig, runs
+the model per view, and stitches per-view distance maps back into a single
+equirect distance map via a multi-scale Poisson + gradient sparse solve.
+Image sampling uses F.grid_sample (GPU); the sparse solve uses lsmr (CPU).
+"""
+
+
+from typing import Callable, List, Optional, Tuple
+
+import numpy as np
+import torch
+import torch.nn.functional as F
+
+from scipy.ndimage import convolve, map_coordinates
+from scipy.sparse import vstack, csr_array
+from scipy.sparse.linalg import lsmr
+
+
+def _icosahedron_directions() -> np.ndarray:
+ """12 icosahedron-vertex directions (non-normalised, matching upstream's vertex order)."""
+ A = (1.0 + np.sqrt(5.0)) / 2.0
+ return np.array([
+ [0, 1, A], [0, -1, A], [0, 1, -A], [0, -1, -A],
+ [1, A, 0], [-1, A, 0], [1, -A, 0], [-1, -A, 0],
+ [A, 0, 1], [A, 0, -1], [-A, 0, 1], [-A, 0, -1],
+ ], dtype=np.float32)
+
+
+def _intrinsics_from_fov(fov_x_rad: float, fov_y_rad: float) -> np.ndarray:
+ """Normalised-image (unit-square) K matrix."""
+ fx = 0.5 / np.tan(fov_x_rad / 2)
+ fy = 0.5 / np.tan(fov_y_rad / 2)
+ return np.array([[fx, 0, 0.5], [0, fy, 0.5], [0, 0, 1]], dtype=np.float32)
+
+
+def _extrinsics_look_at(eye: np.ndarray, target: np.ndarray, up: np.ndarray) -> np.ndarray:
+ """OpenCV-convention world->camera extrinsics for an array of look-at targets (N, 4, 4)."""
+ eye = np.asarray(eye, dtype=np.float32)
+ target = np.asarray(target, dtype=np.float32)
+ up = np.asarray(up, dtype=np.float32)
+ if target.ndim == 1:
+ target = target[None]
+
+ fwd = target - eye
+ fwd = fwd / np.linalg.norm(fwd, axis=-1, keepdims=True).clip(1e-12)
+ right = np.cross(fwd, up)
+ right_norm = np.linalg.norm(right, axis=-1, keepdims=True)
+ # Fall back to an arbitrary perpendicular if forward is parallel to up.
+ parallel = right_norm.squeeze(-1) < 1e-6
+ if parallel.any():
+ alt_up = np.array([1, 0, 0], dtype=np.float32)
+ right = np.where(parallel[:, None], np.cross(fwd, alt_up), right)
+ right_norm = np.linalg.norm(right, axis=-1, keepdims=True)
+ right = right / right_norm.clip(1e-12)
+ new_up = np.cross(fwd, right)
+
+ R = np.stack([right, new_up, fwd], axis=-2)
+ t = -np.einsum("nij,j->ni", R, eye)
+ E = np.zeros((R.shape[0], 4, 4), dtype=np.float32)
+ E[:, :3, :3] = R
+ E[:, :3, 3] = t
+ E[:, 3, 3] = 1.0
+ return E
+
+
+def get_panorama_cameras() -> Tuple[np.ndarray, List[np.ndarray]]:
+ """Returns (extrinsics (12, 4, 4), [intrinsics] * 12) for icosahedron views at 90 deg FoV."""
+ targets = _icosahedron_directions()
+ eye = np.zeros(3, dtype=np.float32)
+ up = np.array([0, 0, 1], dtype=np.float32)
+ extrinsics = _extrinsics_look_at(eye, targets, up)
+ K = _intrinsics_from_fov(np.deg2rad(90.0), np.deg2rad(90.0))
+ return extrinsics, [K] * len(targets)
+
+
+def spherical_uv_to_directions(uv: np.ndarray) -> np.ndarray:
+ """Equirect UV in [0, 1] -> 3D unit-direction (Z up)."""
+ theta = (1 - uv[..., 0]) * (2 * np.pi)
+ phi = uv[..., 1] * np.pi
+ return np.stack([
+ np.sin(phi) * np.cos(theta),
+ np.sin(phi) * np.sin(theta),
+ np.cos(phi),
+ ], axis=-1).astype(np.float32)
+
+
+def directions_to_spherical_uv(directions: np.ndarray) -> np.ndarray:
+ """3D direction -> equirect UV in [0, 1]."""
+ n = np.linalg.norm(directions, axis=-1, keepdims=True).clip(1e-12)
+ d = directions / n
+ u = 1 - np.arctan2(d[..., 1], d[..., 0]) / (2 * np.pi) % 1.0
+ v = np.arccos(d[..., 2].clip(-1, 1)) / np.pi
+ return np.stack([u, v], axis=-1).astype(np.float32)
+
+
+def _uv_grid(H: int, W: int) -> np.ndarray:
+ """Pixel-center UV grid in [0, 1]; (H, W, 2)."""
+ u = (np.arange(W, dtype=np.float32) + 0.5) / W
+ v = (np.arange(H, dtype=np.float32) + 0.5) / H
+ return np.stack(np.meshgrid(u, v, indexing="xy"), axis=-1)
+
+
+def _unproject_cv(uv: np.ndarray, depth: np.ndarray,
+ extrinsics: np.ndarray, intrinsics: np.ndarray) -> np.ndarray:
+ """Back-project pixels into world coords (OpenCV convention)."""
+ pix = np.concatenate([uv, np.ones_like(uv[..., :1])], axis=-1)
+ K_inv = np.linalg.inv(intrinsics)
+ cam = pix @ K_inv.T * depth[..., None]
+ cam_h = np.concatenate([cam, np.ones_like(cam[..., :1])], axis=-1)
+ E_inv = np.linalg.inv(extrinsics)
+ return (cam_h @ E_inv.T)[..., :3]
+
+
+def _project_cv(points: np.ndarray, extrinsics: np.ndarray, intrinsics: np.ndarray) -> Tuple[np.ndarray, np.ndarray]:
+ """World coords -> (uv, depth) in the camera (OpenCV convention)."""
+ pts_h = np.concatenate([points, np.ones_like(points[..., :1])], axis=-1)
+ cam = pts_h @ extrinsics.T
+ cam_xyz = cam[..., :3]
+ depth = cam_xyz[..., 2]
+ proj = cam_xyz @ intrinsics.T
+ uv = proj[..., :2] / proj[..., 2:3].clip(1e-12)
+ return uv.astype(np.float32), depth.astype(np.float32)
+
+
+def _grid_sample_uv(img_bchw: torch.Tensor, uv: torch.Tensor, mode: str = "bilinear") -> torch.Tensor:
+ """Sample img_bchw at UV-in-[0,1] coords uv of shape (B, H, W, 2); replicate-border."""
+ grid = uv * 2.0 - 1.0
+ return F.grid_sample(img_bchw, grid, mode=mode, padding_mode="border", align_corners=False)
+
+
+def split_panorama_image(image: torch.Tensor, extrinsics: np.ndarray, intrinsics: List[np.ndarray], resolution: int) -> torch.Tensor:
+ """(3, Hp, Wp) equirect on any device -> (N, 3, R, R) perspective crops on the same device."""
+ device = image.device
+ N = len(extrinsics)
+ uv = _uv_grid(resolution, resolution)
+ sample_uvs = []
+ for i in range(N):
+ world = _unproject_cv(uv, np.ones(uv.shape[:-1], dtype=np.float32), extrinsics[i], intrinsics[i])
+ sample_uvs.append(directions_to_spherical_uv(world))
+ sample_uvs = np.stack(sample_uvs, axis=0)
+
+ img_bchw = image.unsqueeze(0).expand(N, -1, -1, -1).contiguous()
+ sample_uvs_t = torch.from_numpy(sample_uvs).to(device=device, dtype=image.dtype)
+ return _grid_sample_uv(img_bchw, sample_uvs_t, mode="bilinear")
+
+
+def _poisson_equation(W: int, H: int, wrap_x: bool = False, wrap_y: bool = False):
+ """Sparse Laplacian operator over the H x W grid."""
+ grid_index = np.arange(H * W).reshape(H, W)
+ grid_index = np.pad(grid_index, ((0, 0), (1, 1)), mode="wrap" if wrap_x else "edge")
+ grid_index = np.pad(grid_index, ((1, 1), (0, 0)), mode="wrap" if wrap_y else "edge")
+
+ data = np.array([[-4, 1, 1, 1, 1]], dtype=np.float32).repeat(H * W, axis=0).reshape(-1)
+ indices = np.stack([
+ grid_index[1:-1, 1:-1],
+ grid_index[:-2, 1:-1], grid_index[2:, 1:-1],
+ grid_index[1:-1, :-2], grid_index[1:-1, 2:],
+ ], axis=-1).reshape(-1)
+ indptr = np.arange(0, H * W * 5 + 1, 5)
+ return csr_array((data, indices, indptr), shape=(H * W, H * W))
+
+
+def _grad_equation(W: int, H: int, wrap_x: bool = False, wrap_y: bool = False):
+ """Sparse forward-difference operator over the H x W grid."""
+ grid_index = np.arange(W * H).reshape(H, W)
+ if wrap_x:
+ grid_index = np.pad(grid_index, ((0, 0), (0, 1)), mode="wrap")
+ if wrap_y:
+ grid_index = np.pad(grid_index, ((0, 1), (0, 0)), mode="wrap")
+
+ data = np.concatenate([
+ np.concatenate([
+ np.ones((grid_index.shape[0], grid_index.shape[1] - 1), dtype=np.float32).reshape(-1, 1),
+ -np.ones((grid_index.shape[0], grid_index.shape[1] - 1), dtype=np.float32).reshape(-1, 1),
+ ], axis=1).reshape(-1),
+ np.concatenate([
+ np.ones((grid_index.shape[0] - 1, grid_index.shape[1]), dtype=np.float32).reshape(-1, 1),
+ -np.ones((grid_index.shape[0] - 1, grid_index.shape[1]), dtype=np.float32).reshape(-1, 1),
+ ], axis=1).reshape(-1),
+ ])
+ indices = np.concatenate([
+ np.concatenate([grid_index[:, :-1].reshape(-1, 1), grid_index[:, 1:].reshape(-1, 1)], axis=1).reshape(-1),
+ np.concatenate([grid_index[:-1, :].reshape(-1, 1), grid_index[1:, :].reshape(-1, 1)], axis=1).reshape(-1),
+ ])
+ nx = grid_index.shape[0] * (grid_index.shape[1] - 1)
+ ny = (grid_index.shape[0] - 1) * grid_index.shape[1]
+ indptr = np.arange(0, nx * 2 + ny * 2 + 1, 2)
+ return csr_array((data, indices, indptr), shape=(nx + ny, H * W))
+
+
+def _scipy_remap_bilinear(img: np.ndarray, sample_pixels: np.ndarray, mode: str = "bilinear") -> np.ndarray:
+ """Bilinear/nearest sampling at fractional pixel coords; out-of-range clamps to nearest border."""
+ H, W = img.shape[:2]
+ yy = np.clip(sample_pixels[..., 1], 0, H - 1)
+ xx = np.clip(sample_pixels[..., 0], 0, W - 1)
+ order = 1 if mode == "bilinear" else 0
+ if img.ndim == 2:
+ return map_coordinates(img, [yy, xx], order=order, mode="nearest").astype(img.dtype)
+ out = np.stack([
+ map_coordinates(img[..., c], [yy, xx], order=order, mode="nearest")
+ for c in range(img.shape[-1])
+ ], axis=-1)
+ return out.astype(img.dtype)
+
+
+def merge_panorama_depth(width: int, height: int,
+ distance_maps: List[np.ndarray], pred_masks: List[np.ndarray],
+ extrinsics: List[np.ndarray], intrinsics: List[np.ndarray],
+ on_view: Optional[Callable[[], None]] = None,
+ on_solve_start: Optional[Callable[[int, int], None]] = None,
+ on_solve_end: Optional[Callable[[int, int], None]] = None,
+ ) -> Tuple[np.ndarray, np.ndarray]:
+ """Stitch per-view distance maps into a single equirect distance map.
+
+ Recursive multi-scale solve: solves at half resolution first and uses that as the lsmr init
+ for the full-resolution solve. Optional callbacks fire per view processed and around each
+ lsmr solve so callers can drive a progress bar.
+ """
+
+ if max(width, height) > 256:
+ coarse_depth, _ = merge_panorama_depth(width // 2, height // 2,
+ distance_maps, pred_masks, extrinsics, intrinsics,
+ on_view=on_view,
+ on_solve_start=on_solve_start,
+ on_solve_end=on_solve_end)
+ t = torch.from_numpy(coarse_depth).unsqueeze(0).unsqueeze(0)
+ t = F.interpolate(t, size=(height, width), mode="bilinear", align_corners=False)
+ depth_init = t.squeeze().numpy().astype(np.float32)
+ else:
+ depth_init = None
+
+ spherical_directions = spherical_uv_to_directions(_uv_grid(height, width))
+
+ pano_log_grad_maps, pano_grad_masks = [], []
+ pano_log_lap_maps, pano_lap_masks = [], []
+ pano_pred_masks: List[np.ndarray] = []
+
+ for i in range(len(distance_maps)):
+ proj_uv, proj_depth = _project_cv(spherical_directions, extrinsics[i], intrinsics[i])
+ proj_valid = (proj_depth > 0) & (proj_uv > 0).all(axis=-1) & (proj_uv < 1).all(axis=-1)
+
+ Hd, Wd = distance_maps[i].shape[:2]
+ proj_pixels = np.clip(proj_uv, 0, 1) * np.array([Wd - 1, Hd - 1], dtype=np.float32)
+
+ log_dist = np.log(np.clip(distance_maps[i], 1e-6, None))
+ sampled = _scipy_remap_bilinear(log_dist, proj_pixels, mode="bilinear")
+ pano_log = np.where(proj_valid, sampled, 0.0).astype(np.float32)
+
+ sampled_mask = _scipy_remap_bilinear(pred_masks[i].astype(np.uint8), proj_pixels, mode="nearest")
+ pano_pred = proj_valid & (sampled_mask > 0)
+
+ # Equirect wraps horizontally but not vertically: wrap pad along x, edge pad along y.
+ padded = np.pad(pano_log, ((0, 0), (0, 1)), mode="wrap")
+ gx, gy = padded[:, :-1] - padded[:, 1:], padded[:-1, :] - padded[1:, :]
+ padded_m = np.pad(pano_pred, ((0, 0), (0, 1)), mode="wrap")
+ mx, my = padded_m[:, :-1] & padded_m[:, 1:], padded_m[:-1, :] & padded_m[1:, :]
+ pano_log_grad_maps.append((gx, gy))
+ pano_grad_masks.append((mx, my))
+
+ padded = np.pad(pano_log, ((1, 1), (0, 0)), mode="edge")
+ padded = np.pad(padded, ((0, 0), (1, 1)), mode="wrap")
+ lap_kernel = np.array([[0, 1, 0], [1, -4, 1], [0, 1, 0]], dtype=np.float32)
+ lap = convolve(padded, lap_kernel)[1:-1, 1:-1]
+ padded_m = np.pad(pano_pred, ((1, 1), (0, 0)), mode="edge")
+ padded_m = np.pad(padded_m, ((0, 0), (1, 1)), mode="wrap")
+ m_kernel = np.array([[0, 1, 0], [1, 1, 1], [0, 1, 0]], dtype=np.uint8)
+ lap_mask = convolve(padded_m.astype(np.uint8), m_kernel)[1:-1, 1:-1] == 5
+ pano_log_lap_maps.append(lap)
+ pano_lap_masks.append(lap_mask)
+ pano_pred_masks.append(pano_pred)
+
+ if on_view is not None:
+ on_view()
+
+ gx = np.stack([m[0] for m in pano_log_grad_maps], axis=0)
+ gy = np.stack([m[1] for m in pano_log_grad_maps], axis=0)
+ mx = np.stack([m[0] for m in pano_grad_masks], axis=0)
+ my = np.stack([m[1] for m in pano_grad_masks], axis=0)
+ gx_avg = (gx * mx).sum(axis=0) / mx.sum(axis=0).clip(1e-3)
+ gy_avg = (gy * my).sum(axis=0) / my.sum(axis=0).clip(1e-3)
+
+ laps = np.stack(pano_log_lap_maps, axis=0)
+ lap_masks = np.stack(pano_lap_masks, axis=0)
+ lap_avg = (laps * lap_masks).sum(axis=0) / lap_masks.sum(axis=0).clip(1e-3)
+
+ grad_x_mask = mx.any(axis=0).reshape(-1)
+ grad_y_mask = my.any(axis=0).reshape(-1)
+ grad_mask = np.concatenate([grad_x_mask, grad_y_mask])
+ lap_mask_flat = lap_masks.any(axis=0).reshape(-1)
+
+ A = vstack([
+ _grad_equation(width, height, wrap_x=True, wrap_y=False)[grad_mask],
+ _poisson_equation(width, height, wrap_x=True, wrap_y=False)[lap_mask_flat],
+ ])
+ b = np.concatenate([
+ gx_avg.reshape(-1)[grad_x_mask],
+ gy_avg.reshape(-1)[grad_y_mask],
+ lap_avg.reshape(-1)[lap_mask_flat],
+ ])
+ x0 = np.log(np.clip(depth_init, 1e-6, None)).reshape(-1) if depth_init is not None else None
+
+ if on_solve_start is not None:
+ on_solve_start(width, height)
+ x, *_ = lsmr(A, b, atol=1e-5, btol=1e-5, x0=x0, show=False)
+ if on_solve_end is not None:
+ on_solve_end(width, height)
+
+ pano_depth = np.exp(x).reshape(height, width).astype(np.float32)
+ pano_mask = np.any(pano_pred_masks, axis=0)
+ return pano_depth, pano_mask
diff --git a/ComfyUI/comfy/ldm/omnigen/__pycache__/omnigen2.cpython-312.pyc b/ComfyUI/comfy/ldm/omnigen/__pycache__/omnigen2.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..49ad52034e10be0ce1adad4c67eb13465068a051
Binary files /dev/null and b/ComfyUI/comfy/ldm/omnigen/__pycache__/omnigen2.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/omnigen/omnigen2.py b/ComfyUI/comfy/ldm/omnigen/omnigen2.py
new file mode 100644
index 0000000000000000000000000000000000000000..d18a9f6d0933972093f144e64c0f54352fe23a6b
--- /dev/null
+++ b/ComfyUI/comfy/ldm/omnigen/omnigen2.py
@@ -0,0 +1,466 @@
+# Original code: https://github.com/VectorSpaceLab/OmniGen2
+
+from typing import Optional, Tuple
+
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+from einops import rearrange, repeat
+from comfy.ldm.lightricks.model import Timesteps
+from comfy.ldm.flux.layers import EmbedND
+from comfy.ldm.flux.math import apply_rope1
+from comfy.ldm.modules.attention import optimized_attention_masked
+import comfy.model_management
+import comfy.ldm.common_dit
+
+
+def apply_rotary_emb(x, freqs_cis):
+ if x.shape[1] == 0:
+ return x
+
+ return apply_rope1(x, freqs_cis)
+
+
+def swiglu(x: torch.Tensor, y: torch.Tensor) -> torch.Tensor:
+ return F.silu(x, inplace=True).mul_(y)
+
+
+class TimestepEmbedding(nn.Module):
+ def __init__(self, in_channels: int, time_embed_dim: int, dtype=None, device=None, operations=None):
+ super().__init__()
+ self.linear_1 = operations.Linear(in_channels, time_embed_dim, dtype=dtype, device=device)
+ self.act = nn.SiLU()
+ self.linear_2 = operations.Linear(time_embed_dim, time_embed_dim, dtype=dtype, device=device)
+
+ def forward(self, sample: torch.Tensor) -> torch.Tensor:
+ sample = self.linear_1(sample)
+ sample = self.act(sample)
+ sample = self.linear_2(sample)
+ return sample
+
+
+class LuminaRMSNormZero(nn.Module):
+ def __init__(self, embedding_dim: int, norm_eps: float = 1e-5, dtype=None, device=None, operations=None):
+ super().__init__()
+ self.silu = nn.SiLU()
+ self.linear = operations.Linear(min(embedding_dim, 1024), 4 * embedding_dim, dtype=dtype, device=device)
+ self.norm = operations.RMSNorm(embedding_dim, eps=norm_eps, dtype=dtype, device=device)
+
+ def forward(self, x: torch.Tensor, emb: torch.Tensor) -> Tuple[torch.Tensor, torch.Tensor, torch.Tensor, torch.Tensor]:
+ emb = self.linear(self.silu(emb))
+ scale_msa, gate_msa, scale_mlp, gate_mlp = emb.chunk(4, dim=1)
+ x = self.norm(x) * (1 + scale_msa[:, None])
+ return x, gate_msa, scale_mlp, gate_mlp
+
+
+class LuminaLayerNormContinuous(nn.Module):
+ def __init__(self, embedding_dim: int, conditioning_embedding_dim: int, elementwise_affine: bool = False, eps: float = 1e-6, out_dim: Optional[int] = None, dtype=None, device=None, operations=None):
+ super().__init__()
+ self.silu = nn.SiLU()
+ self.linear_1 = operations.Linear(conditioning_embedding_dim, embedding_dim, dtype=dtype, device=device)
+ self.norm = operations.LayerNorm(embedding_dim, eps, elementwise_affine, dtype=dtype, device=device)
+ self.linear_2 = operations.Linear(embedding_dim, out_dim, bias=True, dtype=dtype, device=device) if out_dim is not None else None
+
+ def forward(self, x: torch.Tensor, conditioning_embedding: torch.Tensor) -> torch.Tensor:
+ emb = self.linear_1(self.silu(conditioning_embedding).to(x.dtype))
+ x = self.norm(x) * (1 + emb)[:, None, :]
+ if self.linear_2 is not None:
+ x = self.linear_2(x)
+ return x
+
+
+class LuminaFeedForward(nn.Module):
+ def __init__(self, dim: int, inner_dim: int, multiple_of: int = 256, dtype=None, device=None, operations=None):
+ super().__init__()
+ inner_dim = multiple_of * ((inner_dim + multiple_of - 1) // multiple_of)
+ self.linear_1 = operations.Linear(dim, inner_dim, bias=False, dtype=dtype, device=device)
+ self.linear_2 = operations.Linear(inner_dim, dim, bias=False, dtype=dtype, device=device)
+ self.linear_3 = operations.Linear(dim, inner_dim, bias=False, dtype=dtype, device=device)
+
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
+ h1, h2 = self.linear_1(x), self.linear_3(x)
+ return self.linear_2(swiglu(h1, h2))
+
+
+class Lumina2CombinedTimestepCaptionEmbedding(nn.Module):
+ def __init__(self, hidden_size: int = 4096, text_feat_dim: int = 2048, frequency_embedding_size: int = 256, norm_eps: float = 1e-5, timestep_scale: float = 1.0, dtype=None, device=None, operations=None):
+ super().__init__()
+ self.time_proj = Timesteps(num_channels=frequency_embedding_size, flip_sin_to_cos=True, downscale_freq_shift=0.0, scale=timestep_scale)
+ self.timestep_embedder = TimestepEmbedding(in_channels=frequency_embedding_size, time_embed_dim=min(hidden_size, 1024), dtype=dtype, device=device, operations=operations)
+ self.caption_embedder = nn.Sequential(
+ operations.RMSNorm(text_feat_dim, eps=norm_eps, dtype=dtype, device=device),
+ operations.Linear(text_feat_dim, hidden_size, bias=True, dtype=dtype, device=device),
+ )
+
+ def forward(self, timestep: torch.Tensor, text_hidden_states: torch.Tensor, dtype: torch.dtype) -> Tuple[torch.Tensor, torch.Tensor]:
+ timestep_proj = self.time_proj(timestep).to(dtype=dtype)
+ time_embed = self.timestep_embedder(timestep_proj)
+ caption_embed = self.caption_embedder(text_hidden_states)
+ return time_embed, caption_embed
+
+
+class Attention(nn.Module):
+ def __init__(self, query_dim: int, dim_head: int, heads: int, kv_heads: int, eps: float = 1e-5, bias: bool = False, dtype=None, device=None, operations=None):
+ super().__init__()
+ self.heads = heads
+ self.kv_heads = kv_heads
+ self.dim_head = dim_head
+ self.scale = dim_head ** -0.5
+
+ self.to_q = operations.Linear(query_dim, heads * dim_head, bias=bias, dtype=dtype, device=device)
+ self.to_k = operations.Linear(query_dim, kv_heads * dim_head, bias=bias, dtype=dtype, device=device)
+ self.to_v = operations.Linear(query_dim, kv_heads * dim_head, bias=bias, dtype=dtype, device=device)
+
+ self.norm_q = operations.RMSNorm(dim_head, eps=eps, dtype=dtype, device=device)
+ self.norm_k = operations.RMSNorm(dim_head, eps=eps, dtype=dtype, device=device)
+
+ self.to_out = nn.Sequential(
+ operations.Linear(heads * dim_head, query_dim, bias=bias, dtype=dtype, device=device),
+ nn.Dropout(0.0)
+ )
+
+ def forward(self, hidden_states: torch.Tensor, encoder_hidden_states: torch.Tensor, attention_mask: Optional[torch.Tensor] = None, image_rotary_emb: Optional[torch.Tensor] = None, transformer_options={}) -> torch.Tensor:
+ batch_size, sequence_length, _ = hidden_states.shape
+
+ query = self.to_q(hidden_states)
+ key = self.to_k(encoder_hidden_states)
+ value = self.to_v(encoder_hidden_states)
+
+ query = query.view(batch_size, -1, self.heads, self.dim_head)
+ key = key.view(batch_size, -1, self.kv_heads, self.dim_head)
+ value = value.view(batch_size, -1, self.kv_heads, self.dim_head)
+
+ query = self.norm_q(query)
+ key = self.norm_k(key)
+
+ if image_rotary_emb is not None:
+ query = apply_rotary_emb(query, image_rotary_emb)
+ key = apply_rotary_emb(key, image_rotary_emb)
+
+ query = query.transpose(1, 2)
+ key = key.transpose(1, 2)
+ value = value.transpose(1, 2)
+
+ gqa_kwargs = {"enable_gqa": True} if self.kv_heads < self.heads else {}
+ hidden_states = optimized_attention_masked(query, key, value, self.heads, attention_mask, skip_reshape=True, transformer_options=transformer_options, **gqa_kwargs)
+ hidden_states = self.to_out[0](hidden_states)
+ return hidden_states
+
+
+class OmniGen2TransformerBlock(nn.Module):
+ def __init__(self, dim: int, num_attention_heads: int, num_kv_heads: int, multiple_of: int, ffn_dim_multiplier: float, norm_eps: float, modulation: bool = True, dtype=None, device=None, operations=None):
+ super().__init__()
+ self.modulation = modulation
+
+ self.attn = Attention(
+ query_dim=dim,
+ dim_head=dim // num_attention_heads,
+ heads=num_attention_heads,
+ kv_heads=num_kv_heads,
+ eps=1e-5,
+ bias=False,
+ dtype=dtype, device=device, operations=operations,
+ )
+
+ self.feed_forward = LuminaFeedForward(
+ dim=dim,
+ inner_dim=4 * dim,
+ multiple_of=multiple_of,
+ dtype=dtype, device=device, operations=operations
+ )
+
+ if modulation:
+ self.norm1 = LuminaRMSNormZero(embedding_dim=dim, norm_eps=norm_eps, dtype=dtype, device=device, operations=operations)
+ else:
+ self.norm1 = operations.RMSNorm(dim, eps=norm_eps, dtype=dtype, device=device)
+
+ self.ffn_norm1 = operations.RMSNorm(dim, eps=norm_eps, dtype=dtype, device=device)
+ self.norm2 = operations.RMSNorm(dim, eps=norm_eps, dtype=dtype, device=device)
+ self.ffn_norm2 = operations.RMSNorm(dim, eps=norm_eps, dtype=dtype, device=device)
+
+ def forward(self, hidden_states: torch.Tensor, attention_mask: torch.Tensor, image_rotary_emb: torch.Tensor, temb: Optional[torch.Tensor] = None, transformer_options={}) -> torch.Tensor:
+ if self.modulation:
+ norm_hidden_states, gate_msa, scale_mlp, gate_mlp = self.norm1(hidden_states, temb)
+ attn_output = self.attn(norm_hidden_states, norm_hidden_states, attention_mask, image_rotary_emb, transformer_options=transformer_options)
+ hidden_states = hidden_states + gate_msa.unsqueeze(1).tanh() * self.norm2(attn_output)
+ mlp_output = self.feed_forward(self.ffn_norm1(hidden_states) * (1 + scale_mlp.unsqueeze(1)))
+ hidden_states = hidden_states + gate_mlp.unsqueeze(1).tanh() * self.ffn_norm2(mlp_output)
+ else:
+ norm_hidden_states = self.norm1(hidden_states)
+ attn_output = self.attn(norm_hidden_states, norm_hidden_states, attention_mask, image_rotary_emb, transformer_options=transformer_options)
+ hidden_states = hidden_states + self.norm2(attn_output)
+ mlp_output = self.feed_forward(self.ffn_norm1(hidden_states))
+ hidden_states = hidden_states + self.ffn_norm2(mlp_output)
+ return hidden_states
+
+
+class OmniGen2RotaryPosEmbed(nn.Module):
+ def __init__(self, theta: int, axes_dim: Tuple[int, int, int], axes_lens: Tuple[int, int, int] = (300, 512, 512), patch_size: int = 2):
+ super().__init__()
+ self.theta = theta
+ self.axes_dim = axes_dim
+ self.axes_lens = axes_lens
+ self.patch_size = patch_size
+ self.rope_embedder = EmbedND(dim=sum(axes_dim), theta=self.theta, axes_dim=axes_dim)
+
+ def forward(self, batch_size, encoder_seq_len, l_effective_cap_len, l_effective_ref_img_len, l_effective_img_len, ref_img_sizes, img_sizes, device):
+ p = self.patch_size
+
+ seq_lengths = [cap_len + sum(ref_img_len) + img_len for cap_len, ref_img_len, img_len in zip(l_effective_cap_len, l_effective_ref_img_len, l_effective_img_len)]
+
+ max_seq_len = max(seq_lengths)
+ max_ref_img_len = max([sum(ref_img_len) for ref_img_len in l_effective_ref_img_len])
+ max_img_len = max(l_effective_img_len)
+
+ position_ids = torch.zeros(batch_size, max_seq_len, 3, dtype=torch.int32, device=device)
+
+ for i, (cap_seq_len, seq_len) in enumerate(zip(l_effective_cap_len, seq_lengths)):
+ position_ids[i, :cap_seq_len] = repeat(torch.arange(cap_seq_len, dtype=torch.int32, device=device), "l -> l 3")
+
+ pe_shift = cap_seq_len
+ pe_shift_len = cap_seq_len
+
+ if ref_img_sizes[i] is not None:
+ for ref_img_size, ref_img_len in zip(ref_img_sizes[i], l_effective_ref_img_len[i]):
+ H, W = ref_img_size
+ ref_H_tokens, ref_W_tokens = H // p, W // p
+
+ row_ids = repeat(torch.arange(ref_H_tokens, dtype=torch.int32, device=device), "h -> h w", w=ref_W_tokens).flatten()
+ col_ids = repeat(torch.arange(ref_W_tokens, dtype=torch.int32, device=device), "w -> h w", h=ref_H_tokens).flatten()
+ position_ids[i, pe_shift_len:pe_shift_len + ref_img_len, 0] = pe_shift
+ position_ids[i, pe_shift_len:pe_shift_len + ref_img_len, 1] = row_ids
+ position_ids[i, pe_shift_len:pe_shift_len + ref_img_len, 2] = col_ids
+
+ pe_shift += max(ref_H_tokens, ref_W_tokens)
+ pe_shift_len += ref_img_len
+
+ H, W = img_sizes[i]
+ H_tokens, W_tokens = H // p, W // p
+
+ row_ids = repeat(torch.arange(H_tokens, dtype=torch.int32, device=device), "h -> h w", w=W_tokens).flatten()
+ col_ids = repeat(torch.arange(W_tokens, dtype=torch.int32, device=device), "w -> h w", h=H_tokens).flatten()
+
+ position_ids[i, pe_shift_len: seq_len, 0] = pe_shift
+ position_ids[i, pe_shift_len: seq_len, 1] = row_ids
+ position_ids[i, pe_shift_len: seq_len, 2] = col_ids
+
+ freqs_cis = self.rope_embedder(position_ids).movedim(1, 2)
+
+ cap_freqs_cis_shape = list(freqs_cis.shape)
+ cap_freqs_cis_shape[1] = encoder_seq_len
+ cap_freqs_cis = torch.zeros(*cap_freqs_cis_shape, device=device, dtype=freqs_cis.dtype)
+
+ ref_img_freqs_cis_shape = list(freqs_cis.shape)
+ ref_img_freqs_cis_shape[1] = max_ref_img_len
+ ref_img_freqs_cis = torch.zeros(*ref_img_freqs_cis_shape, device=device, dtype=freqs_cis.dtype)
+
+ img_freqs_cis_shape = list(freqs_cis.shape)
+ img_freqs_cis_shape[1] = max_img_len
+ img_freqs_cis = torch.zeros(*img_freqs_cis_shape, device=device, dtype=freqs_cis.dtype)
+
+ for i, (cap_seq_len, ref_img_len, img_len, seq_len) in enumerate(zip(l_effective_cap_len, l_effective_ref_img_len, l_effective_img_len, seq_lengths)):
+ cap_freqs_cis[i, :cap_seq_len] = freqs_cis[i, :cap_seq_len]
+ ref_img_freqs_cis[i, :sum(ref_img_len)] = freqs_cis[i, cap_seq_len:cap_seq_len + sum(ref_img_len)]
+ img_freqs_cis[i, :img_len] = freqs_cis[i, cap_seq_len + sum(ref_img_len):cap_seq_len + sum(ref_img_len) + img_len]
+
+ return cap_freqs_cis, ref_img_freqs_cis, img_freqs_cis, freqs_cis, l_effective_cap_len, seq_lengths
+
+
+class OmniGen2Transformer2DModel(nn.Module):
+ def __init__(
+ self,
+ patch_size: int = 2,
+ in_channels: int = 16,
+ out_channels: Optional[int] = None,
+ hidden_size: int = 2304,
+ num_layers: int = 26,
+ num_refiner_layers: int = 2,
+ num_attention_heads: int = 24,
+ num_kv_heads: int = 8,
+ multiple_of: int = 256,
+ ffn_dim_multiplier: Optional[float] = None,
+ norm_eps: float = 1e-5,
+ axes_dim_rope: Tuple[int, int, int] = (32, 32, 32),
+ axes_lens: Tuple[int, int, int] = (300, 512, 512),
+ text_feat_dim: int = 1024,
+ timestep_scale: float = 1.0,
+ image_model=None,
+ device=None,
+ dtype=None,
+ operations=None,
+ ):
+ super().__init__()
+
+ self.patch_size = patch_size
+ self.out_channels = out_channels or in_channels
+ self.hidden_size = hidden_size
+ self.dtype = dtype
+
+ self.rope_embedder = OmniGen2RotaryPosEmbed(
+ theta=10000,
+ axes_dim=axes_dim_rope,
+ axes_lens=axes_lens,
+ patch_size=patch_size,
+ )
+
+ self.x_embedder = operations.Linear(patch_size * patch_size * in_channels, hidden_size, dtype=dtype, device=device)
+ self.ref_image_patch_embedder = operations.Linear(patch_size * patch_size * in_channels, hidden_size, dtype=dtype, device=device)
+
+ self.time_caption_embed = Lumina2CombinedTimestepCaptionEmbedding(
+ hidden_size=hidden_size,
+ text_feat_dim=text_feat_dim,
+ norm_eps=norm_eps,
+ timestep_scale=timestep_scale, dtype=dtype, device=device, operations=operations
+ )
+
+ self.noise_refiner = nn.ModuleList([
+ OmniGen2TransformerBlock(
+ hidden_size, num_attention_heads, num_kv_heads,
+ multiple_of, ffn_dim_multiplier, norm_eps, modulation=True, dtype=dtype, device=device, operations=operations
+ ) for _ in range(num_refiner_layers)
+ ])
+
+ self.ref_image_refiner = nn.ModuleList([
+ OmniGen2TransformerBlock(
+ hidden_size, num_attention_heads, num_kv_heads,
+ multiple_of, ffn_dim_multiplier, norm_eps, modulation=True, dtype=dtype, device=device, operations=operations
+ ) for _ in range(num_refiner_layers)
+ ])
+
+ self.context_refiner = nn.ModuleList([
+ OmniGen2TransformerBlock(
+ hidden_size, num_attention_heads, num_kv_heads,
+ multiple_of, ffn_dim_multiplier, norm_eps, modulation=False, dtype=dtype, device=device, operations=operations
+ ) for _ in range(num_refiner_layers)
+ ])
+
+ self.layers = nn.ModuleList([
+ OmniGen2TransformerBlock(
+ hidden_size, num_attention_heads, num_kv_heads,
+ multiple_of, ffn_dim_multiplier, norm_eps, modulation=True, dtype=dtype, device=device, operations=operations
+ ) for _ in range(num_layers)
+ ])
+
+ self.norm_out = LuminaLayerNormContinuous(
+ embedding_dim=hidden_size,
+ conditioning_embedding_dim=min(hidden_size, 1024),
+ elementwise_affine=False,
+ eps=1e-6,
+ out_dim=patch_size * patch_size * self.out_channels, dtype=dtype, device=device, operations=operations
+ )
+
+ self.image_index_embedding = nn.Parameter(torch.empty(5, hidden_size, device=device, dtype=dtype))
+
+ def flat_and_pad_to_seq(self, hidden_states, ref_image_hidden_states):
+ batch_size = len(hidden_states)
+ p = self.patch_size
+
+ img_sizes = [(img.size(1), img.size(2)) for img in hidden_states]
+ l_effective_img_len = [(H // p) * (W // p) for (H, W) in img_sizes]
+
+ if ref_image_hidden_states is not None:
+ ref_image_hidden_states = list(map(lambda ref: comfy.ldm.common_dit.pad_to_patch_size(ref, (p, p)), ref_image_hidden_states))
+ ref_img_sizes = [[(imgs.size(2), imgs.size(3)) if imgs is not None else None for imgs in ref_image_hidden_states]] * batch_size
+ l_effective_ref_img_len = [[(ref_img_size[0] // p) * (ref_img_size[1] // p) for ref_img_size in _ref_img_sizes] if _ref_img_sizes is not None else [0] for _ref_img_sizes in ref_img_sizes]
+ else:
+ ref_img_sizes = [None for _ in range(batch_size)]
+ l_effective_ref_img_len = [[0] for _ in range(batch_size)]
+
+ flat_ref_img_hidden_states = None
+ if ref_image_hidden_states is not None:
+ imgs = []
+ for ref_img in ref_image_hidden_states:
+ B, C, H, W = ref_img.size()
+ ref_img = rearrange(ref_img, 'b c (h p1) (w p2) -> b (h w) (p1 p2 c)', p1=p, p2=p)
+ imgs.append(ref_img)
+ flat_ref_img_hidden_states = torch.cat(imgs, dim=1)
+
+ img = hidden_states
+ B, C, H, W = img.size()
+ flat_hidden_states = rearrange(img, 'b c (h p1) (w p2) -> b (h w) (p1 p2 c)', p1=p, p2=p)
+
+ return (
+ flat_hidden_states, flat_ref_img_hidden_states,
+ None, None,
+ l_effective_ref_img_len, l_effective_img_len,
+ ref_img_sizes, img_sizes,
+ )
+
+ def img_patch_embed_and_refine(self, hidden_states, ref_image_hidden_states, padded_img_mask, padded_ref_img_mask, noise_rotary_emb, ref_img_rotary_emb, l_effective_ref_img_len, l_effective_img_len, temb, transformer_options={}):
+ batch_size = len(hidden_states)
+
+ hidden_states = self.x_embedder(hidden_states)
+ if ref_image_hidden_states is not None:
+ ref_image_hidden_states = self.ref_image_patch_embedder(ref_image_hidden_states)
+ image_index_embedding = comfy.model_management.cast_to(self.image_index_embedding, dtype=hidden_states.dtype, device=hidden_states.device)
+
+ for i in range(batch_size):
+ shift = 0
+ for j, ref_img_len in enumerate(l_effective_ref_img_len[i]):
+ ref_image_hidden_states[i, shift:shift + ref_img_len, :] = ref_image_hidden_states[i, shift:shift + ref_img_len, :] + image_index_embedding[j]
+ shift += ref_img_len
+
+ for layer in self.noise_refiner:
+ hidden_states = layer(hidden_states, padded_img_mask, noise_rotary_emb, temb, transformer_options=transformer_options)
+
+ if ref_image_hidden_states is not None:
+ for layer in self.ref_image_refiner:
+ ref_image_hidden_states = layer(ref_image_hidden_states, padded_ref_img_mask, ref_img_rotary_emb, temb, transformer_options=transformer_options)
+
+ hidden_states = torch.cat([ref_image_hidden_states, hidden_states], dim=1)
+
+ return hidden_states
+
+ def forward(self, x, timesteps, context, num_tokens, ref_latents=None, attention_mask=None, transformer_options={}, **kwargs):
+ B, C, H, W = x.shape
+ hidden_states = comfy.ldm.common_dit.pad_to_patch_size(x, (self.patch_size, self.patch_size))
+ _, _, H_padded, W_padded = hidden_states.shape
+ timestep = 1.0 - timesteps
+ text_hidden_states = context
+ text_attention_mask = attention_mask
+ ref_image_hidden_states = ref_latents
+ device = hidden_states.device
+
+ temb, text_hidden_states = self.time_caption_embed(timestep, text_hidden_states, hidden_states[0].dtype)
+
+ (
+ hidden_states, ref_image_hidden_states,
+ img_mask, ref_img_mask,
+ l_effective_ref_img_len, l_effective_img_len,
+ ref_img_sizes, img_sizes,
+ ) = self.flat_and_pad_to_seq(hidden_states, ref_image_hidden_states)
+
+ (
+ context_rotary_emb, ref_img_rotary_emb, noise_rotary_emb,
+ rotary_emb, encoder_seq_lengths, seq_lengths,
+ ) = self.rope_embedder(
+ hidden_states.shape[0], text_hidden_states.shape[1], [num_tokens] * text_hidden_states.shape[0],
+ l_effective_ref_img_len, l_effective_img_len,
+ ref_img_sizes, img_sizes, device,
+ )
+
+ for layer in self.context_refiner:
+ text_hidden_states = layer(text_hidden_states, text_attention_mask, context_rotary_emb, transformer_options=transformer_options)
+
+ img_len = hidden_states.shape[1]
+ combined_img_hidden_states = self.img_patch_embed_and_refine(
+ hidden_states, ref_image_hidden_states,
+ img_mask, ref_img_mask,
+ noise_rotary_emb, ref_img_rotary_emb,
+ l_effective_ref_img_len, l_effective_img_len,
+ temb,
+ transformer_options=transformer_options,
+ )
+
+ hidden_states = torch.cat([text_hidden_states, combined_img_hidden_states], dim=1)
+ attention_mask = None
+
+ for layer in self.layers:
+ hidden_states = layer(hidden_states, attention_mask, rotary_emb, temb, transformer_options=transformer_options)
+
+ hidden_states = self.norm_out(hidden_states, temb)
+
+ p = self.patch_size
+ output = rearrange(hidden_states[:, -img_len:], 'b (h w) (p1 p2 c) -> b c (h p1) (w p2)', h=H_padded // p, w=W_padded// p, p1=p, p2=p)[:, :, :H, :W]
+
+ return -output
diff --git a/ComfyUI/comfy/ldm/pixart/__pycache__/blocks.cpython-312.pyc b/ComfyUI/comfy/ldm/pixart/__pycache__/blocks.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..b113329ba35c0815b367714d3252b1f12677c5d7
Binary files /dev/null and b/ComfyUI/comfy/ldm/pixart/__pycache__/blocks.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/pixart/__pycache__/pixartms.cpython-312.pyc b/ComfyUI/comfy/ldm/pixart/__pycache__/pixartms.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..fad44e1e0c1cc35b962d1f2c90d70eccf3597aae
Binary files /dev/null and b/ComfyUI/comfy/ldm/pixart/__pycache__/pixartms.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/pixart/blocks.py b/ComfyUI/comfy/ldm/pixart/blocks.py
new file mode 100644
index 0000000000000000000000000000000000000000..2225076e5754d08cd618014469c2464bad055334
--- /dev/null
+++ b/ComfyUI/comfy/ldm/pixart/blocks.py
@@ -0,0 +1,380 @@
+# Based on:
+# https://github.com/PixArt-alpha/PixArt-alpha [Apache 2.0 license]
+# https://github.com/PixArt-alpha/PixArt-sigma [Apache 2.0 license]
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+from einops import rearrange
+
+from comfy.ldm.modules.diffusionmodules.mmdit import TimestepEmbedder, Mlp, timestep_embedding
+from comfy.ldm.modules.attention import optimized_attention
+
+# if model_management.xformers_enabled():
+# import xformers.ops
+# if int((xformers.__version__).split(".")[2].split("+")[0]) >= 28:
+# block_diagonal_mask_from_seqlens = xformers.ops.fmha.attn_bias.BlockDiagonalMask.from_seqlens
+# else:
+# block_diagonal_mask_from_seqlens = xformers.ops.fmha.BlockDiagonalMask.from_seqlens
+
+def modulate(x, shift, scale):
+ return x * (1 + scale.unsqueeze(1)) + shift.unsqueeze(1)
+
+def t2i_modulate(x, shift, scale):
+ return x * (1 + scale) + shift
+
+class MultiHeadCrossAttention(nn.Module):
+ def __init__(self, d_model, num_heads, attn_drop=0., proj_drop=0., dtype=None, device=None, operations=None, **kwargs):
+ super(MultiHeadCrossAttention, self).__init__()
+ assert d_model % num_heads == 0, "d_model must be divisible by num_heads"
+
+ self.d_model = d_model
+ self.num_heads = num_heads
+ self.head_dim = d_model // num_heads
+
+ self.q_linear = operations.Linear(d_model, d_model, dtype=dtype, device=device)
+ self.kv_linear = operations.Linear(d_model, d_model*2, dtype=dtype, device=device)
+ self.attn_drop = nn.Dropout(attn_drop)
+ self.proj = operations.Linear(d_model, d_model, dtype=dtype, device=device)
+ self.proj_drop = nn.Dropout(proj_drop)
+
+ def forward(self, x, cond, mask=None):
+ # query/value: img tokens; key: condition; mask: if padding tokens
+ B, N, C = x.shape
+
+ q = self.q_linear(x).view(1, -1, self.num_heads, self.head_dim)
+ kv = self.kv_linear(cond).view(1, -1, 2, self.num_heads, self.head_dim)
+ k, v = kv.unbind(2)
+
+ assert mask is None # TODO?
+ # # TODO: xformers needs separate mask logic here
+ # if model_management.xformers_enabled():
+ # attn_bias = None
+ # if mask is not None:
+ # attn_bias = block_diagonal_mask_from_seqlens([N] * B, mask)
+ # x = xformers.ops.memory_efficient_attention(q, k, v, p=0, attn_bias=attn_bias)
+ # else:
+ # q, k, v = map(lambda t: t.transpose(1, 2), (q, k, v),)
+ # attn_mask = None
+ # mask = torch.ones(())
+ # if mask is not None and len(mask) > 1:
+ # # Create equivalent of xformer diagonal block mask, still only correct for square masks
+ # # But depth doesn't matter as tensors can expand in that dimension
+ # attn_mask_template = torch.ones(
+ # [q.shape[2] // B, mask[0]],
+ # dtype=torch.bool,
+ # device=q.device
+ # )
+ # attn_mask = torch.block_diag(attn_mask_template)
+ #
+ # # create a mask on the diagonal for each mask in the batch
+ # for _ in range(B - 1):
+ # attn_mask = torch.block_diag(attn_mask, attn_mask_template)
+ # x = optimized_attention(q, k, v, self.num_heads, mask=attn_mask, skip_reshape=True)
+
+ x = optimized_attention(q.view(B, -1, C), k.view(B, -1, C), v.view(B, -1, C), self.num_heads, mask=None)
+ x = self.proj(x)
+ x = self.proj_drop(x)
+ return x
+
+
+class AttentionKVCompress(nn.Module):
+ """Multi-head Attention block with KV token compression and qk norm."""
+ def __init__(self, dim, num_heads=8, qkv_bias=True, sampling='conv', sr_ratio=1, qk_norm=False, dtype=None, device=None, operations=None, **kwargs):
+ """
+ Args:
+ dim (int): Number of input channels.
+ num_heads (int): Number of attention heads.
+ qkv_bias (bool: If True, add a learnable bias to query, key, value.
+ """
+ super().__init__()
+ assert dim % num_heads == 0, 'dim should be divisible by num_heads'
+ self.num_heads = num_heads
+ self.head_dim = dim // num_heads
+ self.scale = self.head_dim ** -0.5
+
+ self.qkv = operations.Linear(dim, dim * 3, bias=qkv_bias, dtype=dtype, device=device)
+ self.proj = operations.Linear(dim, dim, dtype=dtype, device=device)
+
+ self.sampling=sampling # ['conv', 'ave', 'uniform', 'uniform_every']
+ self.sr_ratio = sr_ratio
+ if sr_ratio > 1 and sampling == 'conv':
+ # Avg Conv Init.
+ self.sr = operations.Conv2d(dim, dim, groups=dim, kernel_size=sr_ratio, stride=sr_ratio, dtype=dtype, device=device)
+ # self.sr.weight.data.fill_(1/sr_ratio**2)
+ # self.sr.bias.data.zero_()
+ self.norm = operations.LayerNorm(dim, dtype=dtype, device=device)
+ if qk_norm:
+ self.q_norm = operations.LayerNorm(dim, dtype=dtype, device=device)
+ self.k_norm = operations.LayerNorm(dim, dtype=dtype, device=device)
+ else:
+ self.q_norm = nn.Identity()
+ self.k_norm = nn.Identity()
+
+ def downsample_2d(self, tensor, H, W, scale_factor, sampling=None):
+ if sampling is None or scale_factor == 1:
+ return tensor
+ B, N, C = tensor.shape
+
+ if sampling == 'uniform_every':
+ return tensor[:, ::scale_factor], int(N // scale_factor)
+
+ tensor = tensor.reshape(B, H, W, C).permute(0, 3, 1, 2)
+ new_H, new_W = int(H / scale_factor), int(W / scale_factor)
+ new_N = new_H * new_W
+
+ if sampling == 'ave':
+ tensor = F.interpolate(
+ tensor, scale_factor=1 / scale_factor, mode='nearest'
+ ).permute(0, 2, 3, 1)
+ elif sampling == 'uniform':
+ tensor = tensor[:, :, ::scale_factor, ::scale_factor].permute(0, 2, 3, 1)
+ elif sampling == 'conv':
+ tensor = self.sr(tensor).reshape(B, C, -1).permute(0, 2, 1)
+ tensor = self.norm(tensor)
+ else:
+ raise ValueError
+
+ return tensor.reshape(B, new_N, C).contiguous(), new_N
+
+ def forward(self, x, mask=None, HW=None, block_id=None):
+ B, N, C = x.shape # 2 4096 1152
+ new_N = N
+ if HW is None:
+ H = W = int(N ** 0.5)
+ else:
+ H, W = HW
+ qkv = self.qkv(x).reshape(B, N, 3, C)
+
+ q, k, v = qkv.unbind(2)
+ q = self.q_norm(q)
+ k = self.k_norm(k)
+
+ # KV compression
+ if self.sr_ratio > 1:
+ k, new_N = self.downsample_2d(k, H, W, self.sr_ratio, sampling=self.sampling)
+ v, new_N = self.downsample_2d(v, H, W, self.sr_ratio, sampling=self.sampling)
+
+ q = q.reshape(B, N, self.num_heads, C // self.num_heads)
+ k = k.reshape(B, new_N, self.num_heads, C // self.num_heads)
+ v = v.reshape(B, new_N, self.num_heads, C // self.num_heads)
+
+ if mask is not None:
+ raise NotImplementedError("Attn mask logic not added for self attention")
+
+ # This is never called at the moment
+ # attn_bias = None
+ # if mask is not None:
+ # attn_bias = torch.zeros([B * self.num_heads, q.shape[1], k.shape[1]], dtype=q.dtype, device=q.device)
+ # attn_bias.masked_fill_(mask.squeeze(1).repeat(self.num_heads, 1, 1) == 0, float('-inf'))
+
+ # attention 2
+ q, k, v = map(lambda t: t.transpose(1, 2), (q, k, v),)
+ x = optimized_attention(q, k, v, self.num_heads, mask=None, skip_reshape=True)
+
+ x = x.view(B, N, C)
+ x = self.proj(x)
+ return x
+
+
+class FinalLayer(nn.Module):
+ """
+ The final layer of PixArt.
+ """
+ def __init__(self, hidden_size, patch_size, out_channels, dtype=None, device=None, operations=None):
+ super().__init__()
+ self.norm_final = operations.LayerNorm(hidden_size, elementwise_affine=False, eps=1e-6, dtype=dtype, device=device)
+ self.linear = operations.Linear(hidden_size, patch_size * patch_size * out_channels, bias=True, dtype=dtype, device=device)
+ self.adaLN_modulation = nn.Sequential(
+ nn.SiLU(),
+ operations.Linear(hidden_size, 2 * hidden_size, bias=True, dtype=dtype, device=device)
+ )
+
+ def forward(self, x, c):
+ shift, scale = self.adaLN_modulation(c).chunk(2, dim=1)
+ x = modulate(self.norm_final(x), shift, scale)
+ x = self.linear(x)
+ return x
+
+class T2IFinalLayer(nn.Module):
+ """
+ The final layer of PixArt.
+ """
+ def __init__(self, hidden_size, patch_size, out_channels, dtype=None, device=None, operations=None):
+ super().__init__()
+ self.norm_final = operations.LayerNorm(hidden_size, elementwise_affine=False, eps=1e-6, dtype=dtype, device=device)
+ self.linear = operations.Linear(hidden_size, patch_size * patch_size * out_channels, bias=True, dtype=dtype, device=device)
+ self.scale_shift_table = nn.Parameter(torch.randn(2, hidden_size) / hidden_size ** 0.5)
+ self.out_channels = out_channels
+
+ def forward(self, x, t):
+ shift, scale = (self.scale_shift_table[None].to(dtype=x.dtype, device=x.device) + t[:, None]).chunk(2, dim=1)
+ x = t2i_modulate(self.norm_final(x), shift, scale)
+ x = self.linear(x)
+ return x
+
+
+class MaskFinalLayer(nn.Module):
+ """
+ The final layer of PixArt.
+ """
+ def __init__(self, final_hidden_size, c_emb_size, patch_size, out_channels, dtype=None, device=None, operations=None):
+ super().__init__()
+ self.norm_final = operations.LayerNorm(final_hidden_size, elementwise_affine=False, eps=1e-6, dtype=dtype, device=device)
+ self.linear = operations.Linear(final_hidden_size, patch_size * patch_size * out_channels, bias=True, dtype=dtype, device=device)
+ self.adaLN_modulation = nn.Sequential(
+ nn.SiLU(),
+ operations.Linear(c_emb_size, 2 * final_hidden_size, bias=True, dtype=dtype, device=device)
+ )
+ def forward(self, x, t):
+ shift, scale = self.adaLN_modulation(t).chunk(2, dim=1)
+ x = modulate(self.norm_final(x), shift, scale)
+ x = self.linear(x)
+ return x
+
+
+class DecoderLayer(nn.Module):
+ """
+ The final layer of PixArt.
+ """
+ def __init__(self, hidden_size, decoder_hidden_size, dtype=None, device=None, operations=None):
+ super().__init__()
+ self.norm_decoder = operations.LayerNorm(hidden_size, elementwise_affine=False, eps=1e-6, dtype=dtype, device=device)
+ self.linear = operations.Linear(hidden_size, decoder_hidden_size, bias=True, dtype=dtype, device=device)
+ self.adaLN_modulation = nn.Sequential(
+ nn.SiLU(),
+ operations.Linear(hidden_size, 2 * hidden_size, bias=True, dtype=dtype, device=device)
+ )
+ def forward(self, x, t):
+ shift, scale = self.adaLN_modulation(t).chunk(2, dim=1)
+ x = modulate(self.norm_decoder(x), shift, scale)
+ x = self.linear(x)
+ return x
+
+
+class SizeEmbedder(TimestepEmbedder):
+ """
+ Embeds scalar timesteps into vector representations.
+ """
+ def __init__(self, hidden_size, frequency_embedding_size=256, dtype=None, device=None, operations=None):
+ super().__init__(hidden_size=hidden_size, frequency_embedding_size=frequency_embedding_size, operations=operations)
+ self.mlp = nn.Sequential(
+ operations.Linear(frequency_embedding_size, hidden_size, bias=True, dtype=dtype, device=device),
+ nn.SiLU(),
+ operations.Linear(hidden_size, hidden_size, bias=True, dtype=dtype, device=device),
+ )
+ self.frequency_embedding_size = frequency_embedding_size
+ self.outdim = hidden_size
+
+ def forward(self, s, bs):
+ if s.ndim == 1:
+ s = s[:, None]
+ assert s.ndim == 2
+ if s.shape[0] != bs:
+ s = s.repeat(bs//s.shape[0], 1)
+ assert s.shape[0] == bs
+ b, dims = s.shape[0], s.shape[1]
+ s = rearrange(s, "b d -> (b d)")
+ s_freq = timestep_embedding(s, self.frequency_embedding_size)
+ s_emb = self.mlp(s_freq.to(s.dtype))
+ s_emb = rearrange(s_emb, "(b d) d2 -> b (d d2)", b=b, d=dims, d2=self.outdim)
+ return s_emb
+
+
+class LabelEmbedder(nn.Module):
+ """
+ Embeds class labels into vector representations. Also handles label dropout for classifier-free guidance.
+ """
+ def __init__(self, num_classes, hidden_size, dropout_prob, dtype=None, device=None, operations=None):
+ super().__init__()
+ use_cfg_embedding = dropout_prob > 0
+ self.embedding_table = operations.Embedding(num_classes + use_cfg_embedding, hidden_size, dtype=dtype, device=device),
+ self.num_classes = num_classes
+ self.dropout_prob = dropout_prob
+
+ def token_drop(self, labels, force_drop_ids=None):
+ """
+ Drops labels to enable classifier-free guidance.
+ """
+ if force_drop_ids is None:
+ drop_ids = torch.rand(labels.shape[0]).cuda() < self.dropout_prob
+ else:
+ drop_ids = force_drop_ids == 1
+ labels = torch.where(drop_ids, self.num_classes, labels)
+ return labels
+
+ def forward(self, labels, train, force_drop_ids=None):
+ use_dropout = self.dropout_prob > 0
+ if (train and use_dropout) or (force_drop_ids is not None):
+ labels = self.token_drop(labels, force_drop_ids)
+ embeddings = self.embedding_table(labels)
+ return embeddings
+
+
+class CaptionEmbedder(nn.Module):
+ """
+ Embeds class labels into vector representations. Also handles label dropout for classifier-free guidance.
+ """
+ def __init__(self, in_channels, hidden_size, uncond_prob, act_layer=nn.GELU(approximate='tanh'), token_num=120, dtype=None, device=None, operations=None):
+ super().__init__()
+ self.y_proj = Mlp(
+ in_features=in_channels, hidden_features=hidden_size, out_features=hidden_size, act_layer=act_layer,
+ dtype=dtype, device=device, operations=operations,
+ )
+ self.register_buffer("y_embedding", nn.Parameter(torch.randn(token_num, in_channels) / in_channels ** 0.5))
+ self.uncond_prob = uncond_prob
+
+ def token_drop(self, caption, force_drop_ids=None):
+ """
+ Drops labels to enable classifier-free guidance.
+ """
+ if force_drop_ids is None:
+ drop_ids = torch.rand(caption.shape[0]).cuda() < self.uncond_prob
+ else:
+ drop_ids = force_drop_ids == 1
+ caption = torch.where(drop_ids[:, None, None, None], self.y_embedding, caption)
+ return caption
+
+ def forward(self, caption, train, force_drop_ids=None):
+ if train:
+ assert caption.shape[2:] == self.y_embedding.shape
+ use_dropout = self.uncond_prob > 0
+ if (train and use_dropout) or (force_drop_ids is not None):
+ caption = self.token_drop(caption, force_drop_ids)
+ caption = self.y_proj(caption)
+ return caption
+
+
+class CaptionEmbedderDoubleBr(nn.Module):
+ """
+ Embeds class labels into vector representations. Also handles label dropout for classifier-free guidance.
+ """
+ def __init__(self, in_channels, hidden_size, uncond_prob, act_layer=nn.GELU(approximate='tanh'), token_num=120, dtype=None, device=None, operations=None):
+ super().__init__()
+ self.proj = Mlp(
+ in_features=in_channels, hidden_features=hidden_size, out_features=hidden_size, act_layer=act_layer,
+ dtype=dtype, device=device, operations=operations,
+ )
+ self.embedding = nn.Parameter(torch.randn(1, in_channels) / 10 ** 0.5)
+ self.y_embedding = nn.Parameter(torch.randn(token_num, in_channels) / 10 ** 0.5)
+ self.uncond_prob = uncond_prob
+
+ def token_drop(self, global_caption, caption, force_drop_ids=None):
+ """
+ Drops labels to enable classifier-free guidance.
+ """
+ if force_drop_ids is None:
+ drop_ids = torch.rand(global_caption.shape[0]).cuda() < self.uncond_prob
+ else:
+ drop_ids = force_drop_ids == 1
+ global_caption = torch.where(drop_ids[:, None], self.embedding, global_caption)
+ caption = torch.where(drop_ids[:, None, None, None], self.y_embedding, caption)
+ return global_caption, caption
+
+ def forward(self, caption, train, force_drop_ids=None):
+ assert caption.shape[2: ] == self.y_embedding.shape
+ global_caption = caption.mean(dim=2).squeeze()
+ use_dropout = self.uncond_prob > 0
+ if (train and use_dropout) or (force_drop_ids is not None):
+ global_caption, caption = self.token_drop(global_caption, caption, force_drop_ids)
+ y_embed = self.proj(global_caption)
+ return y_embed, caption
diff --git a/ComfyUI/comfy/ldm/pixart/pixartms.py b/ComfyUI/comfy/ldm/pixart/pixartms.py
new file mode 100644
index 0000000000000000000000000000000000000000..d1ac49d84c554f1531427dea251dd6d2ea3e0dc7
--- /dev/null
+++ b/ComfyUI/comfy/ldm/pixart/pixartms.py
@@ -0,0 +1,256 @@
+# Based on:
+# https://github.com/PixArt-alpha/PixArt-alpha [Apache 2.0 license]
+# https://github.com/PixArt-alpha/PixArt-sigma [Apache 2.0 license]
+import torch
+import torch.nn as nn
+
+from .blocks import (
+ t2i_modulate,
+ CaptionEmbedder,
+ AttentionKVCompress,
+ MultiHeadCrossAttention,
+ T2IFinalLayer,
+ SizeEmbedder,
+)
+from comfy.ldm.modules.diffusionmodules.mmdit import TimestepEmbedder, PatchEmbed, Mlp, get_1d_sincos_pos_embed_from_grid_torch
+
+
+def get_2d_sincos_pos_embed_torch(embed_dim, w, h, pe_interpolation=1.0, base_size=16, device=None, dtype=torch.float32):
+ grid_h, grid_w = torch.meshgrid(
+ torch.arange(h, device=device, dtype=dtype) / (h/base_size) / pe_interpolation,
+ torch.arange(w, device=device, dtype=dtype) / (w/base_size) / pe_interpolation,
+ indexing='ij'
+ )
+ emb_h = get_1d_sincos_pos_embed_from_grid_torch(embed_dim // 2, grid_h, device=device, dtype=dtype)
+ emb_w = get_1d_sincos_pos_embed_from_grid_torch(embed_dim // 2, grid_w, device=device, dtype=dtype)
+ emb = torch.cat([emb_w, emb_h], dim=1) # (H*W, D)
+ return emb
+
+class PixArtMSBlock(nn.Module):
+ """
+ A PixArt block with adaptive layer norm zero (adaLN-Zero) conditioning.
+ """
+ def __init__(self, hidden_size, num_heads, mlp_ratio=4.0, drop_path=0., input_size=None,
+ sampling=None, sr_ratio=1, qk_norm=False, dtype=None, device=None, operations=None, **block_kwargs):
+ super().__init__()
+ self.hidden_size = hidden_size
+ self.norm1 = operations.LayerNorm(hidden_size, elementwise_affine=False, eps=1e-6, dtype=dtype, device=device)
+ self.attn = AttentionKVCompress(
+ hidden_size, num_heads=num_heads, qkv_bias=True, sampling=sampling, sr_ratio=sr_ratio,
+ qk_norm=qk_norm, dtype=dtype, device=device, operations=operations, **block_kwargs
+ )
+ self.cross_attn = MultiHeadCrossAttention(
+ hidden_size, num_heads, dtype=dtype, device=device, operations=operations, **block_kwargs
+ )
+ self.norm2 = operations.LayerNorm(hidden_size, elementwise_affine=False, eps=1e-6, dtype=dtype, device=device)
+ # to be compatible with lower version pytorch
+ approx_gelu = lambda: nn.GELU(approximate="tanh")
+ self.mlp = Mlp(
+ in_features=hidden_size, hidden_features=int(hidden_size * mlp_ratio), act_layer=approx_gelu,
+ dtype=dtype, device=device, operations=operations
+ )
+ self.scale_shift_table = nn.Parameter(torch.randn(6, hidden_size) / hidden_size ** 0.5)
+
+ def forward(self, x, y, t, mask=None, HW=None, **kwargs):
+ B, N, C = x.shape
+
+ shift_msa, scale_msa, gate_msa, shift_mlp, scale_mlp, gate_mlp = (self.scale_shift_table[None].to(dtype=x.dtype, device=x.device) + t.reshape(B, 6, -1)).chunk(6, dim=1)
+ x = x + (gate_msa * self.attn(t2i_modulate(self.norm1(x), shift_msa, scale_msa), HW=HW))
+ x = x + self.cross_attn(x, y, mask)
+ x = x + (gate_mlp * self.mlp(t2i_modulate(self.norm2(x), shift_mlp, scale_mlp)))
+
+ return x
+
+
+### Core PixArt Model ###
+class PixArtMS(nn.Module):
+ """
+ Diffusion model with a Transformer backbone.
+ """
+ def __init__(
+ self,
+ input_size=32,
+ patch_size=2,
+ in_channels=4,
+ hidden_size=1152,
+ depth=28,
+ num_heads=16,
+ mlp_ratio=4.0,
+ class_dropout_prob=0.1,
+ learn_sigma=True,
+ pred_sigma=True,
+ drop_path: float = 0.,
+ caption_channels=4096,
+ pe_interpolation=None,
+ pe_precision=None,
+ config=None,
+ model_max_length=120,
+ micro_condition=True,
+ qk_norm=False,
+ kv_compress_config=None,
+ dtype=None,
+ device=None,
+ operations=None,
+ **kwargs,
+ ):
+ nn.Module.__init__(self)
+ self.dtype = dtype
+ self.pred_sigma = pred_sigma
+ self.in_channels = in_channels
+ self.out_channels = in_channels * 2 if pred_sigma else in_channels
+ self.patch_size = patch_size
+ self.num_heads = num_heads
+ self.pe_interpolation = pe_interpolation
+ self.pe_precision = pe_precision
+ self.hidden_size = hidden_size
+ self.depth = depth
+
+ approx_gelu = lambda: nn.GELU(approximate="tanh")
+ self.t_block = nn.Sequential(
+ nn.SiLU(),
+ operations.Linear(hidden_size, 6 * hidden_size, bias=True, dtype=dtype, device=device)
+ )
+ self.x_embedder = PatchEmbed(
+ patch_size=patch_size,
+ in_chans=in_channels,
+ embed_dim=hidden_size,
+ bias=True,
+ dtype=dtype,
+ device=device,
+ operations=operations
+ )
+ self.t_embedder = TimestepEmbedder(
+ hidden_size, dtype=dtype, device=device, operations=operations,
+ )
+ self.y_embedder = CaptionEmbedder(
+ in_channels=caption_channels, hidden_size=hidden_size, uncond_prob=class_dropout_prob,
+ act_layer=approx_gelu, token_num=model_max_length,
+ dtype=dtype, device=device, operations=operations,
+ )
+
+ self.micro_conditioning = micro_condition
+ if self.micro_conditioning:
+ self.csize_embedder = SizeEmbedder(hidden_size//3, dtype=dtype, device=device, operations=operations)
+ self.ar_embedder = SizeEmbedder(hidden_size//3, dtype=dtype, device=device, operations=operations)
+
+ # For fixed sin-cos embedding:
+ # num_patches = (input_size // patch_size) * (input_size // patch_size)
+ # self.base_size = input_size // self.patch_size
+ # self.register_buffer("pos_embed", torch.zeros(1, num_patches, hidden_size))
+
+ drop_path = [x.item() for x in torch.linspace(0, drop_path, depth)] # stochastic depth decay rule
+ if kv_compress_config is None:
+ kv_compress_config = {
+ 'sampling': None,
+ 'scale_factor': 1,
+ 'kv_compress_layer': [],
+ }
+ self.blocks = nn.ModuleList([
+ PixArtMSBlock(
+ hidden_size, num_heads, mlp_ratio=mlp_ratio, drop_path=drop_path[i],
+ sampling=kv_compress_config['sampling'],
+ sr_ratio=int(kv_compress_config['scale_factor']) if i in kv_compress_config['kv_compress_layer'] else 1,
+ qk_norm=qk_norm,
+ dtype=dtype,
+ device=device,
+ operations=operations,
+ )
+ for i in range(depth)
+ ])
+ self.final_layer = T2IFinalLayer(
+ hidden_size, patch_size, self.out_channels, dtype=dtype, device=device, operations=operations
+ )
+
+ def forward_orig(self, x, timestep, y, mask=None, c_size=None, c_ar=None, **kwargs):
+ """
+ Original forward pass of PixArt.
+ x: (N, C, H, W) tensor of spatial inputs (images or latent representations of images)
+ t: (N,) tensor of diffusion timesteps
+ y: (N, 1, 120, C) conditioning
+ ar: (N, 1): aspect ratio
+ cs: (N ,2) size conditioning for height/width
+ """
+ B, C, H, W = x.shape
+ c_res = (H + W) // 2
+ pe_interpolation = self.pe_interpolation
+ if pe_interpolation is None or self.pe_precision is not None:
+ # calculate pe_interpolation on-the-fly
+ pe_interpolation = round(c_res / (512/8.0), self.pe_precision or 0)
+
+ pos_embed = get_2d_sincos_pos_embed_torch(
+ self.hidden_size,
+ h=(H // self.patch_size),
+ w=(W // self.patch_size),
+ pe_interpolation=pe_interpolation,
+ base_size=((round(c_res / 64) * 64) // self.patch_size),
+ device=x.device,
+ dtype=x.dtype,
+ ).unsqueeze(0)
+
+ x = self.x_embedder(x) + pos_embed # (N, T, D), where T = H * W / patch_size ** 2
+ t = self.t_embedder(timestep, x.dtype) # (N, D)
+
+ if self.micro_conditioning and (c_size is not None and c_ar is not None):
+ bs = x.shape[0]
+ c_size = self.csize_embedder(c_size, bs) # (N, D)
+ c_ar = self.ar_embedder(c_ar, bs) # (N, D)
+ t = t + torch.cat([c_size, c_ar], dim=1)
+
+ t0 = self.t_block(t)
+ y = self.y_embedder(y, self.training) # (N, D)
+
+ if mask is not None:
+ if mask.shape[0] != y.shape[0]:
+ mask = mask.repeat(y.shape[0] // mask.shape[0], 1)
+ mask = mask.squeeze(1).squeeze(1)
+ y = y.squeeze(1).masked_select(mask.unsqueeze(-1) != 0).view(1, -1, x.shape[-1])
+ y_lens = mask.sum(dim=1).tolist()
+ else:
+ y_lens = None
+ y = y.squeeze(1).view(1, -1, x.shape[-1])
+ for block in self.blocks:
+ x = block(x, y, t0, y_lens, (H, W), **kwargs) # (N, T, D)
+
+ x = self.final_layer(x, t) # (N, T, patch_size ** 2 * out_channels)
+ x = self.unpatchify(x, H, W) # (N, out_channels, H, W)
+
+ return x
+
+ def forward(self, x, timesteps, context, c_size=None, c_ar=None, **kwargs):
+ B, C, H, W = x.shape
+
+ # Fallback for missing microconds
+ if self.micro_conditioning:
+ if c_size is None:
+ c_size = torch.tensor([H*8, W*8], dtype=x.dtype, device=x.device).repeat(B, 1)
+
+ if c_ar is None:
+ c_ar = torch.tensor([H/W], dtype=x.dtype, device=x.device).repeat(B, 1)
+
+ ## Still accepts the input w/o that dim but returns garbage
+ if len(context.shape) == 3:
+ context = context.unsqueeze(1)
+
+ ## run original forward pass
+ out = self.forward_orig(x, timesteps, context, c_size=c_size, c_ar=c_ar)
+
+ ## only return EPS
+ if self.pred_sigma:
+ return out[:, :self.in_channels]
+ return out
+
+ def unpatchify(self, x, h, w):
+ """
+ x: (N, T, patch_size**2 * C)
+ imgs: (N, H, W, C)
+ """
+ c = self.out_channels
+ p = self.x_embedder.patch_size[0]
+ h = h // self.patch_size
+ w = w // self.patch_size
+ assert h * w == x.shape[1]
+
+ x = x.reshape(shape=(x.shape[0], h, w, p, p, c))
+ x = torch.einsum('nhwpqc->nchpwq', x)
+ imgs = x.reshape(shape=(x.shape[0], c, h * p, w * p))
+ return imgs
diff --git a/ComfyUI/comfy/ldm/pixeldit/__pycache__/model.cpython-312.pyc b/ComfyUI/comfy/ldm/pixeldit/__pycache__/model.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..8ca09b7b608c37cb382cbedf74db6a7f845453ed
Binary files /dev/null and b/ComfyUI/comfy/ldm/pixeldit/__pycache__/model.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/pixeldit/__pycache__/modules.cpython-312.pyc b/ComfyUI/comfy/ldm/pixeldit/__pycache__/modules.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..fd25272493c7e42e3be75222a7803b8ef72132d5
Binary files /dev/null and b/ComfyUI/comfy/ldm/pixeldit/__pycache__/modules.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/pixeldit/__pycache__/pid.cpython-312.pyc b/ComfyUI/comfy/ldm/pixeldit/__pycache__/pid.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..5a160c797f18a295a961a13ebc7526820c8fc9bf
Binary files /dev/null and b/ComfyUI/comfy/ldm/pixeldit/__pycache__/pid.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/pixeldit/model.py b/ComfyUI/comfy/ldm/pixeldit/model.py
new file mode 100644
index 0000000000000000000000000000000000000000..3b30b92267a0cdaf13623d33c432a9f3facbcb59
--- /dev/null
+++ b/ComfyUI/comfy/ldm/pixeldit/model.py
@@ -0,0 +1,243 @@
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+
+import comfy.ldm.common_dit
+import comfy.patcher_extension
+from comfy.ldm.flux.math import apply_rope, rope
+from comfy.ldm.hidream.model import FeedForwardSwiGLU
+from comfy.ldm.modules.attention import optimized_attention
+from comfy.ldm.modules.diffusionmodules.mmdit import TimestepEmbedder
+
+from .modules import (
+ FinalLayer,
+ PatchTokenEmbedder,
+ PiTBlock,
+ PixelTokenEmbedder,
+ apply_adaln_,
+ precompute_freqs_cis_2d,
+)
+
+
+class MMDiTJointAttention(nn.Module):
+ """Joint MMDiT attention with separate Q/K/V/proj for image and text streams.
+
+ RoPE is applied to each stream before concatenation so each stream uses its own
+ 2D/1D positional encoding. Concat order is [text, image] (text first).
+ """
+ def __init__(self, dim, num_heads=8, qkv_bias=False, dtype=None, device=None, operations=None):
+ super().__init__()
+ assert dim % num_heads == 0
+ self.num_heads = num_heads
+ self.head_dim = dim // num_heads
+
+ self.qkv_x = operations.Linear(dim, dim * 3, bias=qkv_bias, dtype=dtype, device=device)
+ self.qkv_y = operations.Linear(dim, dim * 3, bias=qkv_bias, dtype=dtype, device=device)
+
+ self.q_norm_x = operations.RMSNorm(self.head_dim, eps=1e-6, dtype=dtype, device=device)
+ self.k_norm_x = operations.RMSNorm(self.head_dim, eps=1e-6, dtype=dtype, device=device)
+ self.q_norm_y = operations.RMSNorm(self.head_dim, eps=1e-6, dtype=dtype, device=device)
+ self.k_norm_y = operations.RMSNorm(self.head_dim, eps=1e-6, dtype=dtype, device=device)
+
+ self.proj_x = operations.Linear(dim, dim, dtype=dtype, device=device)
+ self.proj_y = operations.Linear(dim, dim, dtype=dtype, device=device)
+
+ def forward(self, x, y, pos_img, pos_txt=None, attn_mask=None, transformer_options={}):
+ B, Nx, _ = x.shape
+ _, Ny, _ = y.shape
+ H = self.num_heads
+ D = self.head_dim
+
+ qkv_x = self.qkv_x(x).reshape(B, Nx, 3, H, D).permute(2, 0, 3, 1, 4)
+ qx, kx, vx = qkv_x.unbind(0)
+ qx = self.q_norm_x(qx)
+ kx = self.k_norm_x(kx)
+
+ qkv_y = self.qkv_y(y).reshape(B, Ny, 3, H, D).permute(2, 0, 3, 1, 4)
+ qy, ky, vy = qkv_y.unbind(0)
+ qy = self.q_norm_y(qy)
+ ky = self.k_norm_y(ky)
+
+ qx, kx = apply_rope(qx, kx, pos_img[None, None])
+ if pos_txt is not None:
+ qy, ky = apply_rope(qy, ky, pos_txt[None, None])
+
+ q_joint = torch.cat([qy, qx], dim=2)
+ k_joint = torch.cat([ky, kx], dim=2)
+ v_joint = torch.cat([vy, vx], dim=2)
+
+ out_joint = optimized_attention(
+ q_joint, k_joint, v_joint, H,
+ mask=attn_mask, skip_reshape=True, skip_output_reshape=True,
+ transformer_options=transformer_options,
+ )
+
+ out_y = out_joint[:, :, :Ny, :].transpose(1, 2).reshape(B, Ny, H * D)
+ out_x = out_joint[:, :, Ny:, :].transpose(1, 2).reshape(B, Nx, H * D)
+
+ return self.proj_x(out_x), self.proj_y(out_y)
+
+
+class MMDiTBlockT2I(nn.Module):
+ def __init__(self, hidden_size, groups, mlp_ratio=4.0, dtype=None, device=None, operations=None):
+ super().__init__()
+ self.norm_x1 = operations.RMSNorm(hidden_size, eps=1e-6, dtype=dtype, device=device)
+ self.norm_y1 = operations.RMSNorm(hidden_size, eps=1e-6, dtype=dtype, device=device)
+ self.attn = MMDiTJointAttention(hidden_size, num_heads=groups, qkv_bias=False, dtype=dtype, device=device, operations=operations)
+ self.norm_x2 = operations.RMSNorm(hidden_size, eps=1e-6, dtype=dtype, device=device)
+ self.norm_y2 = operations.RMSNorm(hidden_size, eps=1e-6, dtype=dtype, device=device)
+ mlp_hidden_dim = int(hidden_size * mlp_ratio)
+ self.mlp_x = FeedForwardSwiGLU(hidden_size, mlp_hidden_dim, multiple_of=1, dtype=dtype, device=device, operations=operations)
+ self.mlp_y = FeedForwardSwiGLU(hidden_size, mlp_hidden_dim, multiple_of=1, dtype=dtype, device=device, operations=operations)
+ self.adaLN_modulation_img = nn.Sequential(operations.Linear(hidden_size, 6 * hidden_size, bias=True, dtype=dtype, device=device))
+ self.adaLN_modulation_txt = nn.Sequential(operations.Linear(hidden_size, 6 * hidden_size, bias=True, dtype=dtype, device=device))
+
+ def forward(self, x, y, c, pos_img, pos_txt=None, attn_mask=None, transformer_options={}):
+ shift_msa_x, scale_msa_x, gate_msa_x, shift_mlp_x, scale_mlp_x, gate_mlp_x = self.adaLN_modulation_img(c).chunk(6, dim=-1)
+ shift_msa_y, scale_msa_y, gate_msa_y, shift_mlp_y, scale_mlp_y, gate_mlp_y = self.adaLN_modulation_txt(c).chunk(6, dim=-1)
+
+ x_norm = apply_adaln_(self.norm_x1(x), shift_msa_x, scale_msa_x)
+ y_norm = apply_adaln_(self.norm_y1(y), shift_msa_y, scale_msa_y)
+ attn_x, attn_y = self.attn(x_norm, y_norm, pos_img, pos_txt, attn_mask, transformer_options=transformer_options)
+ x = torch.addcmul(x, gate_msa_x, attn_x)
+ y = torch.addcmul(y, gate_msa_y, attn_y)
+
+ x = torch.addcmul(x, gate_mlp_x, self.mlp_x(apply_adaln_(self.norm_x2(x), shift_mlp_x, scale_mlp_x)))
+ y = torch.addcmul(y, gate_mlp_y, self.mlp_y(apply_adaln_(self.norm_y2(y), shift_mlp_y, scale_mlp_y)))
+ return x, y
+
+
+class PixDiT_T2I(nn.Module):
+ """PixelDiT T2I model. Hardcoded for the released 1024px Stage-3 checkpoint
+ (also runs at 512px when fed the appropriate latent size and flow_shift).
+
+ Forward:
+ x: [B, 3, H, W] pixel-space input (no VAE)
+ timesteps:[B] in [0, 1000] (ComfyUI flow sampling convention)
+ context: [B, Ltxt, 2304] Gemma-2-2b-it hidden states (chi_prompt prepended)
+ Returns flow-matching velocity [B, 3, H, W].
+ """
+ def __init__(
+ self,
+ in_channels=3,
+ num_groups=24,
+ hidden_size=1536,
+ pixel_hidden_size=16,
+ pixel_attn_hidden_size=1152,
+ pixel_num_groups=16,
+ patch_depth=14,
+ pixel_depth=2,
+ patch_size=16,
+ txt_embed_dim=2304,
+ txt_max_length=300,
+ use_text_rope=True,
+ text_rope_theta=10000.0,
+ image_model=None,
+ dtype=None,
+ device=None,
+ operations=None,
+ pixel_mlp_chunks=2,
+ ):
+ super().__init__()
+ self.dtype = dtype
+ self.in_channels = in_channels
+ self.out_channels = in_channels
+ self.hidden_size = hidden_size
+ self.num_groups = num_groups
+ self.patch_depth = patch_depth
+ self.pixel_depth = pixel_depth
+ self.patch_size = patch_size
+ self.pixel_hidden_size = pixel_hidden_size
+ self.pixel_attn_hidden_size = pixel_attn_hidden_size
+ self.pixel_num_groups = pixel_num_groups
+ self.txt_embed_dim = txt_embed_dim
+ self.txt_max_length = txt_max_length
+ self.use_text_rope = use_text_rope
+ self.text_rope_theta = text_rope_theta
+
+ self.pixel_embedder = PixelTokenEmbedder(self.in_channels, self.pixel_hidden_size, dtype=dtype, device=device, operations=operations)
+ self.s_embedder = PatchTokenEmbedder(self.in_channels * self.patch_size ** 2, self.hidden_size, bias=True, dtype=dtype, device=device, operations=operations)
+ self.t_embedder = TimestepEmbedder(self.hidden_size, dtype=dtype, device=device, operations=operations, max_period=10)
+ self.y_embedder = PatchTokenEmbedder(self.txt_embed_dim, self.hidden_size, bias=True, use_norm=True, dtype=dtype, device=device, operations=operations)
+ self.y_pos_embedding = nn.Parameter(torch.empty(1, self.txt_max_length, self.hidden_size, dtype=dtype, device=device))
+
+ self.patch_blocks = nn.ModuleList([
+ MMDiTBlockT2I(self.hidden_size, self.num_groups,
+ dtype=dtype, device=device, operations=operations)
+ for _ in range(self.patch_depth)
+ ])
+ self.pixel_blocks = nn.ModuleList([
+ PiTBlock(
+ self.pixel_hidden_size,
+ self.hidden_size,
+ patch_size=self.patch_size,
+ num_heads=self.num_groups,
+ attn_hidden_size=self.pixel_attn_hidden_size,
+ attn_num_heads=self.pixel_num_groups,
+ dtype=dtype, device=device, operations=operations,
+ mlp_chunks=pixel_mlp_chunks,
+ )
+ for _ in range(self.pixel_depth)
+ ])
+
+ self.final_layer = FinalLayer(self.pixel_hidden_size, self.out_channels, dtype=dtype, device=device, operations=operations)
+
+ def _fetch_patch_pos(self, height, width, device, dtype, **rope_opts):
+ return precompute_freqs_cis_2d(self.hidden_size // self.num_groups, height, width, device=device, dtype=dtype, **rope_opts)
+
+ def _fetch_text_pos(self, length, device, dtype):
+ return rope(torch.arange(length, dtype=torch.float32, device=device).reshape(1, -1), self.hidden_size // self.num_groups, self.text_rope_theta).squeeze(0).to(dtype=dtype)
+
+ def forward(self, x, timesteps, context=None, attention_mask=None, transformer_options={}, **kwargs):
+ return comfy.patcher_extension.WrapperExecutor.new_class_executor(
+ self._forward, self, comfy.patcher_extension.get_all_wrappers(comfy.patcher_extension.WrappersMP.DIFFUSION_MODEL, transformer_options),
+ ).execute(x, timesteps, context, attention_mask, transformer_options, **kwargs)
+
+ def _pre_patch_block(self, s, i, **kwargs):
+ """Hook for subclasses to inject per-block state into the patch stream (e.g. PiD's LQ gate)."""
+ return s
+
+ def _pre_pixel_blocks(self, s, **kwargs):
+ return s
+
+ def _forward(self, x, timesteps, context=None, attention_mask=None, transformer_options={}, **kwargs):
+ H_orig, W_orig = x.shape[2], x.shape[3]
+ x = comfy.ldm.common_dit.pad_to_patch_size(x, (self.patch_size, self.patch_size))
+ B, _, H, W = x.shape
+ Hs = H // self.patch_size
+ Ws = W // self.patch_size
+ L = Hs * Ws
+
+ pos_img = self._fetch_patch_pos(Hs, Ws, x.device, x.dtype, **(transformer_options.get("rope_options") or {}))
+ x_patches = F.unfold(x, kernel_size=self.patch_size, stride=self.patch_size).transpose(1, 2)
+
+ t_emb = self.t_embedder(timesteps.view(-1), x.dtype).view(B, -1, self.hidden_size)
+
+ if context is None or context.dim() != 3:
+ raise ValueError("PixDiT_T2I requires context (text embeddings) of shape [B, L, D]")
+ Ltxt = min(context.shape[1], self.txt_max_length)
+ y = context[:, :Ltxt, :]
+ y_emb = self.y_embedder(y).view(B, Ltxt, self.hidden_size)
+ y_emb = y_emb + self.y_pos_embedding[:, :Ltxt, :].to(y_emb) # y_pos_embedding is a raw nn.Parameter
+
+ condition = F.silu(t_emb)
+ pos_txt = self._fetch_text_pos(Ltxt, x.device, x.dtype) if self.use_text_rope else None
+
+ s = self.s_embedder(x_patches)
+ for i, blk in enumerate(self.patch_blocks):
+ s = self._pre_patch_block(s, i, **kwargs)
+ s, y_emb = blk(s, y_emb, condition, pos_img, pos_txt, None, transformer_options=transformer_options)
+ s = F.silu(t_emb + s)
+
+ s = self._pre_pixel_blocks(s, **kwargs)
+ s_cond = s.view(B * L, self.hidden_size)
+ x_pixels = self.pixel_embedder(x, patch_size=self.patch_size)
+ for blk in self.pixel_blocks:
+ x_pixels = blk(x_pixels, s_cond, H, W, self.patch_size, mask=None, transformer_options=transformer_options)
+
+ x_pixels = self.final_layer(x_pixels)
+ C_out = self.out_channels
+ P2 = self.patch_size * self.patch_size
+ x_pixels = x_pixels.view(B, L, P2, C_out).permute(0, 3, 2, 1).reshape(B, C_out * P2, L)
+ out = F.fold(x_pixels, (H, W), kernel_size=self.patch_size, stride=self.patch_size)
+ return out[:, :, :H_orig, :W_orig]
diff --git a/ComfyUI/comfy/ldm/pixeldit/modules.py b/ComfyUI/comfy/ldm/pixeldit/modules.py
new file mode 100644
index 0000000000000000000000000000000000000000..4b1e538c70be9711ead8d4b8dbf6c821b7d18457
--- /dev/null
+++ b/ComfyUI/comfy/ldm/pixeldit/modules.py
@@ -0,0 +1,187 @@
+import torch
+import torch.nn as nn
+
+from comfy.ldm.flux.math import apply_rope, rope
+from comfy.ldm.modules.attention import optimized_attention
+from comfy.ldm.modules.diffusionmodules.mmdit import Mlp, get_1d_sincos_pos_embed_from_grid_torch
+
+
+def apply_adaln_(x, shift, scale):
+ return x.addcmul_(x, scale).add_(shift)
+
+
+def precompute_freqs_cis_2d(dim, height, width, theta=10000.0, scale=16.0,
+ ref_grid_h=None, ref_grid_w=None,
+ scale_x=1.0, scale_y=1.0, shift_x=0.0, shift_y=0.0,
+ device=None, dtype=torch.float32, **kwargs):
+ """2D RoPE with x/y axis frequencies interleaved at stride 2 across head dim.
+
+ rope_options:
+ scale_x / scale_y multiply the position range (RoPE extrapolation).
+ shift_x / shift_y offset the position origin (tiled / regional inference).
+ With ref_grid_h/w set, also applies NTK-aware per-axis theta scaling
+ (rope_mode='ntk_aware'): theta_axis = theta * (current/ref)^(dim_axis/(dim_axis-2)).
+ Returns Flux-format rotation matrices of shape [H*W, dim/2, 2, 2].
+ Layout of head-dim pairs: [x_0, y_0, x_1, y_1, ..., x_{dim/4-1}, y_{dim/4-1}].
+ """
+ dim_axis = dim // 2
+ if ref_grid_h is not None and dim_axis > 2:
+ h_ntk = (height / ref_grid_h) ** (dim_axis / (dim_axis - 2))
+ w_ntk = (width / ref_grid_w) ** (dim_axis / (dim_axis - 2))
+ else:
+ h_ntk = w_ntk = 1.0
+
+ x_lin = torch.linspace(shift_x, scale * scale_x + shift_x, width, device=device)
+ y_lin = torch.linspace(shift_y, scale * scale_y + shift_y, height, device=device)
+ y_grid, x_grid = torch.meshgrid(y_lin, x_lin, indexing="ij")
+ x_rope = rope(x_grid.reshape(1, -1), dim_axis, theta * w_ntk).squeeze(0)
+ y_rope = rope(y_grid.reshape(1, -1), dim_axis, theta * h_ntk).squeeze(0)
+ out = torch.stack([x_rope, y_rope], dim=2).reshape(height * width, dim // 2, 2, 2)
+ return out.to(dtype=dtype)
+
+
+def get_2d_sincos_pos_embed(embed_dim, height, width, device=None, dtype=torch.float32):
+ """Standard 2D sin/cos absolute positional embedding (ViT-style).
+
+ first half encodes W-coordinates, second half H.
+ """
+ assert embed_dim % 4 == 0
+ grid_h = torch.arange(height, dtype=torch.float32, device=device)
+ grid_w = torch.arange(width, dtype=torch.float32, device=device)
+ grid_y, grid_x = torch.meshgrid(grid_h, grid_w, indexing="ij")
+ emb_w = get_1d_sincos_pos_embed_from_grid_torch(embed_dim // 2, grid_x.reshape(-1), device=device)
+ emb_h = get_1d_sincos_pos_embed_from_grid_torch(embed_dim // 2, grid_y.reshape(-1), device=device)
+ return torch.cat([emb_w, emb_h], dim=1).to(dtype=dtype)
+
+
+class RotaryAttention(nn.Module):
+ """Single-stream self-attention with rotary positional encoding (used inside PiTBlock)."""
+ def __init__(self, dim, num_heads=8, qkv_bias=False, dtype=None, device=None, operations=None):
+ super().__init__()
+ assert dim % num_heads == 0
+ self.num_heads = num_heads
+ self.head_dim = dim // num_heads
+ self.qkv = operations.Linear(dim, dim * 3, bias=qkv_bias, dtype=dtype, device=device)
+ self.q_norm = operations.RMSNorm(self.head_dim, eps=1e-6, dtype=dtype, device=device)
+ self.k_norm = operations.RMSNorm(self.head_dim, eps=1e-6, dtype=dtype, device=device)
+ self.proj = operations.Linear(dim, dim, dtype=dtype, device=device)
+
+ def forward(self, x, pos, mask=None, transformer_options={}):
+ B, N, C = x.shape
+ H = self.num_heads
+ D = self.head_dim
+ qkv = self.qkv(x).reshape(B, N, 3, H, D).permute(2, 0, 3, 1, 4)
+ q, k, v = qkv.unbind(0)
+ q, k = apply_rope(self.q_norm(q), self.k_norm(k), pos[None, None])
+ x = optimized_attention(q, k, v, H, mask=mask, skip_reshape=True, transformer_options=transformer_options)
+ return self.proj(x)
+
+
+class FinalLayer(nn.Module):
+ def __init__(self, hidden_size, out_channels, dtype=None, device=None, operations=None):
+ super().__init__()
+ self.norm = operations.RMSNorm(hidden_size, eps=1e-6, dtype=dtype, device=device)
+ self.linear = operations.Linear(hidden_size, out_channels, bias=True, dtype=dtype, device=device)
+
+ def forward(self, x):
+ return self.linear(self.norm(x))
+
+
+class PatchTokenEmbedder(nn.Module):
+ """Linear projection used both for patchified-image tokens and text-feature tokens."""
+ def __init__(self, in_chans, embed_dim, use_norm=False, bias=True, dtype=None, device=None, operations=None):
+ super().__init__()
+ self.proj = operations.Linear(in_chans, embed_dim, bias=bias, dtype=dtype, device=device)
+ self.norm = operations.RMSNorm(embed_dim, eps=1e-6, dtype=dtype, device=device) if use_norm else nn.Identity()
+
+ def forward(self, x):
+ return self.norm(self.proj(x))
+
+
+class PixelTokenEmbedder(nn.Module):
+ """Pixel-level embedder: lifts each RGB pixel to hidden_size and packs into per-patch sequences."""
+ def __init__(self, in_channels, hidden_size_output, dtype=None, device=None, operations=None):
+ super().__init__()
+ self.in_channels = in_channels
+ self.hidden_size_output = hidden_size_output
+ self.proj = operations.Linear(self.in_channels, self.hidden_size_output, bias=True, dtype=dtype, device=device)
+
+ def forward(self, inputs, patch_size):
+ B, _, H, W = inputs.shape
+ Hs, Ws = H // patch_size, W // patch_size
+ P2 = patch_size * patch_size
+ x = inputs.permute(0, 2, 3, 1).contiguous()
+ x = self.proj(x)
+ pos_full = get_2d_sincos_pos_embed(self.hidden_size_output, H, W, device=x.device, dtype=x.dtype).view(H, W, self.hidden_size_output)
+ x = x + pos_full.unsqueeze(0)
+ x = x.view(B, Hs, patch_size, Ws, patch_size, self.hidden_size_output)
+ return x.permute(0, 1, 3, 2, 4, 5).reshape(B * Hs * Ws, P2, self.hidden_size_output)
+
+
+class PiTBlock(nn.Module):
+ """Pixel-level transformer block.
+
+ Compresses each patch's P^2 pixel tokens → 1 attention token via a linear,
+ runs global self-attention across patches with 2D RoPE, then expands back to P^2 tokens.
+ Conditioning is per-pixel adaLN from the patch-level features.
+ """
+ def __init__(self, pixel_hidden_size, patch_hidden_size, patch_size, num_heads, mlp_ratio=4.0,
+ attn_hidden_size=None, attn_num_heads=None, dtype=None, device=None, operations=None, mlp_chunks=1):
+ super().__init__()
+ self.pixel_dim = pixel_hidden_size
+ self.context_dim = patch_hidden_size
+ self.attn_dim = attn_hidden_size if attn_hidden_size is not None else patch_hidden_size
+ self.num_heads = attn_num_heads if attn_num_heads is not None else num_heads
+ assert self.attn_dim % self.num_heads == 0
+
+ p2 = patch_size * patch_size
+ self.compress_to_attn = operations.Linear(p2 * self.pixel_dim, self.attn_dim, bias=True, dtype=dtype, device=device)
+ self.expand_from_attn = operations.Linear(self.attn_dim, p2 * self.pixel_dim, bias=True, dtype=dtype, device=device)
+
+ self.norm1 = operations.RMSNorm(self.pixel_dim, eps=1e-6, dtype=dtype, device=device)
+ self.attn = RotaryAttention(self.attn_dim, num_heads=self.num_heads, qkv_bias=False, dtype=dtype, device=device, operations=operations)
+ self.norm2 = operations.RMSNorm(self.pixel_dim, eps=1e-6, dtype=dtype, device=device)
+ self.mlp = Mlp(self.pixel_dim, hidden_features=int(self.pixel_dim * mlp_ratio), dtype=dtype, device=device, operations=operations)
+
+ self.adaLN_modulation_msa = operations.Linear(self.context_dim, 3 * self.pixel_dim * p2, bias=True, dtype=dtype, device=device)
+ self.adaLN_modulation_mlp = operations.Linear(self.context_dim, 3 * self.pixel_dim * p2, bias=True, dtype=dtype, device=device)
+
+ self._rope_fn = precompute_freqs_cis_2d
+ self.mlp_chunks = max(1, int(mlp_chunks))
+
+ def _fetch_pos(self, height, width, device, dtype, **rope_opts):
+ return self._rope_fn(self.attn_dim // self.num_heads, height, width, device=device, dtype=dtype, **rope_opts)
+
+ def forward(self, x, s_cond, image_height, image_width, patch_size, mask=None, transformer_options={}):
+ BL, P2, _ = x.shape
+ Hs, Ws = image_height // patch_size, image_width // patch_size
+ L = Hs * Ws
+ B = BL // L
+
+ # Attention path uses only msa params; compute, use, free before mlp params allocate.
+ msa_params = self.adaLN_modulation_msa(s_cond).view(BL, P2, 3 * self.pixel_dim)
+ shift_msa, scale_msa, gate_msa = msa_params.chunk(3, dim=-1)
+
+ x_norm = apply_adaln_(self.norm1(x), shift_msa, scale_msa)
+ x_flat = x_norm.view(BL, P2 * self.pixel_dim)
+
+ x_comp = self.compress_to_attn(x_flat).view(B, L, self.attn_dim)
+ pos_comp = self._fetch_pos(Hs, Ws, x.device, x.dtype, **(transformer_options.get("rope_options") or {}))
+ attn_out = self.attn(x_comp, pos_comp, mask=mask, transformer_options=transformer_options)
+ attn_flat = self.expand_from_attn(attn_out.view(B * L, self.attn_dim))
+ attn_exp = attn_flat.view(BL, P2, self.pixel_dim)
+ x = torch.addcmul(x, gate_msa, attn_exp)
+ del msa_params, shift_msa, scale_msa, gate_msa
+
+ mlp_params = self.adaLN_modulation_mlp(s_cond).view(BL, P2, 3 * self.pixel_dim)
+ shift_mlp, scale_mlp, gate_mlp = mlp_params.chunk(3, dim=-1)
+ gate_mlp = gate_mlp.contiguous() # detach from mlp_params so the del below frees shift+scale storage before the MLP
+ mlp_input = apply_adaln_(self.norm2(x), shift_mlp, scale_mlp)
+ del mlp_params, shift_mlp, scale_mlp
+
+ # MLP in chunks since the peak memory usage is huge here
+ chunk_size = (BL + self.mlp_chunks - 1) // self.mlp_chunks
+ for s in range(0, BL, chunk_size):
+ e = min(s + chunk_size, BL)
+ x[s:e].addcmul_(gate_mlp[s:e], self.mlp(mlp_input[s:e]))
+ return x
diff --git a/ComfyUI/comfy/ldm/pixeldit/pid.py b/ComfyUI/comfy/ldm/pixeldit/pid.py
new file mode 100644
index 0000000000000000000000000000000000000000..8590408d9b0f4ae1322fc7ddf2de0b4dc0e5c6f9
--- /dev/null
+++ b/ComfyUI/comfy/ldm/pixeldit/pid.py
@@ -0,0 +1,263 @@
+"""PiD — Pixel Diffusion Decoder. Decodes a Flux/SD3/Flux2/Z-Image latent
+directly to a 4x-upscaled image in 4 distilled flow-matching steps. PixDiT_T2I
+body + LQ projection branch injected before each MMDiT patch block.
+"""
+
+from typing import List
+
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+
+from .model import PixDiT_T2I
+from .modules import precompute_freqs_cis_2d
+
+
+class SigmaAwareGate(nn.Module):
+ """gate = sigmoid(content_proj(cat[x, lq]) - exp(log_alpha) * sigma); out = x + gate * lq.
+
+ Trained init gives ~0.88 gate at sigma=0, ~0.05 at sigma=1.
+ """
+
+ def __init__(self, dim: int, per_token: bool = False, dtype=None, device=None, operations=None):
+ super().__init__()
+ self.content_proj = operations.Linear(dim * 2, 1 if per_token else dim, dtype=dtype, device=device)
+ self.log_alpha = nn.Parameter(torch.empty((), dtype=dtype, device=device))
+
+ def forward(self, x: torch.Tensor, lq: torch.Tensor, sigma: torch.Tensor) -> torch.Tensor:
+ content_logit = self.content_proj(torch.cat([x, lq], dim=-1))
+ # log_alpha is a raw nn.Parameter -> doesn't auto-cast under dynamic VRAM.
+ log_alpha = self.log_alpha.to(device=x.device, dtype=torch.float32)
+ sigma_offset = -log_alpha.exp() * sigma.float().view(-1, 1, 1)
+ gate = torch.sigmoid(content_logit + sigma_offset)
+ return x + (gate * lq).to(x.dtype)
+
+
+class ResBlock(nn.Module):
+ """Pre-activation ResNet block: GN -> SiLU -> Conv -> GN -> SiLU -> Conv + skip."""
+
+ def __init__(self, channels: int, num_groups: int = 4, conv_padding_mode: str = "zeros", dtype=None, device=None, operations=None):
+ super().__init__()
+ self.block = nn.Sequential(
+ operations.GroupNorm(num_groups, channels, dtype=dtype, device=device),
+ nn.SiLU(),
+ operations.Conv2d(channels, channels, kernel_size=3, padding=1, padding_mode=conv_padding_mode, dtype=dtype, device=device),
+ operations.GroupNorm(num_groups, channels, dtype=dtype, device=device),
+ nn.SiLU(),
+ operations.Conv2d(channels, channels, kernel_size=3, padding=1, padding_mode=conv_padding_mode, dtype=dtype, device=device),
+ )
+
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
+ return x + self.block(x)
+
+
+class LQProjection2D(nn.Module):
+ """LQ latent -> per-block patch-aligned features for controlnet-style injection."""
+
+ def __init__(
+ self,
+ latent_channels: int,
+ hidden_dim: int = 512,
+ out_dim: int = 1536,
+ patch_size: int = 16,
+ sr_scale: int = 4,
+ latent_spatial_down_factor: int = 8,
+ latent_unpatchify_factor: int = 1,
+ num_res_blocks: int = 4,
+ num_outputs: int = 7,
+ interval: int = 2,
+ conv_padding_mode: str = "zeros",
+ gate_per_token: bool = False,
+ pit_output: bool = False,
+ dtype=None, device=None, operations=None,
+ ):
+ super().__init__()
+ self.latent_channels = latent_channels
+ self.hidden_dim = hidden_dim
+ self.out_dim = out_dim
+ self.patch_size = patch_size
+ self.sr_scale = sr_scale
+ self.latent_spatial_down_factor = latent_spatial_down_factor
+ self.latent_unpatchify_factor = latent_unpatchify_factor
+ self.num_outputs = num_outputs
+ self.interval = interval
+
+ effective_latent_channels = latent_channels // (latent_unpatchify_factor * latent_unpatchify_factor)
+ effective_spatial_down_factor = latent_spatial_down_factor // latent_unpatchify_factor
+ z_to_patch_ratio = (sr_scale * effective_spatial_down_factor) / patch_size
+ self.z_to_patch_ratio = z_to_patch_ratio
+ if z_to_patch_ratio >= 1:
+ self.latent_fold_factor = 0
+ latent_proj_in_ch = effective_latent_channels
+ else:
+ fold_factor = int(1 / z_to_patch_ratio)
+ assert fold_factor * z_to_patch_ratio == 1.0
+ self.latent_fold_factor = fold_factor
+ latent_proj_in_ch = effective_latent_channels * fold_factor * fold_factor
+
+ layers = [
+ operations.Conv2d(latent_proj_in_ch, hidden_dim, kernel_size=3, padding=1, padding_mode=conv_padding_mode, dtype=dtype, device=device),
+ nn.SiLU(),
+ operations.Conv2d(hidden_dim, hidden_dim, kernel_size=3, padding=1, padding_mode=conv_padding_mode, dtype=dtype, device=device),
+ ]
+ for _ in range(num_res_blocks):
+ layers.append(ResBlock(hidden_dim, conv_padding_mode=conv_padding_mode, dtype=dtype, device=device, operations=operations))
+ self.latent_proj = nn.Sequential(*layers)
+
+ self.output_heads = nn.ModuleList(
+ [operations.Linear(hidden_dim, out_dim, dtype=dtype, device=device) for _ in range(num_outputs)]
+ )
+ self.pit_head = operations.Linear(hidden_dim, out_dim, dtype=dtype, device=device) if pit_output else None
+ self.gate_modules = nn.ModuleList(
+ [SigmaAwareGate(out_dim, per_token=gate_per_token, dtype=dtype, device=device, operations=operations)
+ for _ in range(num_outputs)]
+ )
+
+ def is_gate_active(self, block_idx: int) -> bool:
+ return block_idx % self.interval == 0
+
+ def output_index(self, block_idx: int) -> int:
+ return block_idx // self.interval
+
+ def gate(self, x: torch.Tensor, lq_feature: torch.Tensor, sigma: torch.Tensor, out_idx: int) -> torch.Tensor:
+ return self.gate_modules[out_idx](x, lq_feature, sigma)
+
+ def _align_latent_to_patch_grid(self, lq_latent: torch.Tensor, pH: int, pW: int) -> torch.Tensor:
+ f = self.latent_unpatchify_factor
+ if f > 1:
+ B, C, H, W = lq_latent.shape
+ lq_latent = lq_latent.reshape(B, C // (f * f), f, f, H, W)
+ lq_latent = lq_latent.permute(0, 1, 4, 2, 5, 3).reshape(B, C // (f * f), H * f, W * f)
+ B, z_dim = lq_latent.shape[:2]
+ if self.z_to_patch_ratio >= 1:
+ if lq_latent.shape[2] != pH or lq_latent.shape[3] != pW:
+ z_aligned = F.interpolate(lq_latent, size=(pH, pW), mode="nearest")
+ else:
+ z_aligned = lq_latent
+ else:
+ f = self.latent_fold_factor
+ zH_expected, zW_expected = pH * f, pW * f
+ if lq_latent.shape[2] != zH_expected or lq_latent.shape[3] != zW_expected:
+ lq_latent = F.interpolate(lq_latent, size=(zH_expected, zW_expected), mode="nearest")
+ z_aligned = lq_latent.reshape(B, z_dim, pH, f, pW, f).permute(0, 1, 3, 5, 2, 4)
+ z_aligned = z_aligned.reshape(B, z_dim * f * f, pH, pW)
+ return self.latent_proj(z_aligned)
+
+ def forward(self, lq_latent: torch.Tensor, target_pH: int, target_pW: int) -> List[torch.Tensor]:
+ feat = self._align_latent_to_patch_grid(lq_latent, target_pH, target_pW)
+ B, C, H, W = feat.shape
+ tokens = feat.permute(0, 2, 3, 1).contiguous().view(B, H * W, C)
+ outputs = [head(tokens) for head in self.output_heads]
+ if self.pit_head is not None:
+ outputs.append(self.pit_head(tokens))
+ return outputs
+
+
+class PidNet(PixDiT_T2I):
+ """PixDiT_T2I + LQ injection (one sigma-gated feature inserted before each patch block)."""
+
+ def __init__(
+ self,
+ lq_latent_channels: int = 16,
+ lq_hidden_dim: int = 512,
+ lq_num_res_blocks: int = 4,
+ lq_interval: int = 2,
+ sr_scale: int = 4,
+ latent_spatial_down_factor: int = 8,
+ lq_latent_unpatchify_factor: int = 1,
+ lq_conv_padding_mode: str = "zeros",
+ lq_gate_per_token: bool = False,
+ pit_lq_inject: bool = False,
+ rope_ref_h: int = 1024, # NTK ref resolution in PIXEL units: 1024px / patch=16 -> grid_ref=64.
+ rope_ref_w: int = 1024,
+ image_model=None,
+ dtype=None, device=None, operations=None,
+ **pixdit_kwargs,
+ ):
+ super().__init__(dtype=dtype, device=device, operations=operations, **pixdit_kwargs)
+
+ self.rope_ref_grid_h = rope_ref_h // self.patch_size
+ self.rope_ref_grid_w = rope_ref_w // self.patch_size
+
+ # Parent's PiTBlocks were built with plain RoPE — swap in NTK-aware.
+ def _pit_rope_fn(head_dim, h, w, device=None, dtype=torch.float32, **rope_opts):
+ return precompute_freqs_cis_2d(head_dim, h, w, ref_grid_h=self.rope_ref_grid_h, ref_grid_w=self.rope_ref_grid_w, device=device, dtype=dtype, **rope_opts)
+ for blk in self.pixel_blocks:
+ blk._rope_fn = _pit_rope_fn
+
+ self.pit_lq_inject = pit_lq_inject
+
+ num_lq_outputs = (self.patch_depth + lq_interval - 1) // lq_interval
+ self.lq_proj = LQProjection2D(
+ latent_channels=lq_latent_channels,
+ hidden_dim=lq_hidden_dim,
+ out_dim=self.hidden_size,
+ patch_size=self.patch_size,
+ sr_scale=sr_scale,
+ latent_spatial_down_factor=latent_spatial_down_factor,
+ latent_unpatchify_factor=lq_latent_unpatchify_factor,
+ num_res_blocks=lq_num_res_blocks,
+ num_outputs=num_lq_outputs,
+ interval=lq_interval,
+ conv_padding_mode=lq_conv_padding_mode,
+ gate_per_token=lq_gate_per_token,
+ pit_output=pit_lq_inject,
+ dtype=dtype,
+ device=device,
+ operations=operations,
+ )
+ self.pit_lq_gate = SigmaAwareGate(
+ self.hidden_size, per_token=lq_gate_per_token, dtype=dtype, device=device, operations=operations
+ ) if pit_lq_inject else None
+
+ def _fetch_patch_pos(self, height, width, device, dtype, **rope_opts):
+ return precompute_freqs_cis_2d(
+ self.hidden_size // self.num_groups,
+ height, width,
+ ref_grid_h=self.rope_ref_grid_h, ref_grid_w=self.rope_ref_grid_w,
+ device=device, dtype=dtype, **rope_opts,
+ )
+
+ def _pre_patch_block(self, s, i, pid_lq_features, pid_degrade_sigma, **kwargs):
+ if not self.lq_proj.is_gate_active(i):
+ return s
+ out_idx = self.lq_proj.output_index(i)
+ if out_idx >= len(pid_lq_features):
+ return s
+ return self.lq_proj.gate(s, pid_lq_features[out_idx], pid_degrade_sigma, out_idx)
+
+ def _pre_pixel_blocks(self, s, pid_pit_lq_feature=None, pid_degrade_sigma=None, **kwargs):
+ if pid_pit_lq_feature is None:
+ return s
+ return self.pit_lq_gate(s, pid_pit_lq_feature, pid_degrade_sigma)
+
+ def _forward(self, x, timesteps, context=None, attention_mask=None, transformer_options={}, lq_latent=None, degrade_sigma=None, **kwargs):
+ if lq_latent is None:
+ raise ValueError("PidNet requires lq_latent — attach via PiDConditioning")
+ expected_c = self.lq_proj.latent_channels
+ if lq_latent.shape[1] != expected_c:
+ raise ValueError(
+ f"Input latent has {lq_latent.shape[1]} channels, this model variant expects {expected_c}. "
+ f"Flux1/SD3 = 16 channels, Flux2 = 128 channels."
+ )
+ B = x.shape[0]
+ # Match the backbone's pad_to_patch_size (round up) so the LQ grid lines up with the patch stream.
+ Hs = -(-x.shape[2] // self.patch_size)
+ Ws = -(-x.shape[3] // self.patch_size)
+
+ degrade_sigma = degrade_sigma.to(device=x.device, dtype=torch.float32).reshape(-1)
+ if degrade_sigma.numel() == 1 and B > 1:
+ degrade_sigma = degrade_sigma.expand(B).contiguous()
+
+ lq_features = self.lq_proj(lq_latent=lq_latent.to(x), target_pH=Hs, target_pW=Ws)
+ pit_lq_feature = lq_features.pop() if self.pit_lq_inject else None
+
+ return super()._forward(
+ x, timesteps,
+ context=context, attention_mask=attention_mask,
+ transformer_options=transformer_options,
+ pid_lq_features=lq_features,
+ pid_pit_lq_feature=pit_lq_feature,
+ pid_degrade_sigma=degrade_sigma,
+ **kwargs,
+ )
diff --git a/ComfyUI/comfy/ldm/qwen_image/__pycache__/controlnet.cpython-312.pyc b/ComfyUI/comfy/ldm/qwen_image/__pycache__/controlnet.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..4aeb42f302ce908b499eef4978910320cea08647
Binary files /dev/null and b/ComfyUI/comfy/ldm/qwen_image/__pycache__/controlnet.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/qwen_image/__pycache__/model.cpython-312.pyc b/ComfyUI/comfy/ldm/qwen_image/__pycache__/model.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..ebd4568d15b1977c4eefabd73452d5e3507cca0b
Binary files /dev/null and b/ComfyUI/comfy/ldm/qwen_image/__pycache__/model.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/qwen_image/controlnet.py b/ComfyUI/comfy/ldm/qwen_image/controlnet.py
new file mode 100644
index 0000000000000000000000000000000000000000..c0aae9240f812f07012c4c312cd4cd5882cd0923
--- /dev/null
+++ b/ComfyUI/comfy/ldm/qwen_image/controlnet.py
@@ -0,0 +1,267 @@
+import torch
+import math
+
+from .model import QwenImageTransformer2DModel
+from .model import QwenImageTransformerBlock
+
+
+class QwenImageFunControlBlock(QwenImageTransformerBlock):
+ def __init__(self, dim, num_attention_heads, attention_head_dim, has_before_proj=False, dtype=None, device=None, operations=None):
+ super().__init__(
+ dim=dim,
+ num_attention_heads=num_attention_heads,
+ attention_head_dim=attention_head_dim,
+ dtype=dtype,
+ device=device,
+ operations=operations,
+ )
+ self.has_before_proj = has_before_proj
+ if has_before_proj:
+ self.before_proj = operations.Linear(dim, dim, device=device, dtype=dtype)
+ self.after_proj = operations.Linear(dim, dim, device=device, dtype=dtype)
+
+
+class QwenImageFunControlNetModel(torch.nn.Module):
+ def __init__(
+ self,
+ control_in_features=132,
+ inner_dim=3072,
+ num_attention_heads=24,
+ attention_head_dim=128,
+ num_control_blocks=5,
+ main_model_double=60,
+ injection_layers=(0, 12, 24, 36, 48),
+ dtype=None,
+ device=None,
+ operations=None,
+ ):
+ super().__init__()
+ self.dtype = dtype
+ self.main_model_double = main_model_double
+ self.injection_layers = tuple(injection_layers)
+ # Keep base hint scaling at 1.0 so user-facing strength behaves similarly
+ # to the reference Gen2/VideoX implementation around strength=1.
+ self.hint_scale = 1.0
+ self.control_img_in = operations.Linear(control_in_features, inner_dim, device=device, dtype=dtype)
+
+ self.control_blocks = torch.nn.ModuleList([])
+ for i in range(num_control_blocks):
+ self.control_blocks.append(
+ QwenImageFunControlBlock(
+ dim=inner_dim,
+ num_attention_heads=num_attention_heads,
+ attention_head_dim=attention_head_dim,
+ has_before_proj=(i == 0),
+ dtype=dtype,
+ device=device,
+ operations=operations,
+ )
+ )
+
+ def _process_hint_tokens(self, hint):
+ if hint is None:
+ return None
+ if hint.ndim == 4:
+ hint = hint.unsqueeze(2)
+
+ # Fun checkpoints are trained with 33 latent channels before 2x2 packing:
+ # [control_latent(16), mask(1), inpaint_latent(16)] -> 132 features.
+ # Default behavior (no inpaint input in stock Apply ControlNet) should use
+ # zeros for mask/inpaint branches, matching VideoX fallback semantics.
+ expected_c = self.control_img_in.weight.shape[1] // 4
+ if hint.shape[1] == 16 and expected_c == 33:
+ zeros_mask = torch.zeros_like(hint[:, :1])
+ zeros_inpaint = torch.zeros_like(hint)
+ hint = torch.cat([hint, zeros_mask, zeros_inpaint], dim=1)
+
+ bs, c, t, h, w = hint.shape
+ hidden_states = torch.nn.functional.pad(hint, (0, w % 2, 0, h % 2))
+ orig_shape = hidden_states.shape
+ hidden_states = hidden_states.view(
+ orig_shape[0],
+ orig_shape[1],
+ orig_shape[-3],
+ orig_shape[-2] // 2,
+ 2,
+ orig_shape[-1] // 2,
+ 2,
+ )
+ hidden_states = hidden_states.permute(0, 2, 3, 5, 1, 4, 6)
+ hidden_states = hidden_states.reshape(
+ bs,
+ t * ((h + 1) // 2) * ((w + 1) // 2),
+ c * 4,
+ )
+
+ expected_in = self.control_img_in.weight.shape[1]
+ cur_in = hidden_states.shape[-1]
+ if cur_in < expected_in:
+ pad = torch.zeros(
+ (hidden_states.shape[0], hidden_states.shape[1], expected_in - cur_in),
+ device=hidden_states.device,
+ dtype=hidden_states.dtype,
+ )
+ hidden_states = torch.cat([hidden_states, pad], dim=-1)
+ elif cur_in > expected_in:
+ hidden_states = hidden_states[:, :, :expected_in]
+
+ return hidden_states
+
+ def forward(
+ self,
+ x,
+ timesteps,
+ context,
+ attention_mask=None,
+ guidance: torch.Tensor = None,
+ hint=None,
+ transformer_options={},
+ base_model=None,
+ **kwargs,
+ ):
+ if base_model is None:
+ raise RuntimeError("Qwen Fun ControlNet requires a QwenImage base model at runtime.")
+
+ encoder_hidden_states_mask = attention_mask
+ # Keep attention mask disabled inside Fun control blocks to mirror
+ # VideoX behavior (they rely on seq lengths for RoPE, not masked attention).
+ encoder_hidden_states_mask = None
+
+ hidden_states, img_ids, _ = base_model.process_img(x)
+ hint_tokens = self._process_hint_tokens(hint)
+ if hint_tokens is None:
+ raise RuntimeError("Qwen Fun ControlNet requires a control hint image.")
+
+ if hint_tokens.shape[1] != hidden_states.shape[1]:
+ max_tokens = min(hint_tokens.shape[1], hidden_states.shape[1])
+ hint_tokens = hint_tokens[:, :max_tokens]
+ hidden_states = hidden_states[:, :max_tokens]
+ img_ids = img_ids[:, :max_tokens]
+
+ txt_start = round(
+ max(
+ ((x.shape[-1] + (base_model.patch_size // 2)) // base_model.patch_size) // 2,
+ ((x.shape[-2] + (base_model.patch_size // 2)) // base_model.patch_size) // 2,
+ )
+ )
+ txt_ids = torch.arange(txt_start, txt_start + context.shape[1], device=x.device).reshape(1, -1, 1).repeat(x.shape[0], 1, 3)
+ ids = torch.cat((txt_ids, img_ids), dim=1)
+ image_rotary_emb = base_model.pe_embedder(ids).to(x.dtype).contiguous()
+
+ hidden_states = base_model.img_in(hidden_states)
+ encoder_hidden_states = base_model.txt_norm(context)
+ encoder_hidden_states = base_model.txt_in(encoder_hidden_states)
+
+ if guidance is not None:
+ guidance = guidance * 1000
+
+ temb = (
+ base_model.time_text_embed(timesteps, hidden_states)
+ if guidance is None
+ else base_model.time_text_embed(timesteps, guidance, hidden_states)
+ )
+
+ c = self.control_img_in(hint_tokens)
+
+ for i, block in enumerate(self.control_blocks):
+ if i == 0:
+ c_in = block.before_proj(c) + hidden_states
+ all_c = []
+ else:
+ all_c = list(torch.unbind(c, dim=0))
+ c_in = all_c.pop(-1)
+
+ encoder_hidden_states, c_out = block(
+ hidden_states=c_in,
+ encoder_hidden_states=encoder_hidden_states,
+ encoder_hidden_states_mask=encoder_hidden_states_mask,
+ temb=temb,
+ image_rotary_emb=image_rotary_emb,
+ transformer_options=transformer_options,
+ )
+
+ c_skip = block.after_proj(c_out) * self.hint_scale
+ all_c += [c_skip, c_out]
+ c = torch.stack(all_c, dim=0)
+
+ hints = torch.unbind(c, dim=0)[:-1]
+
+ controlnet_block_samples = [None] * self.main_model_double
+ for local_idx, base_idx in enumerate(self.injection_layers):
+ if local_idx < len(hints) and base_idx < len(controlnet_block_samples):
+ controlnet_block_samples[base_idx] = hints[local_idx]
+
+ return {"input": controlnet_block_samples}
+
+
+class QwenImageControlNetModel(QwenImageTransformer2DModel):
+ def __init__(
+ self,
+ extra_condition_channels=0,
+ dtype=None,
+ device=None,
+ operations=None,
+ **kwargs
+ ):
+ super().__init__(final_layer=False, dtype=dtype, device=device, operations=operations, **kwargs)
+ self.main_model_double = 60
+
+ # controlnet_blocks
+ self.controlnet_blocks = torch.nn.ModuleList([])
+ for _ in range(len(self.transformer_blocks)):
+ self.controlnet_blocks.append(operations.Linear(self.inner_dim, self.inner_dim, device=device, dtype=dtype))
+ self.controlnet_x_embedder = operations.Linear(self.in_channels + extra_condition_channels, self.inner_dim, device=device, dtype=dtype)
+
+ def forward(
+ self,
+ x,
+ timesteps,
+ context,
+ attention_mask=None,
+ guidance: torch.Tensor = None,
+ ref_latents=None,
+ hint=None,
+ transformer_options={},
+ **kwargs
+ ):
+ timestep = timesteps
+ encoder_hidden_states = context
+ encoder_hidden_states_mask = attention_mask
+
+ hidden_states, img_ids, orig_shape = self.process_img(x)
+ hint, _, _ = self.process_img(hint)
+
+ txt_start = round(max(((x.shape[-1] + (self.patch_size // 2)) // self.patch_size) // 2, ((x.shape[-2] + (self.patch_size // 2)) // self.patch_size) // 2))
+ txt_ids = torch.arange(txt_start, txt_start + context.shape[1], device=x.device).reshape(1, -1, 1).repeat(x.shape[0], 1, 3)
+ ids = torch.cat((txt_ids, img_ids), dim=1)
+ image_rotary_emb = self.pe_embedder(ids).to(x.dtype).contiguous()
+ del ids, txt_ids, img_ids
+
+ hidden_states = self.img_in(hidden_states) + self.controlnet_x_embedder(hint)
+ encoder_hidden_states = self.txt_norm(encoder_hidden_states)
+ encoder_hidden_states = self.txt_in(encoder_hidden_states)
+
+ if guidance is not None:
+ guidance = guidance * 1000
+
+ temb = (
+ self.time_text_embed(timestep, hidden_states)
+ if guidance is None
+ else self.time_text_embed(timestep, guidance, hidden_states)
+ )
+
+ repeat = math.ceil(self.main_model_double / len(self.controlnet_blocks))
+
+ controlnet_block_samples = ()
+ for i, block in enumerate(self.transformer_blocks):
+ encoder_hidden_states, hidden_states = block(
+ hidden_states=hidden_states,
+ encoder_hidden_states=encoder_hidden_states,
+ encoder_hidden_states_mask=encoder_hidden_states_mask,
+ temb=temb,
+ image_rotary_emb=image_rotary_emb,
+ )
+
+ controlnet_block_samples = controlnet_block_samples + (self.controlnet_blocks[i](hidden_states),) * repeat
+
+ return {"input": controlnet_block_samples[:self.main_model_double]}
diff --git a/ComfyUI/comfy/ldm/qwen_image/model.py b/ComfyUI/comfy/ldm/qwen_image/model.py
new file mode 100644
index 0000000000000000000000000000000000000000..e49886dd9931823e0c588782b4dba31cdd44e220
--- /dev/null
+++ b/ComfyUI/comfy/ldm/qwen_image/model.py
@@ -0,0 +1,568 @@
+# https://github.com/QwenLM/Qwen-Image (Apache 2.0)
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+from typing import Optional, Tuple
+from einops import repeat
+
+from comfy.ldm.lightricks.model import TimestepEmbedding, Timesteps
+from comfy.ldm.modules.attention import optimized_attention_masked
+from comfy.ldm.flux.layers import EmbedND
+import comfy.ldm.common_dit
+import comfy.patcher_extension
+from comfy.ldm.flux.math import apply_rope1
+
+class GELU(nn.Module):
+ def __init__(self, dim_in: int, dim_out: int, approximate: str = "none", bias: bool = True, dtype=None, device=None, operations=None):
+ super().__init__()
+ self.proj = operations.Linear(dim_in, dim_out, bias=bias, dtype=dtype, device=device)
+ self.approximate = approximate
+
+ def forward(self, hidden_states):
+ hidden_states = self.proj(hidden_states)
+ hidden_states = F.gelu(hidden_states, approximate=self.approximate)
+ return hidden_states
+
+
+class FeedForward(nn.Module):
+ def __init__(
+ self,
+ dim: int,
+ dim_out: Optional[int] = None,
+ mult: int = 4,
+ dropout: float = 0.0,
+ inner_dim=None,
+ bias: bool = True,
+ dtype=None, device=None, operations=None
+ ):
+ super().__init__()
+ if inner_dim is None:
+ inner_dim = int(dim * mult)
+ dim_out = dim_out if dim_out is not None else dim
+
+ self.net = nn.ModuleList([])
+ self.net.append(GELU(dim, inner_dim, approximate="tanh", bias=bias, dtype=dtype, device=device, operations=operations))
+ self.net.append(nn.Dropout(dropout))
+ self.net.append(operations.Linear(inner_dim, dim_out, bias=bias, dtype=dtype, device=device))
+
+ def forward(self, hidden_states: torch.Tensor, *args, **kwargs) -> torch.Tensor:
+ for module in self.net:
+ hidden_states = module(hidden_states)
+ return hidden_states
+
+
+# Addin this back because Nunchaku custom nodes rely on it, see comment here:
+# https://github.com/Comfy-Org/ComfyUI/pull/14178#issuecomment-4640475161
+# TODO: Eventually remove this once we natively support SVDQuants
+def apply_rotary_emb(x, freqs_cis):
+ if x.shape[1] == 0:
+ return x
+
+ t_ = x.reshape(*x.shape[:-1], -1, 1, 2)
+ t_out = freqs_cis[..., 0] * t_[..., 0] + freqs_cis[..., 1] * t_[..., 1]
+ return t_out.reshape(*x.shape)
+
+
+class QwenTimestepProjEmbeddings(nn.Module):
+ def __init__(self, embedding_dim, pooled_projection_dim, use_additional_t_cond=False, dtype=None, device=None, operations=None):
+ super().__init__()
+ self.time_proj = Timesteps(num_channels=256, flip_sin_to_cos=True, downscale_freq_shift=0, scale=1000)
+ self.timestep_embedder = TimestepEmbedding(
+ in_channels=256,
+ time_embed_dim=embedding_dim,
+ dtype=dtype,
+ device=device,
+ operations=operations
+ )
+
+ self.use_additional_t_cond = use_additional_t_cond
+ if self.use_additional_t_cond:
+ self.addition_t_embedding = operations.Embedding(2, embedding_dim, device=device, dtype=dtype)
+
+ def forward(self, timestep, hidden_states, addition_t_cond=None):
+ timesteps_proj = self.time_proj(timestep)
+ timesteps_emb = self.timestep_embedder(timesteps_proj.to(dtype=hidden_states.dtype))
+
+ if self.use_additional_t_cond:
+ if addition_t_cond is None:
+ addition_t_cond = torch.zeros((timesteps_emb.shape[0]), device=timesteps_emb.device, dtype=torch.long)
+ timesteps_emb += self.addition_t_embedding(addition_t_cond, out_dtype=timesteps_emb.dtype)
+
+ return timesteps_emb
+
+
+class Attention(nn.Module):
+ def __init__(
+ self,
+ query_dim: int,
+ dim_head: int = 64,
+ heads: int = 8,
+ dropout: float = 0.0,
+ bias: bool = False,
+ eps: float = 1e-5,
+ out_bias: bool = True,
+ out_dim: int = None,
+ out_context_dim: int = None,
+ dtype=None,
+ device=None,
+ operations=None
+ ):
+ super().__init__()
+ self.inner_dim = out_dim if out_dim is not None else dim_head * heads
+ self.inner_kv_dim = self.inner_dim
+ self.heads = heads
+ self.dim_head = dim_head
+ self.out_dim = out_dim if out_dim is not None else query_dim
+ self.out_context_dim = out_context_dim if out_context_dim is not None else query_dim
+ self.dropout = dropout
+
+ # Q/K normalization
+ self.norm_q = operations.RMSNorm(dim_head, eps=eps, elementwise_affine=True, dtype=dtype, device=device)
+ self.norm_k = operations.RMSNorm(dim_head, eps=eps, elementwise_affine=True, dtype=dtype, device=device)
+ self.norm_added_q = operations.RMSNorm(dim_head, eps=eps, dtype=dtype, device=device)
+ self.norm_added_k = operations.RMSNorm(dim_head, eps=eps, dtype=dtype, device=device)
+
+ # Image stream projections
+ self.to_q = operations.Linear(query_dim, self.inner_dim, bias=bias, dtype=dtype, device=device)
+ self.to_k = operations.Linear(query_dim, self.inner_kv_dim, bias=bias, dtype=dtype, device=device)
+ self.to_v = operations.Linear(query_dim, self.inner_kv_dim, bias=bias, dtype=dtype, device=device)
+
+ # Text stream projections
+ self.add_q_proj = operations.Linear(query_dim, self.inner_dim, bias=bias, dtype=dtype, device=device)
+ self.add_k_proj = operations.Linear(query_dim, self.inner_kv_dim, bias=bias, dtype=dtype, device=device)
+ self.add_v_proj = operations.Linear(query_dim, self.inner_kv_dim, bias=bias, dtype=dtype, device=device)
+
+ # Output projections
+ self.to_out = nn.ModuleList([
+ operations.Linear(self.inner_dim, self.out_dim, bias=out_bias, dtype=dtype, device=device),
+ nn.Dropout(dropout)
+ ])
+ self.to_add_out = operations.Linear(self.inner_dim, self.out_context_dim, bias=out_bias, dtype=dtype, device=device)
+
+ def forward(
+ self,
+ hidden_states: torch.FloatTensor, # Image stream
+ encoder_hidden_states: torch.FloatTensor = None, # Text stream
+ encoder_hidden_states_mask: torch.FloatTensor = None,
+ attention_mask: Optional[torch.FloatTensor] = None,
+ image_rotary_emb: Optional[torch.Tensor] = None,
+ transformer_options={},
+ ) -> Tuple[torch.Tensor, torch.Tensor]:
+ batch_size = hidden_states.shape[0]
+ seq_img = hidden_states.shape[1]
+ seq_txt = encoder_hidden_states.shape[1]
+
+ transformer_patches = transformer_options.get("patches", {})
+ extra_options = transformer_options.copy()
+
+ # Project and reshape to BHND format (batch, heads, seq, dim)
+ img_query = self.to_q(hidden_states).view(batch_size, seq_img, self.heads, -1).transpose(1, 2).contiguous()
+ img_key = self.to_k(hidden_states).view(batch_size, seq_img, self.heads, -1).transpose(1, 2).contiguous()
+ img_value = self.to_v(hidden_states).view(batch_size, seq_img, self.heads, -1).transpose(1, 2)
+
+ txt_query = self.add_q_proj(encoder_hidden_states).view(batch_size, seq_txt, self.heads, -1).transpose(1, 2).contiguous()
+ txt_key = self.add_k_proj(encoder_hidden_states).view(batch_size, seq_txt, self.heads, -1).transpose(1, 2).contiguous()
+ txt_value = self.add_v_proj(encoder_hidden_states).view(batch_size, seq_txt, self.heads, -1).transpose(1, 2)
+
+ img_query = self.norm_q(img_query)
+ img_key = self.norm_k(img_key)
+ txt_query = self.norm_added_q(txt_query)
+ txt_key = self.norm_added_k(txt_key)
+
+ joint_query = torch.cat([txt_query, img_query], dim=2)
+ joint_key = torch.cat([txt_key, img_key], dim=2)
+ joint_value = torch.cat([txt_value, img_value], dim=2)
+
+ if encoder_hidden_states_mask is not None:
+ attn_mask = torch.zeros((batch_size, 1, seq_txt + seq_img), dtype=hidden_states.dtype, device=hidden_states.device)
+ attn_mask[:, 0, :seq_txt] = encoder_hidden_states_mask
+ else:
+ attn_mask = None
+
+ extra_options["img_slice"] = [txt_query.shape[2], joint_query.shape[2]]
+ if "attn1_patch" in transformer_patches:
+ patch = transformer_patches["attn1_patch"]
+ for p in patch:
+ out = p(joint_query, joint_key, joint_value, pe=image_rotary_emb, attn_mask=encoder_hidden_states_mask, extra_options=extra_options)
+ joint_query, joint_key, joint_value, image_rotary_emb, encoder_hidden_states_mask = out.get("q", joint_query), out.get("k", joint_key), out.get("v", joint_value), out.get("pe", image_rotary_emb), out.get("attn_mask", encoder_hidden_states_mask)
+
+ joint_query = apply_rope1(joint_query, image_rotary_emb)
+ joint_key = apply_rope1(joint_key, image_rotary_emb)
+
+ joint_hidden_states = optimized_attention_masked(joint_query, joint_key, joint_value, self.heads,
+ attn_mask, transformer_options=transformer_options,
+ skip_reshape=True)
+
+ txt_attn_output = joint_hidden_states[:, :seq_txt, :]
+ img_attn_output = joint_hidden_states[:, seq_txt:, :]
+
+ img_attn_output = self.to_out[0](img_attn_output)
+ img_attn_output = self.to_out[1](img_attn_output)
+ txt_attn_output = self.to_add_out(txt_attn_output)
+
+ return img_attn_output, txt_attn_output
+
+
+class QwenImageTransformerBlock(nn.Module):
+ def __init__(
+ self,
+ dim: int,
+ num_attention_heads: int,
+ attention_head_dim: int,
+ eps: float = 1e-6,
+ dtype=None,
+ device=None,
+ operations=None
+ ):
+ super().__init__()
+ self.dim = dim
+ self.num_attention_heads = num_attention_heads
+ self.attention_head_dim = attention_head_dim
+
+ self.img_mod = nn.Sequential(
+ nn.SiLU(),
+ operations.Linear(dim, 6 * dim, bias=True, dtype=dtype, device=device),
+ )
+ self.img_norm1 = operations.LayerNorm(dim, elementwise_affine=False, eps=eps, dtype=dtype, device=device)
+ self.img_norm2 = operations.LayerNorm(dim, elementwise_affine=False, eps=eps, dtype=dtype, device=device)
+ self.img_mlp = FeedForward(dim=dim, dim_out=dim, dtype=dtype, device=device, operations=operations)
+
+ self.txt_mod = nn.Sequential(
+ nn.SiLU(),
+ operations.Linear(dim, 6 * dim, bias=True, dtype=dtype, device=device),
+ )
+ self.txt_norm1 = operations.LayerNorm(dim, elementwise_affine=False, eps=eps, dtype=dtype, device=device)
+ self.txt_norm2 = operations.LayerNorm(dim, elementwise_affine=False, eps=eps, dtype=dtype, device=device)
+ self.txt_mlp = FeedForward(dim=dim, dim_out=dim, dtype=dtype, device=device, operations=operations)
+
+ self.attn = Attention(
+ query_dim=dim,
+ dim_head=attention_head_dim,
+ heads=num_attention_heads,
+ out_dim=dim,
+ bias=True,
+ eps=eps,
+ dtype=dtype,
+ device=device,
+ operations=operations,
+ )
+
+ def _apply_gate(self, x, y, gate, timestep_zero_index=None):
+ if timestep_zero_index is not None:
+ return y + torch.cat((x[:, :timestep_zero_index] * gate[0], x[:, timestep_zero_index:] * gate[1]), dim=1)
+ else:
+ return torch.addcmul(y, gate, x)
+
+ def _modulate(self, x: torch.Tensor, mod_params: torch.Tensor, timestep_zero_index=None) -> Tuple[torch.Tensor, torch.Tensor]:
+ shift, scale, gate = torch.chunk(mod_params, 3, dim=-1)
+ if timestep_zero_index is not None:
+ actual_batch = shift.size(0) // 2
+ shift, shift_0 = shift[:actual_batch], shift[actual_batch:]
+ scale, scale_0 = scale[:actual_batch], scale[actual_batch:]
+ gate, gate_0 = gate[:actual_batch], gate[actual_batch:]
+ reg = torch.addcmul(shift.unsqueeze(1), x[:, :timestep_zero_index], 1 + scale.unsqueeze(1))
+ zero = torch.addcmul(shift_0.unsqueeze(1), x[:, timestep_zero_index:], 1 + scale_0.unsqueeze(1))
+ return torch.cat((reg, zero), dim=1), (gate.unsqueeze(1), gate_0.unsqueeze(1))
+ else:
+ return torch.addcmul(shift.unsqueeze(1), x, 1 + scale.unsqueeze(1)), gate.unsqueeze(1)
+
+ def forward(
+ self,
+ hidden_states: torch.Tensor,
+ encoder_hidden_states: torch.Tensor,
+ encoder_hidden_states_mask: torch.Tensor,
+ temb: torch.Tensor,
+ image_rotary_emb: Optional[Tuple[torch.Tensor, torch.Tensor]] = None,
+ timestep_zero_index=None,
+ transformer_options={},
+ ) -> Tuple[torch.Tensor, torch.Tensor]:
+ img_mod_params = self.img_mod(temb)
+
+ if timestep_zero_index is not None:
+ temb = temb.chunk(2, dim=0)[0]
+
+ txt_mod_params = self.txt_mod(temb)
+ img_mod1, img_mod2 = img_mod_params.chunk(2, dim=-1)
+ txt_mod1, txt_mod2 = txt_mod_params.chunk(2, dim=-1)
+
+ img_modulated, img_gate1 = self._modulate(self.img_norm1(hidden_states), img_mod1, timestep_zero_index)
+ del img_mod1
+ txt_modulated, txt_gate1 = self._modulate(self.txt_norm1(encoder_hidden_states), txt_mod1)
+ del txt_mod1
+
+ img_attn_output, txt_attn_output = self.attn(
+ hidden_states=img_modulated,
+ encoder_hidden_states=txt_modulated,
+ encoder_hidden_states_mask=encoder_hidden_states_mask,
+ image_rotary_emb=image_rotary_emb,
+ transformer_options=transformer_options,
+ )
+ del img_modulated
+ del txt_modulated
+
+ hidden_states = self._apply_gate(img_attn_output, hidden_states, img_gate1, timestep_zero_index)
+ encoder_hidden_states = encoder_hidden_states + txt_gate1 * txt_attn_output
+ del img_attn_output
+ del txt_attn_output
+ del img_gate1
+ del txt_gate1
+
+ img_modulated2, img_gate2 = self._modulate(self.img_norm2(hidden_states), img_mod2, timestep_zero_index)
+ hidden_states = self._apply_gate(self.img_mlp(img_modulated2), hidden_states, img_gate2, timestep_zero_index)
+
+ txt_modulated2, txt_gate2 = self._modulate(self.txt_norm2(encoder_hidden_states), txt_mod2)
+ encoder_hidden_states = torch.addcmul(encoder_hidden_states, txt_gate2, self.txt_mlp(txt_modulated2))
+
+ return encoder_hidden_states, hidden_states
+
+
+class LastLayer(nn.Module):
+ def __init__(
+ self,
+ embedding_dim: int,
+ conditioning_embedding_dim: int,
+ elementwise_affine=False,
+ eps=1e-6,
+ bias=True,
+ dtype=None, device=None, operations=None
+ ):
+ super().__init__()
+ self.silu = nn.SiLU()
+ self.linear = operations.Linear(conditioning_embedding_dim, embedding_dim * 2, bias=bias, dtype=dtype, device=device)
+ self.norm = operations.LayerNorm(embedding_dim, eps, elementwise_affine=False, bias=bias, dtype=dtype, device=device)
+
+ def forward(self, x: torch.Tensor, conditioning_embedding: torch.Tensor) -> torch.Tensor:
+ emb = self.linear(self.silu(conditioning_embedding))
+ scale, shift = torch.chunk(emb, 2, dim=1)
+ x = torch.addcmul(shift[:, None, :], self.norm(x), (1 + scale)[:, None, :])
+ return x
+
+
+class QwenImageTransformer2DModel(nn.Module):
+ def __init__(
+ self,
+ patch_size: int = 2,
+ in_channels: int = 64,
+ out_channels: Optional[int] = 16,
+ num_layers: int = 60,
+ attention_head_dim: int = 128,
+ num_attention_heads: int = 24,
+ joint_attention_dim: int = 3584,
+ pooled_projection_dim: int = 768,
+ axes_dims_rope: Tuple[int, int, int] = (16, 56, 56),
+ default_ref_method="index",
+ image_model=None,
+ final_layer=True,
+ use_additional_t_cond=False,
+ dtype=None,
+ device=None,
+ operations=None,
+ ):
+ super().__init__()
+ self.dtype = dtype
+ self.patch_size = patch_size
+ self.in_channels = in_channels
+ self.out_channels = out_channels or in_channels
+ self.inner_dim = num_attention_heads * attention_head_dim
+ self.default_ref_method = default_ref_method
+
+ self.pe_embedder = EmbedND(dim=attention_head_dim, theta=10000, axes_dim=list(axes_dims_rope))
+
+ self.time_text_embed = QwenTimestepProjEmbeddings(
+ embedding_dim=self.inner_dim,
+ pooled_projection_dim=pooled_projection_dim,
+ use_additional_t_cond=use_additional_t_cond,
+ dtype=dtype,
+ device=device,
+ operations=operations
+ )
+
+ self.txt_norm = operations.RMSNorm(joint_attention_dim, eps=1e-6, dtype=dtype, device=device)
+ self.img_in = operations.Linear(in_channels, self.inner_dim, dtype=dtype, device=device)
+ self.txt_in = operations.Linear(joint_attention_dim, self.inner_dim, dtype=dtype, device=device)
+
+ self.transformer_blocks = nn.ModuleList([
+ QwenImageTransformerBlock(
+ dim=self.inner_dim,
+ num_attention_heads=num_attention_heads,
+ attention_head_dim=attention_head_dim,
+ dtype=dtype,
+ device=device,
+ operations=operations
+ )
+ for _ in range(num_layers)
+ ])
+
+ if self.default_ref_method == "index_timestep_zero":
+ self.register_buffer("__index_timestep_zero__", torch.tensor([]))
+
+ if final_layer:
+ self.norm_out = LastLayer(self.inner_dim, self.inner_dim, dtype=dtype, device=device, operations=operations)
+ self.proj_out = operations.Linear(self.inner_dim, patch_size * patch_size * self.out_channels, bias=True, dtype=dtype, device=device)
+
+ def process_img(self, x, index=0, h_offset=0, w_offset=0):
+ bs, c, t, h, w = x.shape
+ patch_size = self.patch_size
+ hidden_states = comfy.ldm.common_dit.pad_to_patch_size(x, (1, self.patch_size, self.patch_size))
+ orig_shape = hidden_states.shape
+ hidden_states = hidden_states.view(orig_shape[0], orig_shape[1], orig_shape[-3], orig_shape[-2] // 2, 2, orig_shape[-1] // 2, 2)
+ hidden_states = hidden_states.permute(0, 2, 3, 5, 1, 4, 6)
+ hidden_states = hidden_states.reshape(orig_shape[0], orig_shape[-3] * (orig_shape[-2] // 2) * (orig_shape[-1] // 2), orig_shape[1] * 4)
+ t_len = t
+ h_len = ((h + (patch_size // 2)) // patch_size)
+ w_len = ((w + (patch_size // 2)) // patch_size)
+
+ h_offset = ((h_offset + (patch_size // 2)) // patch_size)
+ w_offset = ((w_offset + (patch_size // 2)) // patch_size)
+
+ img_ids = torch.zeros((t_len, h_len, w_len, 3), device=x.device)
+
+ if t_len > 1:
+ img_ids[:, :, :, 0] = img_ids[:, :, :, 0] + torch.linspace(0, t_len - 1, steps=t_len, device=x.device, dtype=x.dtype).unsqueeze(1).unsqueeze(1)
+ else:
+ img_ids[:, :, :, 0] = img_ids[:, :, :, 0] + index
+
+ img_ids[:, :, :, 1] = img_ids[:, :, :, 1] + torch.linspace(h_offset, h_len - 1 + h_offset, steps=h_len, device=x.device, dtype=x.dtype).unsqueeze(1).unsqueeze(0) - (h_len // 2)
+ img_ids[:, :, :, 2] = img_ids[:, :, :, 2] + torch.linspace(w_offset, w_len - 1 + w_offset, steps=w_len, device=x.device, dtype=x.dtype).unsqueeze(0).unsqueeze(0) - (w_len // 2)
+ return hidden_states, repeat(img_ids, "t h w c -> b (t h w) c", b=bs), orig_shape
+
+ def forward(self, x, timestep, context, attention_mask=None, ref_latents=None, additional_t_cond=None, transformer_options={}, **kwargs):
+ return comfy.patcher_extension.WrapperExecutor.new_class_executor(
+ self._forward,
+ self,
+ comfy.patcher_extension.get_all_wrappers(comfy.patcher_extension.WrappersMP.DIFFUSION_MODEL, transformer_options)
+ ).execute(x, timestep, context, attention_mask, ref_latents, additional_t_cond, transformer_options, **kwargs)
+
+ def _forward(
+ self,
+ x,
+ timesteps,
+ context,
+ attention_mask=None,
+ ref_latents=None,
+ additional_t_cond=None,
+ transformer_options={},
+ control=None,
+ **kwargs
+ ):
+ timestep = timesteps
+ encoder_hidden_states = context
+ encoder_hidden_states_mask = attention_mask
+
+ if encoder_hidden_states_mask is not None and not torch.is_floating_point(encoder_hidden_states_mask):
+ encoder_hidden_states_mask = (encoder_hidden_states_mask - 1).to(x.dtype) * torch.finfo(x.dtype).max
+
+ hidden_states, img_ids, orig_shape = self.process_img(x)
+ num_embeds = hidden_states.shape[1]
+
+ timestep_zero_index = None
+ if ref_latents is not None:
+ ref_num_tokens = []
+ h = 0
+ w = 0
+ index = 0
+ ref_method = kwargs.get("ref_latents_method", self.default_ref_method)
+ index_ref_method = (ref_method == "index") or (ref_method == "index_timestep_zero")
+ negative_ref_method = ref_method == "negative_index"
+ timestep_zero = ref_method == "index_timestep_zero"
+ for ref in ref_latents:
+ if index_ref_method:
+ index += 1
+ h_offset = 0
+ w_offset = 0
+ elif negative_ref_method:
+ index -= 1
+ h_offset = 0
+ w_offset = 0
+ else:
+ index = 1
+ h_offset = 0
+ w_offset = 0
+ if ref.shape[-2] + h > ref.shape[-1] + w:
+ w_offset = w
+ else:
+ h_offset = h
+ h = max(h, ref.shape[-2] + h_offset)
+ w = max(w, ref.shape[-1] + w_offset)
+
+ kontext, kontext_ids, _ = self.process_img(ref, index=index, h_offset=h_offset, w_offset=w_offset)
+ hidden_states = torch.cat([hidden_states, kontext], dim=1)
+ img_ids = torch.cat([img_ids, kontext_ids], dim=1)
+ ref_num_tokens.append(kontext.shape[1])
+ if timestep_zero:
+ if index > 0:
+ timestep = torch.cat([timestep, timestep * 0], dim=0)
+ timestep_zero_index = num_embeds
+ transformer_options = transformer_options.copy()
+ transformer_options["reference_image_num_tokens"] = ref_num_tokens
+
+ txt_start = round(max(((x.shape[-1] + (self.patch_size // 2)) // self.patch_size) // 2, ((x.shape[-2] + (self.patch_size // 2)) // self.patch_size) // 2))
+ txt_ids = torch.arange(txt_start, txt_start + context.shape[1], device=x.device).reshape(1, -1, 1).repeat(x.shape[0], 1, 3)
+
+ hidden_states = self.img_in(hidden_states)
+ encoder_hidden_states = self.txt_norm(encoder_hidden_states)
+ encoder_hidden_states = self.txt_in(encoder_hidden_states)
+
+ temb = self.time_text_embed(timestep, hidden_states, additional_t_cond)
+
+ patches_replace = transformer_options.get("patches_replace", {})
+ patches = transformer_options.get("patches", {})
+ blocks_replace = patches_replace.get("dit", {})
+
+ if "post_input" in patches:
+ for p in patches["post_input"]:
+ out = p({"img": hidden_states, "txt": encoder_hidden_states, "img_ids": img_ids, "txt_ids": txt_ids, "transformer_options": transformer_options})
+ hidden_states = out["img"]
+ encoder_hidden_states = out["txt"]
+ img_ids = out["img_ids"]
+ txt_ids = out["txt_ids"]
+
+ ids = torch.cat((txt_ids, img_ids), dim=1)
+ image_rotary_emb = self.pe_embedder(ids).to(x.dtype).contiguous()
+ del ids, txt_ids, img_ids
+
+ transformer_options["total_blocks"] = len(self.transformer_blocks)
+ transformer_options["block_type"] = "double"
+ for i, block in enumerate(self.transformer_blocks):
+ transformer_options["block_index"] = i
+ if ("double_block", i) in blocks_replace:
+ def block_wrap(args):
+ out = {}
+ out["txt"], out["img"] = block(hidden_states=args["img"], encoder_hidden_states=args["txt"], encoder_hidden_states_mask=encoder_hidden_states_mask, temb=args["vec"], image_rotary_emb=args["pe"], timestep_zero_index=timestep_zero_index, transformer_options=args["transformer_options"])
+ return out
+ out = blocks_replace[("double_block", i)]({"img": hidden_states, "txt": encoder_hidden_states, "vec": temb, "pe": image_rotary_emb, "transformer_options": transformer_options}, {"original_block": block_wrap})
+ hidden_states = out["img"]
+ encoder_hidden_states = out["txt"]
+ else:
+ encoder_hidden_states, hidden_states = block(
+ hidden_states=hidden_states,
+ encoder_hidden_states=encoder_hidden_states,
+ encoder_hidden_states_mask=encoder_hidden_states_mask,
+ temb=temb,
+ image_rotary_emb=image_rotary_emb,
+ timestep_zero_index=timestep_zero_index,
+ transformer_options=transformer_options,
+ )
+
+ if "double_block" in patches:
+ for p in patches["double_block"]:
+ out = p({"img": hidden_states, "txt": encoder_hidden_states, "x": x, "block_index": i, "transformer_options": transformer_options})
+ hidden_states = out["img"]
+ encoder_hidden_states = out["txt"]
+
+ if control is not None: # Controlnet
+ control_i = control.get("input")
+ if i < len(control_i):
+ add = control_i[i]
+ if add is not None:
+ hidden_states[:, :add.shape[1]] += add
+
+ if timestep_zero_index is not None:
+ temb = temb.chunk(2, dim=0)[0]
+
+ hidden_states = self.norm_out(hidden_states, temb)
+ hidden_states = self.proj_out(hidden_states)
+
+ hidden_states = hidden_states[:, :num_embeds].view(orig_shape[0], orig_shape[-3], orig_shape[-2] // 2, orig_shape[-1] // 2, orig_shape[1], 2, 2)
+ hidden_states = hidden_states.permute(0, 4, 1, 2, 5, 3, 6)
+ return hidden_states.reshape(orig_shape)[:, :, :, :x.shape[-2], :x.shape[-1]]
diff --git a/ComfyUI/comfy/ldm/rt_detr/__pycache__/rtdetr_v4.cpython-312.pyc b/ComfyUI/comfy/ldm/rt_detr/__pycache__/rtdetr_v4.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..587cc6438956d7557781a64545b0fc63ed01827a
Binary files /dev/null and b/ComfyUI/comfy/ldm/rt_detr/__pycache__/rtdetr_v4.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/rt_detr/rtdetr_v4.py b/ComfyUI/comfy/ldm/rt_detr/rtdetr_v4.py
new file mode 100644
index 0000000000000000000000000000000000000000..9443761cb76c27b49ec55dd97759898861eb3fc2
--- /dev/null
+++ b/ComfyUI/comfy/ldm/rt_detr/rtdetr_v4.py
@@ -0,0 +1,725 @@
+from collections import OrderedDict
+from typing import List
+
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+import torchvision
+import comfy.model_management
+from comfy.ldm.modules.attention import optimized_attention_for_device
+
+COCO_CLASSES = [
+ 'person','bicycle','car','motorcycle','airplane','bus','train','truck','boat',
+ 'traffic light','fire hydrant','stop sign','parking meter','bench','bird','cat',
+ 'dog','horse','sheep','cow','elephant','bear','zebra','giraffe','backpack',
+ 'umbrella','handbag','tie','suitcase','frisbee','skis','snowboard','sports ball',
+ 'kite','baseball bat','baseball glove','skateboard','surfboard','tennis racket',
+ 'bottle','wine glass','cup','fork','knife','spoon','bowl','banana','apple',
+ 'sandwich','orange','broccoli','carrot','hot dog','pizza','donut','cake','chair',
+ 'couch','potted plant','bed','dining table','toilet','tv','laptop','mouse',
+ 'remote','keyboard','cell phone','microwave','oven','toaster','sink',
+ 'refrigerator','book','clock','vase','scissors','teddy bear','hair drier','toothbrush',
+]
+
+# ---------------------------------------------------------------------------
+# HGNetv2 backbone
+# ---------------------------------------------------------------------------
+
+class ConvBNAct(nn.Module):
+ """Conv→BN→ReLU. padding='same' adds asymmetric zero-pad (stem)."""
+ def __init__(self, ic, oc, k=3, s=1, groups=1, use_act=True, device=None, dtype=None, operations=None):
+ super().__init__()
+
+ self.conv = operations.Conv2d(ic, oc, k, s, (k - 1) // 2, groups=groups, bias=False, device=device, dtype=dtype)
+ self.bn = nn.BatchNorm2d(oc, device=device, dtype=dtype)
+ self.act = nn.ReLU() if use_act else nn.Identity()
+
+ def forward(self, x):
+ return self.act(self.bn(self.conv(x)))
+
+class LightConvBNAct(nn.Module):
+ def __init__(self, ic, oc, k, device=None, dtype=None, operations=None):
+ super().__init__()
+ self.conv1 = ConvBNAct(ic, oc, 1, use_act=False, device=device, dtype=dtype, operations=operations)
+ self.conv2 = ConvBNAct(oc, oc, k, groups=oc, use_act=True, device=device, dtype=dtype, operations=operations)
+
+ def forward(self, x):
+ return self.conv2(self.conv1(x))
+
+class _StemBlock(nn.Module):
+ def __init__(self, ic, mc, oc, device=None, dtype=None, operations=None):
+ super().__init__()
+ self.stem1 = ConvBNAct(ic, mc, 3, 2, device=device, dtype=dtype, operations=operations)
+ # stem2a/stem2b use kernel=2, stride=1, no internal padding;
+ # padding is applied manually in forward (matching PaddlePaddle original)
+ self.stem2a = ConvBNAct(mc, mc//2, 2, 1, device=device, dtype=dtype, operations=operations)
+ self.stem2b = ConvBNAct(mc//2, mc, 2, 1, device=device, dtype=dtype, operations=operations)
+ self.stem3 = ConvBNAct(mc*2, mc, 3, 2, device=device, dtype=dtype, operations=operations)
+ self.stem4 = ConvBNAct(mc, oc, 1, device=device, dtype=dtype, operations=operations)
+ self.pool = nn.MaxPool2d(2, 1, ceil_mode=True)
+
+ def forward(self, x):
+ x = self.stem1(x)
+ x = F.pad(x, (0, 1, 0, 1)) # pad before pool and stem2a
+ x2 = self.stem2a(x)
+ x2 = F.pad(x2, (0, 1, 0, 1)) # pad before stem2b
+ x2 = self.stem2b(x2)
+ x1 = self.pool(x)
+ return self.stem4(self.stem3(torch.cat([x1, x2], 1)))
+
+
+class _HG_Block(nn.Module):
+ def __init__(self, ic, mc, oc, layer_num, k=3, residual=False, light=False, device=None, dtype=None, operations=None):
+ super().__init__()
+ self.residual = residual
+ if light:
+ self.layers = nn.ModuleList(
+ [LightConvBNAct(ic if i == 0 else mc, mc, k, device=device, dtype=dtype, operations=operations) for i in range(layer_num)])
+ else:
+ self.layers = nn.ModuleList(
+ [ConvBNAct(ic if i == 0 else mc, mc, k, device=device, dtype=dtype, operations=operations) for i in range(layer_num)])
+ total = ic + layer_num * mc
+
+ self.aggregation = nn.Sequential(
+ ConvBNAct(total, oc // 2, 1, device=device, dtype=dtype, operations=operations),
+ ConvBNAct(oc // 2, oc, 1, device=device, dtype=dtype, operations=operations))
+
+ def forward(self, x):
+ identity = x
+ outs = [x]
+ for layer in self.layers:
+ x = layer(x)
+ outs.append(x)
+ x = self.aggregation(torch.cat(outs, 1))
+ return x + identity if self.residual else x
+
+
+class _HG_Stage(nn.Module):
+ # config order: ic, mc, oc, num_blocks, downsample, light, k, layer_num
+ def __init__(self, ic, mc, oc, num_blocks, downsample=True, light=False, k=3, layer_num=6, device=None, dtype=None, operations=None):
+ super().__init__()
+ if downsample:
+ self.downsample = ConvBNAct(ic, ic, 3, 2, groups=ic, use_act=False, device=device, dtype=dtype, operations=operations)
+ else:
+ self.downsample = nn.Identity()
+ self.blocks = nn.Sequential(*[
+ _HG_Block(ic if i == 0 else oc, mc, oc, layer_num,
+ k=k, residual=(i != 0), light=light, device=device, dtype=dtype, operations=operations)
+ for i in range(num_blocks)
+ ])
+
+ def forward(self, x):
+ return self.blocks(self.downsample(x))
+
+
+class HGNetv2(nn.Module):
+ # B5 config: stem=[3,32,64], stages=[ic, mc, oc, blocks, down, light, k, layers]
+ _STAGE_CFGS = [[64, 64, 128, 1, False, False, 3, 6],
+ [128, 128, 512, 2, True, False, 3, 6],
+ [512, 256, 1024, 5, True, True, 5, 6],
+ [1024,512, 2048, 2, True, True, 5, 6]]
+
+ def __init__(self, return_idx=(1, 2, 3), device=None, dtype=None, operations=None):
+ super().__init__()
+ self.stem = _StemBlock(3, 32, 64, device=device, dtype=dtype, operations=operations)
+ self.stages = nn.ModuleList([_HG_Stage(*cfg, device=device, dtype=dtype, operations=operations) for cfg in self._STAGE_CFGS])
+ self.return_idx = list(return_idx)
+ self.out_channels = [self._STAGE_CFGS[i][2] for i in return_idx]
+
+ def forward(self, x: torch.Tensor) -> List[torch.Tensor]:
+ x = self.stem(x)
+ outs = []
+ for i, stage in enumerate(self.stages):
+ x = stage(x)
+ if i in self.return_idx:
+ outs.append(x)
+ return outs
+
+
+# ---------------------------------------------------------------------------
+# Encoder — HybridEncoder (dfine version: RepNCSPELAN4 + SCDown PAN)
+# ---------------------------------------------------------------------------
+
+class ConvNormLayer(nn.Module):
+ """Conv→act (expects pre-fused BN weights)."""
+ def __init__(self, ic, oc, k, s, g=1, padding=None, act=None, device=None, dtype=None, operations=None):
+ super().__init__()
+ p = (k - 1) // 2 if padding is None else padding
+ self.conv = operations.Conv2d(ic, oc, k, s, p, groups=g, bias=True, device=device, dtype=dtype)
+ self.act = nn.SiLU() if act == 'silu' else nn.Identity()
+
+ def forward(self, x):
+ return self.act(self.conv(x))
+
+
+class VGGBlock(nn.Module):
+ """Rep-VGG block (expects pre-fused weights)."""
+ def __init__(self, ic, oc, device=None, dtype=None, operations=None):
+ super().__init__()
+ self.conv = operations.Conv2d(ic, oc, 3, 1, padding=1, bias=True, device=device, dtype=dtype)
+ self.act = nn.SiLU()
+
+ def forward(self, x):
+ return self.act(self.conv(x))
+
+
+class CSPLayer(nn.Module):
+ def __init__(self, ic, oc, num_blocks=3, expansion=1.0, act='silu', device=None, dtype=None, operations=None):
+ super().__init__()
+ h = int(oc * expansion)
+ self.conv1 = ConvNormLayer(ic, h, 1, 1, act=act, device=device, dtype=dtype, operations=operations)
+ self.conv2 = ConvNormLayer(ic, h, 1, 1, act=act, device=device, dtype=dtype, operations=operations)
+ self.bottlenecks = nn.Sequential(*[VGGBlock(h, h, device=device, dtype=dtype, operations=operations) for _ in range(num_blocks)])
+ self.conv3 = ConvNormLayer(h, oc, 1, 1, act=act, device=device, dtype=dtype, operations=operations) if h != oc else nn.Identity()
+
+ def forward(self, x):
+ return self.conv3(self.bottlenecks(self.conv1(x)) + self.conv2(x))
+
+
+class RepNCSPELAN4(nn.Module):
+ """CSP-ELAN block — the FPN/PAN block in RTv4's HybridEncoder."""
+ def __init__(self, c1, c2, c3, c4, n=3, act='silu', device=None, dtype=None, operations=None):
+ super().__init__()
+ self.c = c3 // 2
+ self.cv1 = ConvNormLayer(c1, c3, 1, 1, act=act, device=device, dtype=dtype, operations=operations)
+ self.cv2 = nn.Sequential(CSPLayer(c3 // 2, c4, n, 1.0, act=act, device=device, dtype=dtype, operations=operations), ConvNormLayer(c4, c4, 3, 1, act=act, device=device, dtype=dtype, operations=operations))
+ self.cv3 = nn.Sequential(CSPLayer(c4, c4, n, 1.0, act=act, device=device, dtype=dtype, operations=operations), ConvNormLayer(c4, c4, 3, 1, act=act, device=device, dtype=dtype, operations=operations))
+ self.cv4 = ConvNormLayer(c3 + 2 * c4, c2, 1, 1, act=act, device=device, dtype=dtype, operations=operations)
+
+ def forward(self, x):
+ y = list(self.cv1(x).split((self.c, self.c), 1))
+ y.extend(m(y[-1]) for m in [self.cv2, self.cv3])
+ return self.cv4(torch.cat(y, 1))
+
+
+class SCDown(nn.Module):
+ """Separable conv downsampling used in HybridEncoder PAN bottom-up path."""
+ def __init__(self, ic, oc, k, s, device=None, dtype=None, operations=None):
+ super().__init__()
+ self.cv1 = ConvNormLayer(ic, oc, 1, 1, device=device, dtype=dtype, operations=operations)
+ self.cv2 = ConvNormLayer(oc, oc, k, s, g=oc, device=device, dtype=dtype, operations=operations)
+
+ def forward(self, x):
+ return self.cv2(self.cv1(x))
+
+
+class SelfAttention(nn.Module):
+ def __init__(self, embed_dim, num_heads, device=None, dtype=None, operations=None):
+ super().__init__()
+ self.embed_dim = embed_dim
+ self.num_heads = num_heads
+ self.head_dim = embed_dim // num_heads
+ self.q_proj = operations.Linear(embed_dim, embed_dim, device=device, dtype=dtype)
+ self.k_proj = operations.Linear(embed_dim, embed_dim, device=device, dtype=dtype)
+ self.v_proj = operations.Linear(embed_dim, embed_dim, device=device, dtype=dtype)
+ self.out_proj = operations.Linear(embed_dim, embed_dim, device=device, dtype=dtype)
+
+ def forward(self, query, key, value, attn_mask=None):
+ optimized_attention = optimized_attention_for_device(query.device, False, small_input=True)
+ q, k, v = self.q_proj(query), self.k_proj(key), self.v_proj(value)
+ out = optimized_attention(q, k, v, heads=self.num_heads, mask=attn_mask)
+ return self.out_proj(out)
+
+
+class _TransformerEncoderLayer(nn.Module):
+ """Single AIFI encoder layer (pre- or post-norm, GELU by default)."""
+ def __init__(self, d_model, nhead, dim_feedforward, device=None, dtype=None, operations=None):
+ super().__init__()
+ self.self_attn = SelfAttention(d_model, nhead, device=device, dtype=dtype, operations=operations)
+ self.linear1 = operations.Linear(d_model, dim_feedforward, device=device, dtype=dtype)
+ self.linear2 = operations.Linear(dim_feedforward, d_model, device=device, dtype=dtype)
+ self.norm1 = operations.LayerNorm(d_model, device=device, dtype=dtype)
+ self.norm2 = operations.LayerNorm(d_model, device=device, dtype=dtype)
+ self.activation = nn.GELU()
+
+ def forward(self, src, src_mask=None, pos_embed=None):
+ q = k = src if pos_embed is None else src + pos_embed
+ src2 = self.self_attn(q, k, value=src, attn_mask=src_mask)
+ src = self.norm1(src + src2)
+ src2 = self.linear2(self.activation(self.linear1(src)))
+ return self.norm2(src + src2)
+
+
+class _TransformerEncoder(nn.Module):
+ """Thin wrapper so state-dict keys are encoder.0.layers.N.*"""
+ def __init__(self, num_layers, d_model, nhead, dim_feedforward, device=None, dtype=None, operations=None):
+ super().__init__()
+ self.layers = nn.ModuleList([
+ _TransformerEncoderLayer(d_model, nhead, dim_feedforward, device=device, dtype=dtype, operations=operations)
+ for _ in range(num_layers)
+ ])
+
+ def forward(self, src, src_mask=None, pos_embed=None):
+ for layer in self.layers:
+ src = layer(src, src_mask=src_mask, pos_embed=pos_embed)
+ return src
+
+
+class HybridEncoder(nn.Module):
+ def __init__(self, in_channels=(512, 1024, 2048), feat_strides=(8, 16, 32), hidden_dim=256, nhead=8, dim_feedforward=2048, use_encoder_idx=(2,), num_encoder_layers=1,
+ pe_temperature=10000, expansion=1.0, depth_mult=1.0, act='silu', eval_spatial_size=(640, 640), device=None, dtype=None, operations=None):
+ super().__init__()
+ self.in_channels = list(in_channels)
+ self.feat_strides = list(feat_strides)
+ self.hidden_dim = hidden_dim
+ self.use_encoder_idx = list(use_encoder_idx)
+ self.pe_temperature = pe_temperature
+ self.eval_spatial_size = eval_spatial_size
+ self.out_channels = [hidden_dim] * len(in_channels)
+ self.out_strides = list(feat_strides)
+
+ # channel projection (expects pre-fused weights)
+ self.input_proj = nn.ModuleList([
+ nn.Sequential(OrderedDict([('conv', operations.Conv2d(ch, hidden_dim, 1, bias=True, device=device, dtype=dtype))]))
+ for ch in in_channels
+ ])
+
+ # AIFI transformer — use _TransformerEncoder so keys are encoder.0.layers.N.*
+ self.encoder = nn.ModuleList([
+ _TransformerEncoder(num_encoder_layers, hidden_dim, nhead, dim_feedforward, device=device, dtype=dtype, operations=operations)
+ for _ in range(len(use_encoder_idx))
+ ])
+
+ nb = round(3 * depth_mult)
+ exp = expansion
+
+ # top-down FPN (dfine: lateral conv has no act)
+ self.lateral_convs = nn.ModuleList(
+ [ConvNormLayer(hidden_dim, hidden_dim, 1, 1, device=device, dtype=dtype, operations=operations)
+ for _ in range(len(in_channels) - 1)])
+ self.fpn_blocks = nn.ModuleList(
+ [RepNCSPELAN4(hidden_dim * 2, hidden_dim, hidden_dim * 2, round(exp * hidden_dim // 2), nb, act=act, device=device, dtype=dtype, operations=operations)
+ for _ in range(len(in_channels) - 1)])
+
+ # bottom-up PAN (dfine: nn.Sequential(SCDown) — keeps checkpoint key .0.cv1/.0.cv2)
+ self.downsample_convs = nn.ModuleList(
+ [nn.Sequential(SCDown(hidden_dim, hidden_dim, 3, 2, device=device, dtype=dtype, operations=operations))
+ for _ in range(len(in_channels) - 1)])
+ self.pan_blocks = nn.ModuleList(
+ [RepNCSPELAN4(hidden_dim * 2, hidden_dim, hidden_dim * 2, round(exp * hidden_dim // 2), nb, act=act, device=device, dtype=dtype, operations=operations)
+ for _ in range(len(in_channels) - 1)])
+
+ # cache positional embeddings for fixed spatial size
+ if eval_spatial_size:
+ for idx in self.use_encoder_idx:
+ stride = self.feat_strides[idx]
+ pe = self._build_pe(eval_spatial_size[1] // stride,
+ eval_spatial_size[0] // stride,
+ hidden_dim, pe_temperature)
+ setattr(self, f'pos_embed{idx}', pe)
+
+ @staticmethod
+ def _build_pe(w, h, dim=256, temp=10000.):
+ assert dim % 4 == 0
+ gw = torch.arange(w, dtype=torch.float32)
+ gh = torch.arange(h, dtype=torch.float32)
+ gw, gh = torch.meshgrid(gw, gh, indexing='ij')
+ pdim = dim // 4
+ omega = 1. / (temp ** (torch.arange(pdim, dtype=torch.float32) / pdim))
+ ow = gw.flatten()[:, None] @ omega[None]
+ oh = gh.flatten()[:, None] @ omega[None]
+ return torch.cat([ow.sin(), ow.cos(), oh.sin(), oh.cos()], 1)[None]
+
+ def forward(self, feats: List[torch.Tensor]) -> List[torch.Tensor]:
+ proj = [self.input_proj[i](f) for i, f in enumerate(feats)]
+
+ for i, enc_idx in enumerate(self.use_encoder_idx):
+ h, w = proj[enc_idx].shape[2:]
+ src = proj[enc_idx].flatten(2).permute(0, 2, 1)
+ pe = getattr(self, f'pos_embed{enc_idx}').to(device=src.device, dtype=src.dtype)
+ for layer in self.encoder[i].layers:
+ src = layer(src, pos_embed=pe)
+ proj[enc_idx] = src.permute(0, 2, 1).reshape(-1, self.hidden_dim, h, w).contiguous()
+
+ n = len(self.in_channels)
+ inner = [proj[-1]]
+ for k in range(n - 1, 0, -1):
+ j = n - 1 - k
+ top = self.lateral_convs[j](inner[0])
+ inner[0] = top
+ up = F.interpolate(top, scale_factor=2., mode='nearest')
+ inner.insert(0, self.fpn_blocks[j](torch.cat([up, proj[k - 1]], 1)))
+
+ outs = [inner[0]]
+ for k in range(n - 1):
+ outs.append(self.pan_blocks[k](
+ torch.cat([self.downsample_convs[k](outs[-1]), inner[k + 1]], 1)))
+ return outs
+
+
+# ---------------------------------------------------------------------------
+# Decoder — DFINETransformer
+# ---------------------------------------------------------------------------
+
+def _deformable_attn_v2(value: list, spatial_shapes, sampling_locations: torch.Tensor, attention_weights: torch.Tensor, num_points_list: List[int]) -> torch.Tensor:
+ """
+ value : list of per-level tensors [bs*n_head, c, h_l, w_l]
+ sampling_locations: [bs, Lq, n_head, sum(pts), 2] in [0,1]
+ attention_weights : [bs, Lq, n_head, sum(pts)]
+ """
+ _, c = value[0].shape[:2] # bs*n_head, c
+ _, Lq, n_head, _, _ = sampling_locations.shape
+ bs = sampling_locations.shape[0]
+ n_h = n_head
+
+ grids = (2 * sampling_locations - 1) # [bs, Lq, n_head, sum_pts, 2]
+ grids = grids.permute(0, 2, 1, 3, 4).flatten(0, 1) # [bs*n_head, Lq, sum_pts, 2]
+ grids_per_lvl = grids.split(num_points_list, dim=2) # list of [bs*n_head, Lq, pts_l, 2]
+
+ sampled = []
+ for lvl, (h, w) in enumerate(spatial_shapes):
+ val_l = value[lvl].reshape(bs * n_h, c, h, w)
+ sv = F.grid_sample(val_l, grids_per_lvl[lvl], mode='bilinear', padding_mode='zeros', align_corners=False)
+ sampled.append(sv) # sv: [bs*n_head, c, Lq, pts_l]
+
+ attn = attention_weights.permute(0, 2, 1, 3) # [bs, n_head, Lq, sum_pts]
+ attn = attn.flatten(0, 1).unsqueeze(1) # [bs*n_head, 1, Lq, sum_pts]
+ out = (torch.cat(sampled, -1) * attn).sum(-1) # [bs*n_head, c, Lq]
+ out = out.reshape(bs, n_h * c, Lq)
+ return out.permute(0, 2, 1) # [bs, Lq, hidden]
+
+
+class MSDeformableAttention(nn.Module):
+ def __init__(self, embed_dim=256, num_heads=8, num_levels=3, num_points=4, offset_scale=0.5, device=None, dtype=None, operations=None):
+ super().__init__()
+ self.embed_dim, self.num_heads = embed_dim, num_heads
+ self.head_dim = embed_dim // num_heads
+ pts = num_points if isinstance(num_points, list) else [num_points] * num_levels
+ self.num_points_list = pts
+ self.offset_scale = offset_scale
+ total = num_heads * sum(pts)
+ self.register_buffer('num_points_scale', torch.tensor([1. / n for n in pts for _ in range(n)], dtype=torch.float32))
+ self.sampling_offsets = operations.Linear(embed_dim, total * 2, device=device, dtype=dtype)
+ self.attention_weights = operations.Linear(embed_dim, total, device=device, dtype=dtype)
+
+ def forward(self, query, ref_pts, value, spatial_shapes):
+ bs, Lq = query.shape[:2]
+ offsets = self.sampling_offsets(query).reshape(
+ bs, Lq, self.num_heads, sum(self.num_points_list), 2)
+ attn_w = F.softmax(
+ self.attention_weights(query).reshape(
+ bs, Lq, self.num_heads, sum(self.num_points_list)), -1)
+ scale = self.num_points_scale.to(query).unsqueeze(-1)
+ offset = offsets * scale * ref_pts[:, :, None, :, 2:] * self.offset_scale
+ locs = ref_pts[:, :, None, :, :2] + offset # [bs, Lq, n_head, sum_pts, 2]
+ return _deformable_attn_v2(value, spatial_shapes, locs, attn_w, self.num_points_list)
+
+
+class Gate(nn.Module):
+ def __init__(self, d_model, device=None, dtype=None, operations=None):
+ super().__init__()
+ self.gate = operations.Linear(2 * d_model, 2 * d_model, device=device, dtype=dtype)
+ self.norm = operations.LayerNorm(d_model, device=device, dtype=dtype)
+
+ def forward(self, x1, x2):
+ g1, g2 = torch.sigmoid(self.gate(torch.cat([x1, x2], -1))).chunk(2, -1)
+ return self.norm(g1 * x1 + g2 * x2)
+
+
+class MLP(nn.Module):
+ def __init__(self, in_dim, hidden_dim, out_dim, num_layers, device=None, dtype=None, operations=None):
+ super().__init__()
+ dims = [in_dim] + [hidden_dim] * (num_layers - 1) + [out_dim]
+ self.layers = nn.ModuleList(operations.Linear(dims[i], dims[i + 1], device=device, dtype=dtype) for i in range(num_layers))
+
+ def forward(self, x):
+ for i, layer in enumerate(self.layers):
+ x = nn.SiLU()(layer(x)) if i < len(self.layers) - 1 else layer(x)
+ return x
+
+
+class TransformerDecoderLayer(nn.Module):
+ def __init__(self, d_model=256, nhead=8, dim_feedforward=1024, num_levels=3, num_points=4, device=None, dtype=None, operations=None):
+ super().__init__()
+ self.self_attn = SelfAttention(d_model, nhead, device=device, dtype=dtype, operations=operations)
+ self.norm1 = operations.LayerNorm(d_model, device=device, dtype=dtype)
+ self.cross_attn = MSDeformableAttention(d_model, nhead, num_levels, num_points, device=device, dtype=dtype, operations=operations)
+ self.gateway = Gate(d_model, device=device, dtype=dtype, operations=operations)
+ self.linear1 = operations.Linear(d_model, dim_feedforward, device=device, dtype=dtype)
+ self.activation = nn.ReLU()
+ self.linear2 = operations.Linear(dim_feedforward, d_model, device=device, dtype=dtype)
+ self.norm3 = operations.LayerNorm(d_model, device=device, dtype=dtype)
+
+ def forward(self, target, ref_pts, value, spatial_shapes, attn_mask=None, query_pos=None):
+ q = k = target if query_pos is None else target + query_pos
+ t2 = self.self_attn(q, k, value=target, attn_mask=attn_mask)
+ target = self.norm1(target + t2)
+ t2 = self.cross_attn(
+ target if query_pos is None else target + query_pos,
+ ref_pts, value, spatial_shapes)
+ target = self.gateway(target, t2)
+ t2 = self.linear2(self.activation(self.linear1(target)))
+ target = self.norm3((target + t2).clamp(-65504, 65504))
+ return target
+
+
+# ---------------------------------------------------------------------------
+# FDR utilities
+# ---------------------------------------------------------------------------
+
+def weighting_function(reg_max, up, reg_scale):
+ """Non-uniform weighting function W(n) for FDR box regression."""
+ ub1 = (abs(up[0]) * abs(reg_scale)).item()
+ ub2 = ub1 * 2
+ step = (ub1 + 1) ** (2 / (reg_max - 2))
+ left = [-(step ** i) + 1 for i in range(reg_max // 2 - 1, 0, -1)]
+ right = [ (step ** i) - 1 for i in range(1, reg_max // 2)]
+ vals = [-ub2] + left + [0] + right + [ub2]
+ return torch.tensor(vals, dtype=up.dtype, device=up.device)
+
+
+def distance2bbox(points, distance, reg_scale):
+ """Decode edge-distances → cxcywh boxes."""
+ rs = abs(reg_scale).to(dtype=points.dtype)
+ x1 = points[..., 0] - (0.5 * rs + distance[..., 0]) * (points[..., 2] / rs)
+ y1 = points[..., 1] - (0.5 * rs + distance[..., 1]) * (points[..., 3] / rs)
+ x2 = points[..., 0] + (0.5 * rs + distance[..., 2]) * (points[..., 2] / rs)
+ y2 = points[..., 1] + (0.5 * rs + distance[..., 3]) * (points[..., 3] / rs)
+ x0, y0, x1_, y1_ = (x1 + x2) / 2, (y1 + y2) / 2, x2 - x1, y2 - y1
+ return torch.stack([x0, y0, x1_, y1_], -1)
+
+
+class Integral(nn.Module):
+ """Sum Pr(n)·W(n) over the distribution bins."""
+ def __init__(self, reg_max=32):
+ super().__init__()
+ self.reg_max = reg_max
+
+ def forward(self, x, project):
+ shape = x.shape
+ x = F.softmax(x.reshape(-1, self.reg_max + 1), 1)
+ x = F.linear(x, project.to(device=x.device, dtype=x.dtype)).reshape(-1, 4)
+ return x.reshape(list(shape[:-1]) + [-1])
+
+
+class LQE(nn.Module):
+ """Location Quality Estimator — refines class scores using corner distribution."""
+ def __init__(self, k=4, hidden_dim=64, num_layers=2, reg_max=32, device=None, dtype=None, operations=None):
+ super().__init__()
+ self.k, self.reg_max = k, reg_max
+ self.reg_conf = MLP(4 * (k + 1), hidden_dim, 1, num_layers, device=device, dtype=dtype, operations=operations)
+
+ def forward(self, scores, pred_corners):
+ B, L, _ = pred_corners.shape
+ prob = F.softmax(pred_corners.reshape(B, L, 4, self.reg_max + 1), -1)
+ topk, _ = prob.topk(self.k, -1)
+ stat = torch.cat([topk, topk.mean(-1, keepdim=True)], -1)
+ return scores + self.reg_conf(stat.reshape(B, L, -1))
+
+
+class TransformerDecoder(nn.Module):
+ def __init__(self, hidden_dim, nhead, dim_feedforward, num_levels, num_points, num_layers, reg_max, reg_scale, up, eval_idx=-1, device=None, dtype=None, operations=None):
+ super().__init__()
+ self.hidden_dim = hidden_dim
+ self.num_layers = num_layers
+ self.nhead = nhead
+ self.eval_idx = eval_idx if eval_idx >= 0 else num_layers + eval_idx
+ self.up, self.reg_scale, self.reg_max = up, reg_scale, reg_max
+ self.layers = nn.ModuleList([
+ TransformerDecoderLayer(hidden_dim, nhead, dim_feedforward, num_levels, num_points, device=device, dtype=dtype, operations=operations)
+ for _ in range(self.eval_idx + 1)
+ ])
+ self.lqe_layers = nn.ModuleList([LQE(4, 64, 2, reg_max, device=device, dtype=dtype, operations=operations) for _ in range(self.eval_idx + 1)])
+ self.register_buffer('project', weighting_function(reg_max, up, reg_scale))
+
+ def _value_op(self, memory, spatial_shapes):
+ """Reshape memory to per-level value tensors for deformable attention."""
+ c = self.hidden_dim // self.nhead
+ split = [h * w for h, w in spatial_shapes]
+ val = memory.reshape(memory.shape[0], memory.shape[1], self.nhead, c) # memory: [bs, sum(h*w), hidden_dim]
+ # → [bs, n_head, c, sum_hw]
+ val = val.permute(0, 2, 3, 1).flatten(0, 1) # [bs*n_head, c, sum_hw]
+ return val.split(split, dim=-1) # list of [bs*n_head, c, h_l*w_l]
+
+ def forward(self, target, ref_pts_unact, memory, spatial_shapes, bbox_head, score_head, query_pos_head, pre_bbox_head, integral):
+ val_split_flat = self._value_op(memory, spatial_shapes) # pre-split value for deformable attention
+
+ # reshape to [bs*n_head, c, h_l, w_l]
+ value = []
+ for lvl, (h, w) in enumerate(spatial_shapes):
+ v = val_split_flat[lvl] # [bs*n_head, c, h*w]
+ value.append(v.reshape(v.shape[0], v.shape[1], h, w))
+
+ ref_pts = F.sigmoid(ref_pts_unact)
+ output = target
+ output_detach = pred_corners_undetach = 0
+
+ dec_bboxes, dec_logits = [], []
+
+ for i, layer in enumerate(self.layers):
+ ref_input = ref_pts.unsqueeze(2) # [bs, Lq, 1, 4]
+ query_pos = query_pos_head(ref_pts).clamp(-10, 10)
+ output = layer(output, ref_input, value, spatial_shapes, query_pos=query_pos)
+
+ if i == 0:
+ ref_unact = ref_pts.clamp(1e-5, 1 - 1e-5)
+ ref_unact = torch.log(ref_unact / (1 - ref_unact))
+ pre_bboxes = F.sigmoid(pre_bbox_head(output) + ref_unact)
+ ref_pts_initial = pre_bboxes.detach()
+
+ pred_corners = bbox_head[i](output + output_detach) + pred_corners_undetach
+ inter_ref_bbox = distance2bbox(ref_pts_initial, integral(pred_corners, self.project), self.reg_scale)
+
+ if i == self.eval_idx:
+ scores = score_head[i](output)
+ scores = self.lqe_layers[i](scores, pred_corners)
+ dec_bboxes.append(inter_ref_bbox)
+ dec_logits.append(scores)
+ break
+
+ pred_corners_undetach = pred_corners
+ ref_pts = inter_ref_bbox.detach()
+ output_detach = output.detach()
+
+ return torch.stack(dec_bboxes), torch.stack(dec_logits)
+
+
+class DFINETransformer(nn.Module):
+ def __init__(self, num_classes=80, hidden_dim=256, num_queries=300, feat_channels=[256, 256, 256], feat_strides=[8, 16, 32],
+ num_levels=3, num_points=[3, 6, 3], nhead=8, num_layers=6, dim_feedforward=1024, eval_idx=-1, eps=1e-2, reg_max=32,
+ reg_scale=8.0, eval_spatial_size=(640, 640), device=None, dtype=None, operations=None):
+ super().__init__()
+ assert len(feat_strides) == len(feat_channels)
+ self.hidden_dim = hidden_dim
+ self.num_queries = num_queries
+ self.num_levels = num_levels
+ self.eps = eps
+ self.eval_spatial_size = eval_spatial_size
+
+ self.feat_strides = list(feat_strides)
+ for i in range(num_levels - len(feat_strides)):
+ self.feat_strides.append(feat_strides[-1] * 2 ** (i + 1))
+
+ # input projection (expects pre-fused weights)
+ self.input_proj = nn.ModuleList()
+ for ch in feat_channels:
+ if ch == hidden_dim:
+ self.input_proj.append(nn.Identity())
+ else:
+ self.input_proj.append(nn.Sequential(OrderedDict([
+ ('conv', operations.Conv2d(ch, hidden_dim, 1, bias=True, device=device, dtype=dtype))])))
+ in_ch = feat_channels[-1]
+ for i in range(num_levels - len(feat_channels)):
+ self.input_proj.append(nn.Sequential(OrderedDict([
+ ('conv', operations.Conv2d(in_ch if i == 0 else hidden_dim,
+ hidden_dim, 3, 2, 1, bias=True, device=device, dtype=dtype))])))
+ in_ch = hidden_dim
+
+ # FDR parameters (non-trainable placeholders, set from config)
+ self.up = nn.Parameter(torch.tensor([0.5]), requires_grad=False)
+ self.reg_scale = nn.Parameter(torch.tensor([reg_scale]), requires_grad=False)
+
+ pts = num_points if isinstance(num_points, (list, tuple)) else [num_points] * num_levels
+ self.decoder = TransformerDecoder(hidden_dim, nhead, dim_feedforward, num_levels, pts,
+ num_layers, reg_max, self.reg_scale, self.up, eval_idx, device=device, dtype=dtype, operations=operations)
+
+ self.query_pos_head = MLP(4, 2 * hidden_dim, hidden_dim, 2, device=device, dtype=dtype, operations=operations)
+ self.enc_output = nn.Sequential(OrderedDict([
+ ('proj', operations.Linear(hidden_dim, hidden_dim, device=device, dtype=dtype)),
+ ('norm', operations.LayerNorm(hidden_dim, device=device, dtype=dtype))]))
+ self.enc_score_head = operations.Linear(hidden_dim, num_classes, device=device, dtype=dtype)
+ self.enc_bbox_head = MLP(hidden_dim, hidden_dim, 4, 3, device=device, dtype=dtype, operations=operations)
+
+ self.eval_idx_ = eval_idx if eval_idx >= 0 else num_layers + eval_idx
+ self.dec_score_head = nn.ModuleList(
+ [operations.Linear(hidden_dim, num_classes, device=device, dtype=dtype) for _ in range(self.eval_idx_ + 1)])
+ self.pre_bbox_head = MLP(hidden_dim, hidden_dim, 4, 3, device=device, dtype=dtype, operations=operations)
+ self.dec_bbox_head = nn.ModuleList(
+ [MLP(hidden_dim, hidden_dim, 4 * (reg_max + 1), 3, device=device, dtype=dtype, operations=operations)
+ for _ in range(self.eval_idx_ + 1)])
+ self.integral = Integral(reg_max)
+
+ if eval_spatial_size:
+ # Register as buffers so checkpoint values override the freshly-computed defaults
+ anchors, valid_mask = self._gen_anchors()
+ self.register_buffer('anchors', anchors)
+ self.register_buffer('valid_mask', valid_mask)
+
+ def _gen_anchors(self, spatial_shapes=None, grid_size=0.05, dtype=torch.float32, device='cpu'):
+ if spatial_shapes is None:
+ h0, w0 = self.eval_spatial_size
+ spatial_shapes = [[int(h0 / s), int(w0 / s)] for s in self.feat_strides]
+ anchors = []
+ for lvl, (h, w) in enumerate(spatial_shapes):
+ gy, gx = torch.meshgrid(torch.arange(h), torch.arange(w), indexing='ij')
+ gxy = (torch.stack([gx, gy], -1).float() + 0.5) / torch.tensor([w, h], dtype=dtype)
+ wh = torch.ones_like(gxy) * grid_size * (2. ** lvl)
+ anchors.append(torch.cat([gxy, wh], -1).reshape(-1, h * w, 4))
+ anchors = torch.cat(anchors, 1).to(device)
+ valid_mask = ((anchors > self.eps) & (anchors < 1 - self.eps)).all(-1, keepdim=True)
+ anchors = torch.log(anchors / (1 - anchors))
+ anchors = torch.where(valid_mask, anchors, torch.full_like(anchors, float('inf')))
+ return anchors, valid_mask
+
+ def _encoder_input(self, feats: List[torch.Tensor]):
+ proj = [self.input_proj[i](f) for i, f in enumerate(feats)]
+ for i in range(len(feats), self.num_levels):
+ proj.append(self.input_proj[i](feats[-1] if i == len(feats) else proj[-1]))
+ flat, shapes = [], []
+ for f in proj:
+ _, _, h, w = f.shape
+ flat.append(f.flatten(2).permute(0, 2, 1))
+ shapes.append([h, w])
+ return torch.cat(flat, 1), shapes
+
+ def _decoder_input(self, memory: torch.Tensor):
+ anchors, valid_mask = self.anchors.to(memory), self.valid_mask
+ if memory.shape[0] > 1:
+ anchors = anchors.repeat(memory.shape[0], 1, 1)
+
+ mem = valid_mask.to(memory) * memory
+ out_mem = self.enc_output(mem)
+ logits = self.enc_score_head(out_mem)
+ _, idx = torch.topk(logits.max(-1).values, self.num_queries, dim=-1)
+ idx_e = idx.unsqueeze(-1)
+ topk_mem = out_mem.gather(1, idx_e.expand(-1, -1, out_mem.shape[-1]))
+ topk_anc = anchors.gather(1, idx_e.expand(-1, -1, anchors.shape[-1]))
+ topk_ref = self.enc_bbox_head(topk_mem) + topk_anc
+ return topk_mem.detach(), topk_ref.detach()
+
+ def forward(self, feats: List[torch.Tensor]):
+ memory, shapes = self._encoder_input(feats)
+ content, ref = self._decoder_input(memory)
+ out_bboxes, out_logits = self.decoder(
+ content, ref, memory, shapes,
+ self.dec_bbox_head, self.dec_score_head,
+ self.query_pos_head, self.pre_bbox_head, self.integral)
+ return {'pred_logits': out_logits[-1], 'pred_boxes': out_bboxes[-1]}
+
+
+# ---------------------------------------------------------------------------
+# Main model
+# ---------------------------------------------------------------------------
+
+class RTv4(nn.Module):
+ def __init__(self, num_classes=80, num_queries=300, enc_h=256, dec_h=256, enc_ff=2048, dec_ff=1024, feat_strides=[8, 16, 32], device=None, dtype=None, operations=None, **kwargs):
+ super().__init__()
+ self.device = device
+ self.dtype = dtype
+ self.operations = operations
+
+ self.backbone = HGNetv2(device=device, dtype=dtype, operations=operations)
+ self.encoder = HybridEncoder(hidden_dim=enc_h, dim_feedforward=enc_ff, device=device, dtype=dtype, operations=operations)
+ self.decoder = DFINETransformer(num_classes=num_classes, hidden_dim=dec_h, num_queries=num_queries,
+ feat_channels=[enc_h] * len(feat_strides), feat_strides=feat_strides, dim_feedforward=dec_ff, device=device, dtype=dtype, operations=operations)
+
+ self.num_classes = num_classes
+ self.num_queries = num_queries
+ self.load_device = comfy.model_management.get_torch_device()
+
+ def _forward(self, x: torch.Tensor):
+ return self.decoder(self.encoder(self.backbone(x)))
+
+ def postprocess(self, outputs, orig_size: tuple = (640, 640)) -> List[dict]:
+ logits = outputs['pred_logits']
+ boxes = torchvision.ops.box_convert(outputs['pred_boxes'], 'cxcywh', 'xyxy')
+ boxes = boxes * torch.tensor(orig_size, device=boxes.device, dtype=boxes.dtype).repeat(1, 2).unsqueeze(1)
+ scores = F.sigmoid(logits)
+ scores, idx = torch.topk(scores.flatten(1), self.num_queries, dim=-1)
+ labels = idx % self.num_classes
+ boxes = boxes.gather(1, (idx // self.num_classes).unsqueeze(-1).expand(-1, -1, 4))
+ return [{'labels': lbl, 'boxes': b, 'scores': s} for lbl, b, s in zip(labels, boxes, scores)]
+
+ def forward(self, x: torch.Tensor, orig_size: tuple = (640, 640), **kwargs):
+ outputs = self._forward(x.to(device=self.load_device, dtype=self.dtype))
+ return self.postprocess(outputs, orig_size)
diff --git a/ComfyUI/comfy/ldm/sam3/__pycache__/detector.cpython-312.pyc b/ComfyUI/comfy/ldm/sam3/__pycache__/detector.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..347cdd63c2a335a5f97151969f011b2a2604ef2c
Binary files /dev/null and b/ComfyUI/comfy/ldm/sam3/__pycache__/detector.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/sam3/__pycache__/sam.cpython-312.pyc b/ComfyUI/comfy/ldm/sam3/__pycache__/sam.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..03b132f9f0878f140dd6195bd6bc3ece5557987a
Binary files /dev/null and b/ComfyUI/comfy/ldm/sam3/__pycache__/sam.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/sam3/__pycache__/tracker.cpython-312.pyc b/ComfyUI/comfy/ldm/sam3/__pycache__/tracker.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..9f64cd5e8092bc4cf4dca7f2f528c309e2ca8ce5
--- /dev/null
+++ b/ComfyUI/comfy/ldm/sam3/__pycache__/tracker.cpython-312.pyc
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:f09329d6fc24ecfa9727312cd85d92e0d96ac52d8b166b7cfc534639fb728088
+size 104089
diff --git a/ComfyUI/comfy/ldm/sam3/detector.py b/ComfyUI/comfy/ldm/sam3/detector.py
new file mode 100644
index 0000000000000000000000000000000000000000..23a972ac7dc7238c38372d651ea120a7c3577825
--- /dev/null
+++ b/ComfyUI/comfy/ldm/sam3/detector.py
@@ -0,0 +1,599 @@
+# SAM3 detector: transformer encoder-decoder, segmentation head, geometry encoder, scoring.
+
+import math
+
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+from torchvision.ops import roi_align
+
+from comfy.ldm.modules.attention import optimized_attention
+from comfy.ldm.sam3.tracker import SAM3Tracker, SAM31Tracker
+from comfy.ldm.sam3.sam import SAM3VisionBackbone # noqa: used in __init__
+from comfy.ldm.sam3.sam import MLP, PositionEmbeddingSine
+
+TRACKER_CLASSES = {"SAM3": SAM3Tracker, "SAM31": SAM31Tracker}
+from comfy.ops import cast_to_input
+
+
+def box_cxcywh_to_xyxy(x):
+ cx, cy, w, h = x.unbind(-1)
+ return torch.stack([cx - 0.5 * w, cy - 0.5 * h, cx + 0.5 * w, cy + 0.5 * h], dim=-1)
+
+
+def gen_sineembed_for_position(pos_tensor, num_feats=256):
+ """Per-coordinate sinusoidal embedding: (..., N) -> (..., N * num_feats)."""
+ assert num_feats % 2 == 0
+ hdim = num_feats // 2
+ freqs = 10000.0 ** (2 * (torch.arange(hdim, dtype=torch.float32, device=pos_tensor.device) // 2) / hdim)
+ embeds = []
+ for c in range(pos_tensor.shape[-1]):
+ raw = (pos_tensor[..., c].float() * 2 * math.pi).unsqueeze(-1) / freqs
+ embeds.append(torch.stack([raw[..., 0::2].sin(), raw[..., 1::2].cos()], dim=-1).flatten(-2))
+ return torch.cat(embeds, dim=-1).to(pos_tensor.dtype)
+
+
+class SplitMHA(nn.Module):
+ """Multi-head attention with separate Q/K/V projections (split from fused in_proj_weight)."""
+ def __init__(self, d_model, num_heads=8, device=None, dtype=None, operations=None):
+ super().__init__()
+ self.num_heads = num_heads
+ self.q_proj = operations.Linear(d_model, d_model, device=device, dtype=dtype)
+ self.k_proj = operations.Linear(d_model, d_model, device=device, dtype=dtype)
+ self.v_proj = operations.Linear(d_model, d_model, device=device, dtype=dtype)
+ self.out_proj = operations.Linear(d_model, d_model, device=device, dtype=dtype)
+
+ def forward(self, q_input, k_input=None, v_input=None, mask=None):
+ q = self.q_proj(q_input)
+ if k_input is None:
+ k = self.k_proj(q_input)
+ v = self.v_proj(q_input)
+ else:
+ k = self.k_proj(k_input)
+ v = self.v_proj(v_input if v_input is not None else k_input)
+ if mask is not None and mask.ndim == 2:
+ mask = mask[:, None, None, :] # [B, T] -> [B, 1, 1, T] for SDPA broadcast
+ dtype = q.dtype # manual_cast may produce mixed dtypes
+ out = optimized_attention(q, k.to(dtype), v.to(dtype), self.num_heads, mask=mask, low_precision_attention=False)
+ return self.out_proj(out)
+
+
+class MLPWithNorm(nn.Module):
+ """MLP with residual connection and output LayerNorm."""
+ def __init__(self, input_dim, hidden_dim, output_dim, num_layers, residual=True, device=None, dtype=None, operations=None):
+ super().__init__()
+ dims = [input_dim] + [hidden_dim] * (num_layers - 1) + [output_dim]
+ self.layers = nn.ModuleList([
+ operations.Linear(dims[i], dims[i + 1], device=device, dtype=dtype)
+ for i in range(num_layers)
+ ])
+ self.out_norm = operations.LayerNorm(output_dim, device=device, dtype=dtype)
+ self.residual = residual and (input_dim == output_dim)
+
+ def forward(self, x):
+ orig = x
+ for i, layer in enumerate(self.layers):
+ x = layer(x)
+ if i < len(self.layers) - 1:
+ x = F.relu(x)
+ if self.residual:
+ x = x + orig
+ return self.out_norm(x)
+
+
+class EncoderLayer(nn.Module):
+ def __init__(self, d_model=256, num_heads=8, dim_ff=2048, device=None, dtype=None, operations=None):
+ super().__init__()
+ self.self_attn = SplitMHA(d_model, num_heads, device=device, dtype=dtype, operations=operations)
+ self.cross_attn_image = SplitMHA(d_model, num_heads, device=device, dtype=dtype, operations=operations)
+ self.linear1 = operations.Linear(d_model, dim_ff, device=device, dtype=dtype)
+ self.linear2 = operations.Linear(dim_ff, d_model, device=device, dtype=dtype)
+ self.norm1 = operations.LayerNorm(d_model, device=device, dtype=dtype)
+ self.norm2 = operations.LayerNorm(d_model, device=device, dtype=dtype)
+ self.norm3 = operations.LayerNorm(d_model, device=device, dtype=dtype)
+
+ def forward(self, x, pos, text_memory=None, text_mask=None):
+ normed = self.norm1(x)
+ q_k = normed + pos
+ x = x + self.self_attn(q_k, q_k, normed)
+ if text_memory is not None:
+ normed = self.norm2(x)
+ x = x + self.cross_attn_image(normed, text_memory, text_memory, mask=text_mask)
+ normed = self.norm3(x)
+ x = x + self.linear2(F.relu(self.linear1(normed)))
+ return x
+
+
+class TransformerEncoder(nn.Module):
+ """Checkpoint: transformer.encoder.layers.N.*"""
+ def __init__(self, d_model=256, num_heads=8, dim_ff=2048, num_layers=6, device=None, dtype=None, operations=None):
+ super().__init__()
+ self.layers = nn.ModuleList([
+ EncoderLayer(d_model, num_heads, dim_ff, device=device, dtype=dtype, operations=operations)
+ for _ in range(num_layers)
+ ])
+
+ def forward(self, x, pos, text_memory=None, text_mask=None):
+ for layer in self.layers:
+ x = layer(x, pos, text_memory, text_mask)
+ return x
+
+
+class DecoderLayer(nn.Module):
+ def __init__(self, d_model=256, num_heads=8, dim_ff=2048, device=None, dtype=None, operations=None):
+ super().__init__()
+ self.self_attn = SplitMHA(d_model, num_heads, device=device, dtype=dtype, operations=operations)
+ self.cross_attn = SplitMHA(d_model, num_heads, device=device, dtype=dtype, operations=operations)
+ self.ca_text = SplitMHA(d_model, num_heads, device=device, dtype=dtype, operations=operations)
+ self.norm1 = operations.LayerNorm(d_model, device=device, dtype=dtype)
+ self.norm2 = operations.LayerNorm(d_model, device=device, dtype=dtype)
+ self.norm3 = operations.LayerNorm(d_model, device=device, dtype=dtype)
+ self.catext_norm = operations.LayerNorm(d_model, device=device, dtype=dtype)
+ self.linear1 = operations.Linear(d_model, dim_ff, device=device, dtype=dtype)
+ self.linear2 = operations.Linear(dim_ff, d_model, device=device, dtype=dtype)
+
+ def forward(self, x, memory, x_pos, memory_pos, text_memory=None, text_mask=None, cross_attn_bias=None):
+ q_k = x + x_pos
+ x = self.norm2(x + self.self_attn(q_k, q_k, x))
+ if text_memory is not None:
+ x = self.catext_norm(x + self.ca_text(x + x_pos, text_memory, text_memory, mask=text_mask))
+ x = self.norm1(x + self.cross_attn(x + x_pos, memory + memory_pos, memory, mask=cross_attn_bias))
+ x = self.norm3(x + self.linear2(F.relu(self.linear1(x))))
+ return x
+
+
+class TransformerDecoder(nn.Module):
+ def __init__(self, d_model=256, num_heads=8, dim_ff=2048, num_layers=6,
+ num_queries=200, device=None, dtype=None, operations=None):
+ super().__init__()
+ self.d_model = d_model
+ self.num_queries = num_queries
+
+ self.layers = nn.ModuleList([
+ DecoderLayer(d_model, num_heads, dim_ff, device=device, dtype=dtype, operations=operations)
+ for _ in range(num_layers)
+ ])
+ self.norm = operations.LayerNorm(d_model, device=device, dtype=dtype)
+ self.query_embed = operations.Embedding(num_queries, d_model, device=device, dtype=dtype)
+ self.reference_points = operations.Embedding(num_queries, 4, device=device, dtype=dtype) # Reference points: Embedding(num_queries, 4) — learned anchor boxes
+ self.ref_point_head = MLP(d_model * 2, d_model, d_model, 2, device=device, dtype=dtype, operations=operations) # ref_point_head input: 512 (4 coords * 128 sine features each)
+ self.bbox_embed = MLP(d_model, d_model, 4, 3, device=device, dtype=dtype, operations=operations)
+
+ self.boxRPB_embed_x = MLP(2, d_model, num_heads, 2, device=device, dtype=dtype, operations=operations)
+ self.boxRPB_embed_y = MLP(2, d_model, num_heads, 2, device=device, dtype=dtype, operations=operations)
+
+ self.presence_token = operations.Embedding(1, d_model, device=device, dtype=dtype)
+ self.presence_token_head = MLP(d_model, d_model, 1, 3, device=device, dtype=dtype, operations=operations)
+ self.presence_token_out_norm = operations.LayerNorm(d_model, device=device, dtype=dtype)
+
+ @staticmethod
+ def _inverse_sigmoid(x):
+ return torch.log(x / (1 - x + 1e-6) + 1e-6)
+
+ def _compute_box_rpb(self, ref_points, H, W):
+ """Box rotary position bias: (B, Q, 4) cxcywh -> (B, n_heads, Q+1, H*W) bias."""
+ boxes_xyxy = box_cxcywh_to_xyxy(ref_points)
+ B, Q, _ = boxes_xyxy.shape
+ coords_h = torch.arange(H, device=ref_points.device, dtype=torch.float32) / H
+ coords_w = torch.arange(W, device=ref_points.device, dtype=torch.float32) / W
+ deltas_x = coords_w.view(1, 1, -1, 1) - boxes_xyxy[:, :, None, 0:3:2]
+ deltas_y = coords_h.view(1, 1, -1, 1) - boxes_xyxy[:, :, None, 1:4:2]
+
+ log2_8 = float(math.log2(8))
+ def log_scale(d):
+ return torch.sign(d * 8) * torch.log2(torch.abs(d * 8) + 1.0) / log2_8
+
+ rpb_x = self.boxRPB_embed_x(log_scale(deltas_x).to(ref_points.dtype))
+ rpb_y = self.boxRPB_embed_y(log_scale(deltas_y).to(ref_points.dtype))
+
+ bias = (rpb_y.unsqueeze(3) + rpb_x.unsqueeze(2)).flatten(2, 3).permute(0, 3, 1, 2)
+ pres_bias = torch.zeros(B, bias.shape[1], 1, bias.shape[3], device=bias.device, dtype=bias.dtype)
+ return torch.cat([pres_bias, bias], dim=2)
+
+ def forward(self, memory, memory_pos, text_memory=None, text_mask=None, H=72, W=72):
+ B = memory.shape[0]
+ tgt = cast_to_input(self.query_embed.weight, memory).unsqueeze(0).expand(B, -1, -1)
+ presence_out = cast_to_input(self.presence_token.weight, memory)[None].expand(B, -1, -1)
+ ref_points = cast_to_input(self.reference_points.weight, memory).unsqueeze(0).expand(B, -1, -1).sigmoid()
+
+ for layer_idx, layer in enumerate(self.layers):
+ query_pos = self.ref_point_head(gen_sineembed_for_position(ref_points, self.d_model))
+ tgt_with_pres = torch.cat([presence_out, tgt], dim=1)
+ pos_with_pres = torch.cat([torch.zeros_like(presence_out), query_pos], dim=1)
+ tgt_with_pres = layer(tgt_with_pres, memory, pos_with_pres, memory_pos,
+ text_memory, text_mask, self._compute_box_rpb(ref_points, H, W))
+ presence_out, tgt = tgt_with_pres[:, :1], tgt_with_pres[:, 1:]
+ if layer_idx < len(self.layers) - 1:
+ ref_inv = self._inverse_sigmoid(ref_points)
+ ref_points = (ref_inv + self.bbox_embed(self.norm(tgt))).sigmoid().detach()
+
+ query_out = self.norm(tgt)
+ ref_inv = self._inverse_sigmoid(ref_points)
+ boxes = (ref_inv + self.bbox_embed(query_out)).sigmoid()
+ presence = self.presence_token_head(self.presence_token_out_norm(presence_out)).squeeze(-1)
+ return {"decoder_output": query_out, "pred_boxes": boxes, "presence": presence}
+
+
+class Transformer(nn.Module):
+ def __init__(self, d_model=256, num_heads=8, dim_ff=2048, enc_layers=6, dec_layers=6,
+ num_queries=200, device=None, dtype=None, operations=None):
+ super().__init__()
+ self.encoder = TransformerEncoder(d_model, num_heads, dim_ff, enc_layers, device=device, dtype=dtype, operations=operations)
+ self.decoder = TransformerDecoder(d_model, num_heads, dim_ff, dec_layers, num_queries, device=device, dtype=dtype, operations=operations)
+
+
+class GeometryEncoder(nn.Module):
+ def __init__(self, d_model=256, num_heads=8, num_layers=3, roi_size=7, device=None, dtype=None, operations=None):
+ super().__init__()
+ self.d_model = d_model
+ self.roi_size = roi_size
+ self.pos_enc = PositionEmbeddingSine(num_pos_feats=d_model, normalize=True)
+ self.points_direct_project = operations.Linear(2, d_model, device=device, dtype=dtype)
+ self.points_pool_project = operations.Linear(d_model, d_model, device=device, dtype=dtype)
+ self.points_pos_enc_project = operations.Linear(d_model, d_model, device=device, dtype=dtype)
+ self.boxes_direct_project = operations.Linear(4, d_model, device=device, dtype=dtype)
+ self.boxes_pool_project = operations.Conv2d(d_model, d_model, kernel_size=roi_size, device=device, dtype=dtype)
+ self.boxes_pos_enc_project = operations.Linear(d_model + 2, d_model, device=device, dtype=dtype)
+ self.label_embed = operations.Embedding(2, d_model, device=device, dtype=dtype)
+ self.cls_embed = operations.Embedding(1, d_model, device=device, dtype=dtype)
+ self.norm = operations.LayerNorm(d_model, device=device, dtype=dtype)
+ self.img_pre_norm = operations.LayerNorm(d_model, device=device, dtype=dtype)
+ self.encode = nn.ModuleList([
+ EncoderLayer(d_model, num_heads, 2048, device=device, dtype=dtype, operations=operations)
+ for _ in range(num_layers)
+ ])
+ self.encode_norm = operations.LayerNorm(d_model, device=device, dtype=dtype)
+ self.final_proj = operations.Linear(d_model, d_model, device=device, dtype=dtype)
+
+ def _encode_points(self, coords, labels, img_feat_2d):
+ """Encode point prompts: direct + pool + pos_enc + label. coords: [B, N, 2] normalized."""
+ B, N, _ = coords.shape
+ embed = self.points_direct_project(coords)
+ # Pool features from backbone at point locations via grid_sample
+ grid = (coords * 2 - 1).unsqueeze(2) # [B, N, 1, 2] in [-1, 1]
+ sampled = F.grid_sample(img_feat_2d, grid, align_corners=False) # [B, C, N, 1]
+ embed = embed + self.points_pool_project(sampled.squeeze(-1).permute(0, 2, 1)) # [B, N, C]
+ # Positional encoding of coordinates
+ x, y = coords[:, :, 0], coords[:, :, 1] # [B, N]
+ pos_x, pos_y = self.pos_enc._encode_xy(x.flatten(), y.flatten())
+ enc = torch.cat([pos_x, pos_y], dim=-1).view(B, N, -1)
+ embed = embed + self.points_pos_enc_project(cast_to_input(enc, embed))
+ embed = embed + cast_to_input(self.label_embed(labels.long()), embed)
+ return embed
+
+ def _encode_boxes(self, boxes, labels, img_feat_2d):
+ """Encode box prompts: direct + pool + pos_enc + label. boxes: [B, N, 4] normalized cxcywh."""
+ B, N, _ = boxes.shape
+ embed = self.boxes_direct_project(boxes)
+ # ROI align from backbone at box regions
+ H, W = img_feat_2d.shape[-2:]
+ boxes_xyxy = box_cxcywh_to_xyxy(boxes)
+ scale = torch.tensor([W, H, W, H], dtype=boxes_xyxy.dtype, device=boxes_xyxy.device)
+ boxes_scaled = boxes_xyxy * scale
+ sampled = roi_align(img_feat_2d, boxes_scaled.view(-1, 4).split(N), self.roi_size)
+ proj = self.boxes_pool_project(sampled).view(B, N, -1) # Conv2d(roi_size) -> [B*N, C, 1, 1] -> [B, N, C]
+ embed = embed + proj
+ # Positional encoding of box center + size
+ cx, cy, w, h = boxes[:, :, 0], boxes[:, :, 1], boxes[:, :, 2], boxes[:, :, 3]
+ enc = self.pos_enc.encode_boxes(cx.flatten(), cy.flatten(), w.flatten(), h.flatten())
+ enc = enc.view(B, N, -1)
+ embed = embed + self.boxes_pos_enc_project(cast_to_input(enc, embed))
+ embed = embed + cast_to_input(self.label_embed(labels.long()), embed)
+ return embed
+
+ def forward(self, points=None, boxes=None, image_features=None):
+ """Encode geometry prompts. image_features: [B, HW, C] flattened backbone features."""
+ # Prepare 2D image features for pooling
+ img_feat_2d = None
+ if image_features is not None:
+ B = image_features.shape[0]
+ HW, C = image_features.shape[1], image_features.shape[2]
+ hw = int(math.sqrt(HW))
+ img_normed = self.img_pre_norm(image_features)
+ img_feat_2d = img_normed.permute(0, 2, 1).view(B, C, hw, hw)
+
+ embeddings = []
+ if points is not None:
+ coords, labels = points
+ embeddings.append(self._encode_points(coords, labels, img_feat_2d))
+ if boxes is not None:
+ B = boxes.shape[0]
+ box_labels = torch.ones(B, boxes.shape[1], dtype=torch.long, device=boxes.device)
+ embeddings.append(self._encode_boxes(boxes, box_labels, img_feat_2d))
+ if not embeddings:
+ return None
+ geo = torch.cat(embeddings, dim=1)
+ geo = self.norm(geo)
+ if image_features is not None:
+ for layer in self.encode:
+ geo = layer(geo, torch.zeros_like(geo), image_features)
+ geo = self.encode_norm(geo)
+ return self.final_proj(geo)
+
+
+class PixelDecoder(nn.Module):
+ """Top-down FPN pixel decoder with GroupNorm + ReLU + nearest interpolation."""
+ def __init__(self, d_model=256, num_stages=3, device=None, dtype=None, operations=None):
+ super().__init__()
+ self.conv_layers = nn.ModuleList([operations.Conv2d(d_model, d_model, kernel_size=3, padding=1, device=device, dtype=dtype) for _ in range(num_stages)])
+ self.norms = nn.ModuleList([operations.GroupNorm(8, d_model, device=device, dtype=dtype) for _ in range(num_stages)])
+
+ def forward(self, backbone_features):
+ prev = backbone_features[-1]
+ for i, feat in enumerate(backbone_features[:-1][::-1]):
+ prev = F.relu(self.norms[i](self.conv_layers[i](feat + F.interpolate(prev, size=feat.shape[-2:], mode="nearest"))))
+ return prev
+
+
+class MaskPredictor(nn.Module):
+ def __init__(self, d_model=256, device=None, dtype=None, operations=None):
+ super().__init__()
+ self.mask_embed = MLP(d_model, d_model, d_model, 3, device=device, dtype=dtype, operations=operations)
+
+ def forward(self, query_embeddings, pixel_features):
+ mask_embed = self.mask_embed(query_embeddings)
+ return torch.einsum("bqc,bchw->bqhw", mask_embed, pixel_features)
+
+
+class SegmentationHead(nn.Module):
+ def __init__(self, d_model=256, num_heads=8, device=None, dtype=None, operations=None):
+ super().__init__()
+ self.d_model = d_model
+ self.pixel_decoder = PixelDecoder(d_model, 3, device=device, dtype=dtype, operations=operations)
+ self.mask_predictor = MaskPredictor(d_model, device=device, dtype=dtype, operations=operations)
+ self.cross_attend_prompt = SplitMHA(d_model, num_heads, device=device, dtype=dtype, operations=operations)
+ self.cross_attn_norm = operations.LayerNorm(d_model, device=device, dtype=dtype)
+ self.instance_seg_head = operations.Conv2d(d_model, d_model, kernel_size=1, device=device, dtype=dtype)
+ self.semantic_seg_head = operations.Conv2d(d_model, 1, kernel_size=1, device=device, dtype=dtype)
+
+ def forward(self, query_embeddings, backbone_features, encoder_hidden_states=None, prompt=None, prompt_mask=None):
+ if encoder_hidden_states is not None and prompt is not None:
+ enc_normed = self.cross_attn_norm(encoder_hidden_states)
+ enc_cross = self.cross_attend_prompt(enc_normed, prompt, prompt, mask=prompt_mask)
+ encoder_hidden_states = enc_cross + encoder_hidden_states
+
+ if encoder_hidden_states is not None:
+ B, H, W = encoder_hidden_states.shape[0], backbone_features[-1].shape[-2], backbone_features[-1].shape[-1]
+ encoder_visual = encoder_hidden_states[:, :H * W].permute(0, 2, 1).view(B, self.d_model, H, W)
+ backbone_features = list(backbone_features)
+ backbone_features[-1] = encoder_visual
+
+ pixel_features = self.pixel_decoder(backbone_features)
+ instance_features = self.instance_seg_head(pixel_features)
+ masks = self.mask_predictor(query_embeddings, instance_features)
+ return masks
+
+
+class DotProductScoring(nn.Module):
+ def __init__(self, d_model=256, device=None, dtype=None, operations=None):
+ super().__init__()
+ self.hs_proj = operations.Linear(d_model, d_model, device=device, dtype=dtype)
+ self.prompt_proj = operations.Linear(d_model, d_model, device=device, dtype=dtype)
+ self.prompt_mlp = MLPWithNorm(d_model, 2048, d_model, 2, device=device, dtype=dtype, operations=operations)
+ self.scale = 1.0 / (d_model ** 0.5)
+
+ def forward(self, query_embeddings, prompt_embeddings, prompt_mask=None):
+ prompt = self.prompt_mlp(prompt_embeddings)
+ if prompt_mask is not None:
+ weight = prompt_mask.unsqueeze(-1).to(dtype=prompt.dtype)
+ pooled = (prompt * weight).sum(dim=1) / weight.sum(dim=1).clamp(min=1)
+ else:
+ pooled = prompt.mean(dim=1)
+ hs = self.hs_proj(query_embeddings)
+ pp = self.prompt_proj(pooled).unsqueeze(-1).to(hs.dtype)
+ scores = torch.matmul(hs, pp)
+ return (scores * self.scale).clamp(-12.0, 12.0).squeeze(-1)
+
+
+class SAM3Detector(nn.Module):
+ def __init__(self, d_model=256, embed_dim=1024, num_queries=200, device=None, dtype=None, operations=None, **kwargs):
+ super().__init__()
+ image_model = kwargs.pop("image_model", "SAM3")
+ for k in ("num_heads", "num_head_channels"):
+ kwargs.pop(k, None)
+ multiplex = image_model == "SAM31"
+ # SAM3: 4 FPN levels, drop last (scalp=1); SAM3.1: 3 levels, use all (scalp=0)
+ self.scalp = 0 if multiplex else 1
+ self.backbone = nn.ModuleDict({
+ "vision_backbone": SAM3VisionBackbone(embed_dim=embed_dim, d_model=d_model, multiplex=multiplex, device=device, dtype=dtype, operations=operations, **kwargs),
+ "language_backbone": nn.ModuleDict({"resizer": operations.Linear(embed_dim, d_model, device=device, dtype=dtype)}),
+ })
+ self.transformer = Transformer(d_model=d_model, num_queries=num_queries, device=device, dtype=dtype, operations=operations)
+ self.segmentation_head = SegmentationHead(d_model=d_model, device=device, dtype=dtype, operations=operations)
+ self.geometry_encoder = GeometryEncoder(d_model=d_model, device=device, dtype=dtype, operations=operations)
+ self.dot_prod_scoring = DotProductScoring(d_model=d_model, device=device, dtype=dtype, operations=operations)
+
+ def _get_backbone_features(self, images):
+ """Run backbone and return (detector_features, detector_positions, tracker_features, tracker_positions)."""
+ bb = self.backbone["vision_backbone"]
+ if bb.multiplex:
+ all_f, all_p, tf, tp = bb(images, tracker_mode="propagation")
+ else:
+ all_f, all_p, tf, tp = bb(images, need_tracker=True)
+ return all_f, all_p, tf, tp
+
+ @staticmethod
+ def _run_geo_layer(layer, x, memory, memory_pos):
+ x = x + layer.self_attn(layer.norm1(x))
+ x = x + layer.cross_attn_image(layer.norm2(x), memory + memory_pos, memory)
+ x = x + layer.linear2(F.relu(layer.linear1(layer.norm3(x))))
+ return x
+
+ def _detect(self, features, positions, text_embeddings=None, text_mask=None,
+ points=None, boxes=None):
+ """Shared detection: geometry encoding, transformer, scoring, segmentation."""
+ B = features[0].shape[0]
+ # Scalp for encoder (use top-level feature), but keep all levels for segmentation head
+ seg_features = features
+ if self.scalp > 0:
+ features = features[:-self.scalp]
+ positions = positions[:-self.scalp]
+ enc_feat, enc_pos = features[-1], positions[-1]
+ _, _, H, W = enc_feat.shape
+ img_flat = enc_feat.flatten(2).permute(0, 2, 1)
+ pos_flat = enc_pos.flatten(2).permute(0, 2, 1)
+
+ has_prompts = text_embeddings is not None or points is not None or boxes is not None
+ if has_prompts:
+ geo_enc = self.geometry_encoder
+ geo_prompts = geo_enc(points=points, boxes=boxes, image_features=img_flat)
+ geo_cls = geo_enc.norm(geo_enc.final_proj(cast_to_input(geo_enc.cls_embed.weight, img_flat).view(1, 1, -1).expand(B, -1, -1)))
+ for layer in geo_enc.encode:
+ geo_cls = self._run_geo_layer(layer, geo_cls, img_flat, pos_flat)
+ geo_cls = geo_enc.encode_norm(geo_cls)
+ if text_embeddings is not None and text_embeddings.shape[0] != B:
+ text_embeddings = text_embeddings.expand(B, -1, -1)
+ if text_mask is not None and text_mask.shape[0] != B:
+ text_mask = text_mask.expand(B, -1)
+ parts = [t for t in [text_embeddings, geo_prompts, geo_cls] if t is not None]
+ text_embeddings = torch.cat(parts, dim=1)
+ n_new = text_embeddings.shape[1] - (text_mask.shape[1] if text_mask is not None else 0)
+ if text_mask is not None:
+ text_mask = torch.cat([text_mask, torch.ones(B, n_new, dtype=torch.bool, device=text_mask.device)], dim=1)
+ else:
+ text_mask = torch.ones(B, text_embeddings.shape[1], dtype=torch.bool, device=text_embeddings.device)
+
+ memory = self.transformer.encoder(img_flat, pos_flat, text_embeddings, text_mask)
+ dec_out = self.transformer.decoder(memory, pos_flat, text_embeddings, text_mask, H, W)
+ query_out, pred_boxes = dec_out["decoder_output"], dec_out["pred_boxes"]
+
+ if text_embeddings is not None:
+ scores = self.dot_prod_scoring(query_out, text_embeddings, text_mask)
+ else:
+ scores = torch.zeros(B, query_out.shape[1], device=query_out.device)
+
+ masks = self.segmentation_head(query_out, seg_features, encoder_hidden_states=memory, prompt=text_embeddings, prompt_mask=text_mask)
+ return box_cxcywh_to_xyxy(pred_boxes), scores, masks, dec_out
+
+ def forward(self, images, text_embeddings=None, text_mask=None, points=None, boxes=None, threshold=0.3, orig_size=None):
+ features, positions, _, _ = self._get_backbone_features(images)
+
+ if text_embeddings is not None:
+ text_embeddings = self.backbone["language_backbone"]["resizer"](text_embeddings)
+ if text_mask is not None:
+ text_mask = text_mask.bool()
+
+ boxes_xyxy, scores, masks, dec_out = self._detect(
+ features, positions, text_embeddings, text_mask, points, boxes)
+
+ if orig_size is not None:
+ oh, ow = orig_size
+ boxes_xyxy = boxes_xyxy * torch.tensor([ow, oh, ow, oh], device=boxes_xyxy.device, dtype=boxes_xyxy.dtype)
+ masks = F.interpolate(masks, size=orig_size, mode="bilinear", align_corners=False)
+
+ return {
+ "boxes": boxes_xyxy,
+ "scores": scores,
+ "masks": masks,
+ "presence": dec_out.get("presence"),
+ }
+
+ def forward_from_trunk(self, trunk_out, text_embeddings, text_mask):
+ """Run detection using a pre-computed ViTDet trunk output.
+
+ text_embeddings must already be resized through language_backbone.resizer.
+ Returns dict with boxes (normalized xyxy), scores, masks at detector resolution.
+ """
+ bb = self.backbone["vision_backbone"]
+ features = [conv(trunk_out) for conv in bb.convs]
+ positions = [cast_to_input(bb.position_encoding(f), f) for f in features]
+
+ if text_mask is not None:
+ text_mask = text_mask.bool()
+
+ boxes_xyxy, scores, masks, _ = self._detect(features, positions, text_embeddings, text_mask)
+ return {"boxes": boxes_xyxy, "scores": scores, "masks": masks}
+
+
+class SAM3Model(nn.Module):
+ def __init__(self, device=None, dtype=None, operations=None, **kwargs):
+ super().__init__()
+ self.dtype = dtype
+ image_model = kwargs.get("image_model", "SAM3")
+ tracker_cls = TRACKER_CLASSES[image_model]
+ self.detector = SAM3Detector(device=device, dtype=dtype, operations=operations, **kwargs)
+ self.tracker = tracker_cls(device=device, dtype=dtype, operations=operations, **kwargs)
+
+ def forward(self, images, **kwargs):
+ return self.detector(images, **kwargs)
+
+ def forward_segment(self, images, point_inputs=None, box_inputs=None, mask_inputs=None):
+ """Interactive segmentation using SAM decoder with point/box/mask prompts.
+
+ Args:
+ images: [B, 3, 1008, 1008] preprocessed images
+ point_inputs: {"point_coords": [B, N, 2], "point_labels": [B, N]} in 1008x1008 pixel space
+ box_inputs: [B, 2, 2] box corners (top-left, bottom-right) in 1008x1008 pixel space
+ mask_inputs: [B, 1, H, W] coarse mask logits to refine
+ Returns:
+ [B, 1, image_size, image_size] high-res mask logits
+ """
+ bb = self.detector.backbone["vision_backbone"]
+ if bb.multiplex:
+ _, _, tracker_features, tracker_positions = bb(images, tracker_mode="interactive")
+ else:
+ _, _, tracker_features, tracker_positions = bb(images, need_tracker=True)
+ if self.detector.scalp > 0:
+ tracker_features = tracker_features[:-self.detector.scalp]
+ tracker_positions = tracker_positions[:-self.detector.scalp]
+
+ high_res = list(tracker_features[:-1])
+ backbone_feat = tracker_features[-1]
+ B, C, H, W = backbone_feat.shape
+ # Add no-memory embedding (init frame path)
+ no_mem = getattr(self.tracker, 'interactivity_no_mem_embed', None)
+ if no_mem is None:
+ no_mem = getattr(self.tracker, 'no_mem_embed', None)
+ if no_mem is not None:
+ feat_flat = backbone_feat.flatten(2).permute(0, 2, 1)
+ feat_flat = feat_flat + cast_to_input(no_mem, feat_flat)
+ backbone_feat = feat_flat.view(B, H, W, C).permute(0, 3, 1, 2)
+
+ num_pts = 0 if point_inputs is None else point_inputs["point_labels"].size(1)
+ _, high_res_masks, _, _ = self.tracker._forward_sam_heads(
+ backbone_features=backbone_feat,
+ point_inputs=point_inputs,
+ mask_inputs=mask_inputs,
+ box_inputs=box_inputs,
+ high_res_features=high_res,
+ multimask_output=(0 < num_pts <= 1),
+ )
+ return high_res_masks
+
+ def forward_video(self, images, initial_masks, pbar=None, text_prompts=None,
+ new_det_thresh=0.5, max_objects=0, detect_interval=1,
+ target_device=None, target_dtype=None):
+ """Track video with optional per-frame text-prompted detection."""
+ bb = self.detector.backbone["vision_backbone"]
+
+ def backbone_fn(frame, frame_idx=None):
+ trunk_out = bb.trunk(frame)
+ if bb.multiplex:
+ _, _, tf, tp = bb(frame, tracker_mode="propagation", cached_trunk=trunk_out, tracker_only=True)
+ else:
+ _, _, tf, tp = bb(frame, need_tracker=True, cached_trunk=trunk_out, tracker_only=True)
+ return tf, tp, trunk_out
+
+ detect_fn = None
+ if text_prompts:
+ resizer = self.detector.backbone["language_backbone"]["resizer"]
+ resized = [(resizer(emb), m.bool() if m is not None else None) for emb, m in text_prompts]
+ def detect_fn(trunk_out):
+ all_scores, all_masks = [], []
+ for emb, mask in resized:
+ det = self.detector.forward_from_trunk(trunk_out, emb, mask)
+ all_scores.append(det["scores"])
+ all_masks.append(det["masks"])
+ return {"scores": torch.cat(all_scores, dim=1), "masks": torch.cat(all_masks, dim=1)}
+
+ if hasattr(self.tracker, 'track_video_with_detection'):
+ return self.tracker.track_video_with_detection(
+ backbone_fn, images, initial_masks, detect_fn,
+ new_det_thresh=new_det_thresh, max_objects=max_objects,
+ detect_interval=detect_interval, backbone_obj=bb, pbar=pbar,
+ target_device=target_device, target_dtype=target_dtype)
+ # SAM3 (non-multiplex) — no detection support, requires initial masks
+ if initial_masks is None:
+ raise ValueError("SAM3 (non-multiplex) requires initial_mask for video tracking")
+ return self.tracker.track_video(backbone_fn, images, initial_masks, pbar=pbar, backbone_obj=bb,
+ target_device=target_device, target_dtype=target_dtype)
diff --git a/ComfyUI/comfy/ldm/sam3/sam.py b/ComfyUI/comfy/ldm/sam3/sam.py
new file mode 100644
index 0000000000000000000000000000000000000000..75cb457cff5318ee79ca0300a46c6bd41e776fea
--- /dev/null
+++ b/ComfyUI/comfy/ldm/sam3/sam.py
@@ -0,0 +1,425 @@
+# SAM3 shared components: primitives, ViTDet backbone, FPN neck, position encodings.
+
+import math
+
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+
+from comfy.ldm.modules.attention import optimized_attention
+from comfy.ldm.flux.math import apply_rope
+from comfy.ldm.flux.layers import EmbedND
+from comfy.ops import cast_to_input
+
+
+class MLP(nn.Module):
+ def __init__(self, input_dim, hidden_dim, output_dim, num_layers, sigmoid_output=False, device=None, dtype=None, operations=None):
+ super().__init__()
+ dims = [input_dim] + [hidden_dim] * (num_layers - 1) + [output_dim]
+ self.layers = nn.ModuleList([operations.Linear(dims[i], dims[i + 1], device=device, dtype=dtype) for i in range(num_layers)])
+ self.sigmoid_output = sigmoid_output
+
+ def forward(self, x):
+ for i, layer in enumerate(self.layers):
+ x = F.relu(layer(x)) if i < len(self.layers) - 1 else layer(x)
+ return torch.sigmoid(x) if self.sigmoid_output else x
+
+
+class SAMAttention(nn.Module):
+ def __init__(self, embedding_dim, num_heads, downsample_rate=1, kv_in_dim=None, device=None, dtype=None, operations=None):
+ super().__init__()
+ self.num_heads = num_heads
+ internal_dim = embedding_dim // downsample_rate
+ kv_dim = kv_in_dim if kv_in_dim is not None else embedding_dim
+ self.q_proj = operations.Linear(embedding_dim, internal_dim, device=device, dtype=dtype)
+ self.k_proj = operations.Linear(kv_dim, internal_dim, device=device, dtype=dtype)
+ self.v_proj = operations.Linear(kv_dim, internal_dim, device=device, dtype=dtype)
+ self.out_proj = operations.Linear(internal_dim, embedding_dim, device=device, dtype=dtype)
+
+ def forward(self, q, k, v):
+ q = self.q_proj(q)
+ k = self.k_proj(k)
+ v = self.v_proj(v)
+ return self.out_proj(optimized_attention(q, k, v, self.num_heads, low_precision_attention=False))
+
+
+class TwoWayAttentionBlock(nn.Module):
+ def __init__(self, embedding_dim, num_heads, mlp_dim=2048, attention_downsample_rate=2, skip_first_layer_pe=False, device=None, dtype=None, operations=None):
+ super().__init__()
+ self.skip_first_layer_pe = skip_first_layer_pe
+ self.self_attn = SAMAttention(embedding_dim, num_heads, device=device, dtype=dtype, operations=operations)
+ self.cross_attn_token_to_image = SAMAttention(embedding_dim, num_heads, downsample_rate=attention_downsample_rate, device=device, dtype=dtype, operations=operations)
+ self.cross_attn_image_to_token = SAMAttention(embedding_dim, num_heads, downsample_rate=attention_downsample_rate, device=device, dtype=dtype, operations=operations)
+ self.mlp = nn.Sequential(operations.Linear(embedding_dim, mlp_dim, device=device, dtype=dtype), nn.ReLU(), operations.Linear(mlp_dim, embedding_dim, device=device, dtype=dtype))
+ self.norm1 = operations.LayerNorm(embedding_dim, device=device, dtype=dtype)
+ self.norm2 = operations.LayerNorm(embedding_dim, device=device, dtype=dtype)
+ self.norm3 = operations.LayerNorm(embedding_dim, device=device, dtype=dtype)
+ self.norm4 = operations.LayerNorm(embedding_dim, device=device, dtype=dtype)
+
+ def forward(self, queries, keys, query_pe, key_pe):
+ if self.skip_first_layer_pe:
+ queries = self.norm1(self.self_attn(queries, queries, queries))
+ else:
+ q = queries + query_pe
+ queries = self.norm1(queries + self.self_attn(q, q, queries))
+ q, k = queries + query_pe, keys + key_pe
+ queries = self.norm2(queries + self.cross_attn_token_to_image(q, k, keys))
+ queries = self.norm3(queries + self.mlp(queries))
+ q, k = queries + query_pe, keys + key_pe
+ keys = self.norm4(keys + self.cross_attn_image_to_token(k, q, queries))
+ return queries, keys
+
+
+class TwoWayTransformer(nn.Module):
+ def __init__(self, depth=2, embedding_dim=256, num_heads=8, mlp_dim=2048, attention_downsample_rate=2, device=None, dtype=None, operations=None):
+ super().__init__()
+ self.layers = nn.ModuleList([
+ TwoWayAttentionBlock(embedding_dim, num_heads, mlp_dim, attention_downsample_rate,
+ skip_first_layer_pe=(i == 0), device=device, dtype=dtype, operations=operations)
+ for i in range(depth)
+ ])
+ self.final_attn_token_to_image = SAMAttention(embedding_dim, num_heads, downsample_rate=attention_downsample_rate, device=device, dtype=dtype, operations=operations)
+ self.norm_final = operations.LayerNorm(embedding_dim, device=device, dtype=dtype)
+
+ def forward(self, image_embedding, image_pe, point_embedding):
+ queries, keys = point_embedding, image_embedding
+ for layer in self.layers:
+ queries, keys = layer(queries, keys, point_embedding, image_pe)
+ q, k = queries + point_embedding, keys + image_pe
+ queries = self.norm_final(queries + self.final_attn_token_to_image(q, k, keys))
+ return queries, keys
+
+
+class PositionEmbeddingRandom(nn.Module):
+ """Fourier feature positional encoding with random gaussian projection."""
+ def __init__(self, num_pos_feats=64, scale=None):
+ super().__init__()
+ self.register_buffer("positional_encoding_gaussian_matrix", (scale or 1.0) * torch.randn(2, num_pos_feats))
+
+ def _encode(self, normalized_coords):
+ """Map normalized [0,1] coordinates to fourier features via random projection. Computes in fp32."""
+ orig_dtype = normalized_coords.dtype
+ proj_matrix = self.positional_encoding_gaussian_matrix.to(device=normalized_coords.device, dtype=torch.float32)
+ projected = 2 * math.pi * (2 * normalized_coords.float() - 1) @ proj_matrix
+ return torch.cat([projected.sin(), projected.cos()], dim=-1).to(orig_dtype)
+
+ def forward(self, size, device=None):
+ h, w = size
+ dev = device if device is not None else self.positional_encoding_gaussian_matrix.device
+ ones = torch.ones((h, w), device=dev, dtype=torch.float32)
+ norm_xy = torch.stack([(ones.cumsum(1) - 0.5) / w, (ones.cumsum(0) - 0.5) / h], dim=-1)
+ return self._encode(norm_xy).permute(2, 0, 1).unsqueeze(0)
+
+ def forward_with_coords(self, pixel_coords, image_size):
+ norm = pixel_coords.clone()
+ norm[:, :, 0] /= image_size[1]
+ norm[:, :, 1] /= image_size[0]
+ return self._encode(norm)
+
+
+# ViTDet backbone + FPN neck
+
+def window_partition(x: torch.Tensor, window_size: int):
+ B, H, W, C = x.shape
+ pad_h = (window_size - H % window_size) % window_size
+ pad_w = (window_size - W % window_size) % window_size
+ if pad_h > 0 or pad_w > 0:
+ x = F.pad(x, (0, 0, 0, pad_w, 0, pad_h))
+ Hp, Wp = H + pad_h, W + pad_w
+ x = x.view(B, Hp // window_size, window_size, Wp // window_size, window_size, C)
+ windows = x.permute(0, 1, 3, 2, 4, 5).contiguous().view(-1, window_size, window_size, C)
+ return windows, (Hp, Wp)
+
+
+def window_unpartition(windows: torch.Tensor, window_size: int, pad_hw, hw):
+ Hp, Wp = pad_hw
+ H, W = hw
+ B = windows.shape[0] // (Hp * Wp // window_size // window_size)
+ x = windows.view(B, Hp // window_size, Wp // window_size, window_size, window_size, -1)
+ x = x.permute(0, 1, 3, 2, 4, 5).contiguous().view(B, Hp, Wp, -1)
+ if Hp > H or Wp > W:
+ x = x[:, :H, :W, :].contiguous()
+ return x
+
+
+def rope_2d(end_x: int, end_y: int, dim: int, theta: float = 10000.0, scale_pos: float = 1.0):
+ """Generate 2D axial RoPE using flux EmbedND. Returns [1, 1, HW, dim//2, 2, 2]."""
+ t = torch.arange(end_x * end_y, dtype=torch.float32)
+ ids = torch.stack([(t % end_x) * scale_pos,
+ torch.div(t, end_x, rounding_mode="floor") * scale_pos], dim=-1)
+ return EmbedND(dim=dim, theta=theta, axes_dim=[dim // 2, dim // 2])(ids.unsqueeze(0))
+
+
+class _ViTMLP(nn.Module):
+ def __init__(self, dim, mlp_ratio=4.0, device=None, dtype=None, operations=None):
+ super().__init__()
+ hidden = int(dim * mlp_ratio)
+ self.fc1 = operations.Linear(dim, hidden, device=device, dtype=dtype)
+ self.act = nn.GELU()
+ self.fc2 = operations.Linear(hidden, dim, device=device, dtype=dtype)
+
+ def forward(self, x):
+ return self.fc2(self.act(self.fc1(x)))
+
+
+class Attention(nn.Module):
+ """ViTDet multi-head attention with fused QKV projection."""
+
+ def __init__(self, dim, num_heads=8, qkv_bias=True, use_rope=False, device=None, dtype=None, operations=None):
+ super().__init__()
+ self.num_heads = num_heads
+ self.head_dim = dim // num_heads
+ self.use_rope = use_rope
+ self.qkv = operations.Linear(dim, dim * 3, bias=qkv_bias, device=device, dtype=dtype)
+ self.proj = operations.Linear(dim, dim, device=device, dtype=dtype)
+
+ def forward(self, x, freqs_cis=None):
+ B, N, C = x.shape
+ qkv = self.qkv(x).reshape(B, N, 3, self.num_heads, self.head_dim)
+ q, k, v = qkv.permute(2, 0, 3, 1, 4).unbind(dim=0)
+ if self.use_rope and freqs_cis is not None:
+ q, k = apply_rope(q, k, freqs_cis)
+ return self.proj(optimized_attention(q, k, v, self.num_heads, skip_reshape=True, low_precision_attention=False))
+
+
+class Block(nn.Module):
+ def __init__(self, dim, num_heads, mlp_ratio=4.0, qkv_bias=True, window_size=0, use_rope=False, device=None, dtype=None, operations=None):
+ super().__init__()
+ self.window_size = window_size
+ self.norm1 = operations.LayerNorm(dim, device=device, dtype=dtype)
+ self.attn = Attention(dim, num_heads, qkv_bias, use_rope, device=device, dtype=dtype, operations=operations)
+ self.norm2 = operations.LayerNorm(dim, device=device, dtype=dtype)
+ self.mlp = _ViTMLP(dim, mlp_ratio, device=device, dtype=dtype, operations=operations)
+
+ def forward(self, x, freqs_cis=None):
+ shortcut = x
+ x = self.norm1(x)
+ if self.window_size > 0:
+ H, W = x.shape[1], x.shape[2]
+ x, pad_hw = window_partition(x, self.window_size)
+ x = x.view(x.shape[0], self.window_size * self.window_size, -1)
+ x = self.attn(x, freqs_cis=freqs_cis)
+ x = x.view(-1, self.window_size, self.window_size, x.shape[-1])
+ x = window_unpartition(x, self.window_size, pad_hw, (H, W))
+ else:
+ B, H, W, C = x.shape
+ x = x.view(B, H * W, C)
+ x = self.attn(x, freqs_cis=freqs_cis)
+ x = x.view(B, H, W, C)
+ x = shortcut + x
+ x = x + self.mlp(self.norm2(x))
+ return x
+
+
+class PatchEmbed(nn.Module):
+ def __init__(self, patch_size=14, in_chans=3, embed_dim=1024, device=None, dtype=None, operations=None):
+ super().__init__()
+ self.proj = operations.Conv2d(in_chans, embed_dim, kernel_size=patch_size, stride=patch_size, bias=False, device=device, dtype=dtype)
+
+ def forward(self, x):
+ return self.proj(x)
+
+
+class ViTDet(nn.Module):
+ def __init__(self, img_size=1008, patch_size=14, embed_dim=1024, depth=32, num_heads=16, mlp_ratio=4.625, qkv_bias=True, window_size=24,
+ global_att_blocks=(7, 15, 23, 31), use_rope=True, pretrain_img_size=336, device=None, dtype=None, operations=None, **kwargs):
+ super().__init__()
+ self.img_size = img_size
+ self.patch_size = patch_size
+ self.embed_dim = embed_dim
+ self.num_heads = num_heads
+ self.global_att_blocks = set(global_att_blocks)
+
+ self.patch_embed = PatchEmbed(patch_size, 3, embed_dim, device=device, dtype=dtype, operations=operations)
+
+ num_patches = (pretrain_img_size // patch_size) ** 2 + 1 # +1 for cls token
+ self.pos_embed = nn.Parameter(torch.zeros(1, num_patches, embed_dim, device=device, dtype=dtype))
+
+ self.ln_pre = operations.LayerNorm(embed_dim, device=device, dtype=dtype)
+
+ grid_size = img_size // patch_size
+ pretrain_grid = pretrain_img_size // patch_size
+
+ self.blocks = nn.ModuleList()
+ for i in range(depth):
+ is_global = i in self.global_att_blocks
+ self.blocks.append(Block(
+ embed_dim, num_heads, mlp_ratio, qkv_bias,
+ window_size=0 if is_global else window_size,
+ use_rope=use_rope,
+ device=device, dtype=dtype, operations=operations,
+ ))
+
+ if use_rope:
+ rope_scale = pretrain_grid / grid_size
+ self.register_buffer("freqs_cis", rope_2d(grid_size, grid_size, embed_dim // num_heads, scale_pos=rope_scale), persistent=False)
+ self.register_buffer("freqs_cis_window", rope_2d(window_size, window_size, embed_dim // num_heads), persistent=False)
+ else:
+ self.freqs_cis = None
+ self.freqs_cis_window = None
+
+ def _get_pos_embed(self, num_tokens):
+ pos = self.pos_embed
+ if pos.shape[1] == num_tokens:
+ return pos
+ cls_pos = pos[:, :1]
+ spatial_pos = pos[:, 1:]
+ old_size = int(math.sqrt(spatial_pos.shape[1]))
+ new_size = int(math.sqrt(num_tokens - 1)) if num_tokens > 1 else old_size
+ spatial_2d = spatial_pos.reshape(1, old_size, old_size, -1).permute(0, 3, 1, 2)
+ tiles_h = new_size // old_size + 1
+ tiles_w = new_size // old_size + 1
+ tiled = spatial_2d.tile([1, 1, tiles_h, tiles_w])[:, :, :new_size, :new_size]
+ tiled = tiled.permute(0, 2, 3, 1).reshape(1, new_size * new_size, -1)
+ return torch.cat([cls_pos, tiled], dim=1)
+
+ def forward(self, x):
+ x = self.patch_embed(x)
+ B, C, Hp, Wp = x.shape
+ x = x.permute(0, 2, 3, 1).reshape(B, Hp * Wp, C)
+
+ pos = cast_to_input(self._get_pos_embed(Hp * Wp + 1), x)
+ x = x + pos[:, 1:Hp * Wp + 1]
+
+ x = x.view(B, Hp, Wp, C)
+ x = self.ln_pre(x)
+
+ freqs_cis_global = self.freqs_cis
+ freqs_cis_win = self.freqs_cis_window
+ if freqs_cis_global is not None:
+ freqs_cis_global = cast_to_input(freqs_cis_global, x)
+ if freqs_cis_win is not None:
+ freqs_cis_win = cast_to_input(freqs_cis_win, x)
+
+ for block in self.blocks:
+ fc = freqs_cis_win if block.window_size > 0 else freqs_cis_global
+ x = block(x, freqs_cis=fc)
+
+ return x.permute(0, 3, 1, 2)
+
+
+class FPNScaleConv(nn.Module):
+ def __init__(self, in_dim, out_dim, scale, device=None, dtype=None, operations=None):
+ super().__init__()
+ if scale == 4.0:
+ self.dconv_2x2_0 = operations.ConvTranspose2d(in_dim, in_dim // 2, kernel_size=2, stride=2, device=device, dtype=dtype)
+ self.dconv_2x2_1 = operations.ConvTranspose2d(in_dim // 2, in_dim // 4, kernel_size=2, stride=2, device=device, dtype=dtype)
+ proj_in = in_dim // 4
+ elif scale == 2.0:
+ self.dconv_2x2 = operations.ConvTranspose2d(in_dim, in_dim // 2, kernel_size=2, stride=2, device=device, dtype=dtype)
+ proj_in = in_dim // 2
+ elif scale == 1.0:
+ proj_in = in_dim
+ elif scale == 0.5:
+ self.pool = nn.MaxPool2d(kernel_size=2, stride=2)
+ proj_in = in_dim
+ self.scale = scale
+ self.conv_1x1 = operations.Conv2d(proj_in, out_dim, kernel_size=1, device=device, dtype=dtype)
+ self.conv_3x3 = operations.Conv2d(out_dim, out_dim, kernel_size=3, padding=1, device=device, dtype=dtype)
+
+ def forward(self, x):
+ if self.scale == 4.0:
+ x = F.gelu(self.dconv_2x2_0(x))
+ x = self.dconv_2x2_1(x)
+ elif self.scale == 2.0:
+ x = self.dconv_2x2(x)
+ elif self.scale == 0.5:
+ x = self.pool(x)
+ x = self.conv_1x1(x)
+ x = self.conv_3x3(x)
+ return x
+
+
+class PositionEmbeddingSine(nn.Module):
+ """2D sinusoidal position encoding (DETR-style) with result caching."""
+ def __init__(self, num_pos_feats=256, temperature=10000.0, normalize=True, scale=None):
+ super().__init__()
+ assert num_pos_feats % 2 == 0
+ self.half_dim = num_pos_feats // 2
+ self.temperature = temperature
+ self.normalize = normalize
+ self.scale = scale if scale is not None else 2 * math.pi
+ self._cache = {}
+
+ def _sincos(self, vals):
+ """Encode 1D values to interleaved sin/cos features."""
+ freqs = self.temperature ** (2 * (torch.arange(self.half_dim, dtype=torch.float32, device=vals.device) // 2) / self.half_dim)
+ raw = vals[..., None] * self.scale / freqs
+ return torch.stack((raw[..., 0::2].sin(), raw[..., 1::2].cos()), dim=-1).flatten(-2)
+
+ def _encode_xy(self, x, y):
+ """Encode normalized x, y coordinates to sinusoidal features. Returns (pos_x, pos_y) each [N, half_dim]."""
+ dim_t = self.temperature ** (2 * (torch.arange(self.half_dim, dtype=torch.float32, device=x.device) // 2) / self.half_dim)
+ pos_x = x[:, None] * self.scale / dim_t
+ pos_y = y[:, None] * self.scale / dim_t
+ pos_x = torch.stack((pos_x[:, 0::2].sin(), pos_x[:, 1::2].cos()), dim=2).flatten(1)
+ pos_y = torch.stack((pos_y[:, 0::2].sin(), pos_y[:, 1::2].cos()), dim=2).flatten(1)
+ return pos_x, pos_y
+
+ def encode_boxes(self, cx, cy, w, h):
+ """Encode box center + size to [N, d_model+2] features."""
+ pos_x, pos_y = self._encode_xy(cx, cy)
+ return torch.cat((pos_y, pos_x, h[:, None], w[:, None]), dim=1)
+
+ def forward(self, x):
+ B, C, H, W = x.shape
+ key = (H, W, x.device)
+ if key not in self._cache:
+ gy = torch.arange(H, dtype=torch.float32, device=x.device)
+ gx = torch.arange(W, dtype=torch.float32, device=x.device)
+ if self.normalize:
+ gy, gx = gy / (H - 1 + 1e-6), gx / (W - 1 + 1e-6)
+ yy, xx = torch.meshgrid(gy, gx, indexing="ij")
+ self._cache[key] = torch.cat((self._sincos(yy), self._sincos(xx)), dim=-1).permute(2, 0, 1).unsqueeze(0)
+ return self._cache[key].expand(B, -1, -1, -1)
+
+
+class SAM3VisionBackbone(nn.Module):
+ def __init__(self, embed_dim=1024, d_model=256, multiplex=False, device=None, dtype=None, operations=None, **kwargs):
+ super().__init__()
+ self.trunk = ViTDet(embed_dim=embed_dim, device=device, dtype=dtype, operations=operations, **kwargs)
+ self.position_encoding = PositionEmbeddingSine(num_pos_feats=d_model, normalize=True)
+ self.multiplex = multiplex
+
+ fpn_args = dict(device=device, dtype=dtype, operations=operations)
+ if multiplex:
+ scales = [4.0, 2.0, 1.0]
+ self.convs = nn.ModuleList([FPNScaleConv(embed_dim, d_model, s, **fpn_args) for s in scales])
+ self.propagation_convs = nn.ModuleList([FPNScaleConv(embed_dim, d_model, s, **fpn_args) for s in scales])
+ self.interactive_convs = nn.ModuleList([FPNScaleConv(embed_dim, d_model, s, **fpn_args) for s in scales])
+ else:
+ scales = [4.0, 2.0, 1.0, 0.5]
+ self.convs = nn.ModuleList([FPNScaleConv(embed_dim, d_model, s, **fpn_args) for s in scales])
+ self.sam2_convs = nn.ModuleList([FPNScaleConv(embed_dim, d_model, s, **fpn_args) for s in scales])
+
+ def forward(self, images, need_tracker=False, tracker_mode=None, cached_trunk=None, tracker_only=False):
+ backbone_out = cached_trunk if cached_trunk is not None else self.trunk(images)
+
+ if tracker_only:
+ # Skip detector FPN when only tracker features are needed (video tracking)
+ if self.multiplex:
+ tracker_convs = self.propagation_convs if tracker_mode == "propagation" else self.interactive_convs
+ else:
+ tracker_convs = self.sam2_convs
+ tracker_features = [conv(backbone_out) for conv in tracker_convs]
+ tracker_positions = [cast_to_input(self.position_encoding(f), f) for f in tracker_features]
+ return None, None, tracker_features, tracker_positions
+
+ features = [conv(backbone_out) for conv in self.convs]
+ positions = [cast_to_input(self.position_encoding(f), f) for f in features]
+
+ if self.multiplex:
+ if tracker_mode == "propagation":
+ tracker_convs = self.propagation_convs
+ elif tracker_mode == "interactive":
+ tracker_convs = self.interactive_convs
+ else:
+ return features, positions, None, None
+ elif need_tracker:
+ tracker_convs = self.sam2_convs
+ else:
+ return features, positions, None, None
+
+ tracker_features = [conv(backbone_out) for conv in tracker_convs]
+ tracker_positions = [cast_to_input(self.position_encoding(f), f) for f in tracker_features]
+ return features, positions, tracker_features, tracker_positions
diff --git a/ComfyUI/comfy/ldm/sam3/tracker.py b/ComfyUI/comfy/ldm/sam3/tracker.py
new file mode 100644
index 0000000000000000000000000000000000000000..8456e90a617cfcf166307cb0542219e6e3a333cb
--- /dev/null
+++ b/ComfyUI/comfy/ldm/sam3/tracker.py
@@ -0,0 +1,1802 @@
+# SAM3 video tracker: memory encoder, memory attention, SAM mask decoder/prompt encoder.
+
+import numpy as np
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+from tqdm import tqdm
+
+try:
+ import cv2
+ _HAS_CV2 = True
+except ImportError:
+ from scipy import ndimage
+ _HAS_CV2 = False
+
+import comfy.model_management
+from comfy.ldm.modules.attention import optimized_attention
+from comfy.ldm.sam3.sam import rope_2d, PositionEmbeddingSine
+from comfy.ops import cast_to_input
+from comfy.ldm.flux.math import apply_rope1
+from comfy.ldm.cascade.common import LayerNorm2d_op
+from comfy.ldm.sam3.sam import MLP, PositionEmbeddingRandom
+from comfy.ldm.sam3.sam import TwoWayTransformer as SAMTwoWayTransformer
+
+NO_OBJ_SCORE = -1024.0
+
+
+def to_spatial(x, H, W):
+ """Reshape (B, H*W, C) → (B, C, H, W)."""
+ return x.view(x.shape[0], H, W, -1).permute(0, 3, 1, 2)
+
+class MultiplexState:
+ """Tracks object-to-slot assignments for multiplex tracking. Provides mux/demux operations."""
+
+ def __init__(self, num_objects, multiplex_count, device, dtype):
+ self.multiplex_count = multiplex_count
+ self.device = device
+ self.dtype = dtype
+ self._build(num_objects)
+
+ def mux(self, x):
+ """[N_obj, ...] -> [num_buckets, multiplex_count, ...]"""
+ out_shape = (self.num_buckets, self.multiplex_count) + x.shape[1:]
+ return (self.mux_matrix.to(device=x.device, dtype=x.dtype) @ x.reshape(self.total_valid_entries, -1)).view(out_shape)
+
+ def demux(self, x):
+ """[num_buckets, multiplex_count, ...] -> [N_obj, ...]"""
+ out_shape = (self.total_valid_entries,) + x.shape[2:]
+ flat = x.reshape(self.num_buckets * self.multiplex_count, -1)
+ return (self.demux_matrix.to(device=x.device, dtype=x.dtype) @ flat).view(out_shape)
+
+ def get_valid_object_mask(self):
+ """[num_buckets, multiplex_count] bool tensor, True for valid slots."""
+ return (self.mux_matrix.sum(dim=1) > 0).reshape(self.num_buckets, self.multiplex_count)
+
+ def _build(self, num_objects):
+ M = self.multiplex_count
+ self.num_buckets = (num_objects + M - 1) // M
+ self.total_valid_entries = num_objects
+ total_slots = self.num_buckets * M
+ self.mux_matrix = torch.zeros(total_slots, num_objects, device=self.device, dtype=self.dtype)
+ self.demux_matrix = torch.zeros(num_objects, total_slots, device=self.device, dtype=self.dtype)
+ oids = torch.arange(num_objects, device=self.device)
+ slots = (oids // M) * M + (oids % M)
+ self.mux_matrix[slots, oids] = 1.0
+ self.demux_matrix[oids, slots] = 1.0
+
+ def add_objects(self, n_new):
+ """Grow multiplex state for n_new additional objects."""
+ self._build(self.total_valid_entries + n_new)
+
+def _compute_mask_overlap(masks_a, masks_b):
+ """Max of IoU and IoM (intersection over minimum area). More robust to size differences."""
+ a_flat = (masks_a > 0).float().flatten(1)
+ b_flat = (masks_b > 0).float().flatten(1)
+ intersection = a_flat @ b_flat.T
+ area_a = a_flat.sum(1, keepdim=True)
+ area_b = b_flat.sum(1, keepdim=True).T
+ iou = intersection / (area_a + area_b - intersection).clamp(min=1)
+ iom = intersection / torch.min(area_a.expand_as(iou), area_b.expand_as(iou)).clamp(min=1)
+ return torch.max(iou, iom)
+
+
+def _nms_masks(masks, scores, thresh=0.5):
+ """Mask-based NMS using IoU+IoM overlap. Returns (filtered_masks, filtered_scores)."""
+ order = scores.argsort(descending=True)
+ masks, scores = masks[order], scores[order]
+ keep = []
+ for i in range(masks.shape[0]):
+ if keep:
+ if _compute_mask_overlap(masks[i:i+1], masks[torch.tensor(keep, device=masks.device)]).max() >= thresh:
+ continue
+ keep.append(i)
+ return masks[keep], scores[keep]
+
+
+def _get_connected_components(mask_bin):
+ """Get connected component labels and areas. mask_bin: [B, 1, H, W] uint8."""
+ labels_list, areas_list = [], []
+ for i in range(mask_bin.shape[0]):
+ m = mask_bin[i, 0].cpu().numpy()
+ if _HAS_CV2:
+ _, labeled, stats, _ = cv2.connectedComponentsWithStats(m, connectivity=8)
+ areas = stats[labeled, cv2.CC_STAT_AREA].astype('int32')
+ else:
+ labeled, num_features = ndimage.label(m)
+ areas = np.zeros_like(m, dtype=np.int32)
+ for c in range(1, num_features + 1):
+ component = labeled == c
+ areas[component] = component.sum()
+ labels_list.append(torch.from_numpy(labeled).to(mask_bin.device))
+ areas_list.append(torch.from_numpy(areas).to(device=mask_bin.device, dtype=torch.int32))
+ return torch.stack(labels_list).unsqueeze(1), torch.stack(areas_list).unsqueeze(1)
+
+
+def fill_holes_in_mask_scores(mask, max_area=0):
+ """Remove small foreground sprinkles and fill small background holes using connected components."""
+ if max_area <= 0:
+ return mask
+
+ # Fill holes: small connected components in background → foreground
+ mask_bg = (mask <= 0).to(torch.uint8)
+ _, areas_bg = _get_connected_components(mask_bg)
+ small_bg = mask_bg.bool() & (areas_bg <= max_area)
+ mask = torch.where(small_bg, 0.1, mask)
+
+ # Remove sprinkles: small connected components in foreground → background
+ # Only remove if area < min(max_area, half of total foreground area)
+ mask_fg = (mask > 0).to(torch.uint8)
+ fg_area_thresh = mask_fg.sum(dim=(2, 3), keepdim=True, dtype=torch.int32)
+ fg_area_thresh.floor_divide_(2).clamp_(max=max_area)
+ _, areas_fg = _get_connected_components(mask_fg)
+ small_fg = mask_fg.bool() & (areas_fg <= fg_area_thresh)
+ mask = torch.where(small_fg, -0.1, mask)
+
+ return mask
+
+
+def apply_rope_memory(q, k, freqs, num_heads, num_k_exclude_rope=0):
+ """Apply 2D axial RoPE to memory attention using flux rope format.
+
+ Args:
+ q: [B, Nq, C] projected queries (current frame features)
+ k: [B, Nk, C] projected keys (memory tokens)
+ freqs: [1, Nq, dim//2, 2, 2] flux-format rotation matrices for one frame
+ num_heads: number of attention heads
+ num_k_exclude_rope: number of trailing k tokens to skip RoPE (object pointers)
+ """
+ B, Nq, C = q.shape
+ head_dim = C // num_heads
+
+ # freqs shape: [1, 1, Nq, dim//2, 2, 2] (heads broadcast dim already included)
+ q_h = q.view(B, Nq, num_heads, head_dim).transpose(1, 2)
+ q_h = apply_rope1(q_h, freqs)
+ q = q_h.transpose(1, 2).reshape(B, Nq, C)
+
+ # Apply RoPE to k (excluding last num_k_exclude_rope tokens)
+ Nk = k.shape[1]
+ num_k_rope = Nk - num_k_exclude_rope
+ if num_k_rope > 0:
+ # Repeat freqs for multiple frames of spatial memory
+ Nf = freqs.shape[2] # spatial positions in one frame
+ if num_k_rope > Nf:
+ r = (num_k_rope + Nf - 1) // Nf
+ pe_k = freqs.repeat(1, 1, r, 1, 1, 1)[:, :, :num_k_rope]
+ else:
+ pe_k = freqs[:, :, :num_k_rope]
+
+ k_h = k[:, :num_k_rope].view(B, num_k_rope, num_heads, head_dim).transpose(1, 2)
+ k_h = apply_rope1(k_h, pe_k)
+ k = k.clone()
+ k[:, :num_k_rope] = k_h.transpose(1, 2).reshape(B, num_k_rope, C)
+
+ return q, k
+
+
+def get_1d_sine_pe(pos_inds, dim, temperature=10000):
+ """1D sinusoidal positional encoding for temporal positions."""
+ pe_dim = dim // 2
+ dim_t = torch.arange(pe_dim, dtype=torch.float32, device=pos_inds.device)
+ dim_t = temperature ** (2 * (dim_t // 2) / pe_dim)
+ pos_embed = pos_inds.unsqueeze(-1) / dim_t
+ return torch.cat([pos_embed.sin(), pos_embed.cos()], dim=-1)
+
+
+def _pad_to_buckets(tensor, target_buckets):
+ """Pad a [num_buckets, ...] tensor to target_buckets along dim 0 if needed."""
+ if tensor.shape[0] >= target_buckets:
+ return tensor
+ pad_shape = (target_buckets - tensor.shape[0],) + tensor.shape[1:]
+ return torch.cat([tensor, torch.zeros(pad_shape, device=tensor.device, dtype=tensor.dtype)], dim=0)
+
+
+def pack_masks(masks):
+ """Pack binary masks [*, H, W] to bit-packed [*, H, W//8] uint8. W must be divisible by 8."""
+ binary = masks > 0
+ shifts = torch.arange(8, device=masks.device)
+ return (binary.view(*masks.shape[:-1], -1, 8) * (1 << shifts)).sum(-1).byte()
+
+
+def unpack_masks(packed):
+ """Unpack bit-packed [*, H, W//8] uint8 to bool [*, H, W*8]."""
+ bits = torch.tensor([1, 2, 4, 8, 16, 32, 64, 128], dtype=torch.uint8, device=packed.device)
+ return (packed.unsqueeze(-1) & bits).bool().view(*packed.shape[:-1], -1)
+
+
+def _prep_frame(images, idx, device, dt, size):
+ """Slice CPU full-res frames, transfer to GPU in target dtype, and resize to (size, size)."""
+ return comfy.utils.common_upscale(images[idx].to(device=device, dtype=dt), size, size, "bicubic", crop="disabled")
+
+
+def _compute_backbone(backbone_fn, frame, frame_idx=None):
+ """Compute backbone features for a single frame. Returns (vision_feats, vision_pos, feat_sizes, features, trunk_out)."""
+ features, positions, trunk_out = backbone_fn(frame, frame_idx=frame_idx)
+ feat_sizes = [(x.shape[-2], x.shape[-1]) for x in features]
+ vision_feats = [x.flatten(2).permute(0, 2, 1) for x in features]
+ vision_pos = [x.flatten(2).permute(0, 2, 1) for x in positions]
+ return vision_feats, vision_pos, feat_sizes, features, trunk_out
+
+
+def collect_memory_tokens(output_dict, frame_idx, num_maskmem, maskmem_tpos_enc, device,
+ collect_image_feats=False, tpos_v2=False, num_buckets=None):
+ """Collect spatial memory, position encodings, and optionally image features from past frames."""
+ to_cat_memory, to_cat_memory_pos = [], []
+ to_cat_image_feat, to_cat_image_pos = [], []
+
+ def _append(out, tpos_idx):
+ feats = out["maskmem_features"].to(device)
+ if num_buckets is not None:
+ feats = _pad_to_buckets(feats, num_buckets)
+ to_cat_memory.append(feats.flatten(2).permute(0, 2, 1))
+ enc = out["maskmem_pos_enc"][-1].to(device).flatten(2).permute(0, 2, 1)
+ if num_buckets is not None:
+ enc = _pad_to_buckets(enc, num_buckets)
+ tpos = cast_to_input(maskmem_tpos_enc[tpos_idx], enc)
+ to_cat_memory_pos.append(enc + tpos)
+ if collect_image_feats and "image_features" in out:
+ to_cat_image_feat.append(out["image_features"].to(device))
+ to_cat_image_pos.append(out["image_pos_enc"].to(device) + tpos)
+
+ cond_outputs = output_dict["cond_frame_outputs"]
+ for t, out in cond_outputs.items():
+ if tpos_v2:
+ t_pos = frame_idx - t
+ tpos_idx = num_maskmem - t_pos - 1 if 0 < t_pos < num_maskmem else num_maskmem - 1
+ else:
+ tpos_idx = num_maskmem - 1
+ _append(out, tpos_idx)
+
+ for t_pos in range(1, num_maskmem):
+ out = output_dict["non_cond_frame_outputs"].get(frame_idx - (num_maskmem - t_pos), None)
+ if out is None or out.get("maskmem_features") is None:
+ continue
+ _append(out, num_maskmem - t_pos - 1)
+
+ return to_cat_memory, to_cat_memory_pos, to_cat_image_feat, to_cat_image_pos, cond_outputs
+
+
+def compute_tpos_enc(rel_pos_list, device, d_model, proj_layer, dtype=None, max_abs_pos=None):
+ """Temporal position encoding for object pointers."""
+ pos_enc = torch.tensor(rel_pos_list, dtype=torch.float32, device=device) / max((max_abs_pos or 2) - 1, 1)
+ pos_enc = get_1d_sine_pe(pos_enc, dim=d_model)
+ if dtype is not None:
+ pos_enc = pos_enc.to(dtype)
+ return proj_layer(pos_enc)
+
+
+def forward_sam_heads(backbone_features, prompt_encoder, mask_decoder, obj_ptr_proj, no_obj_fn,
+ image_size, point_inputs=None, mask_inputs=None, box_inputs=None,
+ high_res_features=None, multimask_output=False):
+ """Shared SAM prompt encoder + mask decoder forward for both SAM3 and SAM3.1 trackers."""
+ device = backbone_features.device
+ # Batch size from inputs (mask_inputs may have N_obj > 1 while backbone is batch 1)
+ if mask_inputs is not None:
+ B = mask_inputs.shape[0]
+ elif box_inputs is not None:
+ B = box_inputs.shape[0]
+ elif point_inputs is not None:
+ B = point_inputs["point_coords"].shape[0]
+ else:
+ B = backbone_features.shape[0]
+
+ if point_inputs is not None:
+ sam_point_coords = point_inputs["point_coords"]
+ sam_point_labels = point_inputs["point_labels"]
+ else:
+ sam_point_coords = torch.zeros(B, 1, 2, device=device)
+ sam_point_labels = -torch.ones(B, 1, dtype=torch.int32, device=device)
+
+ if mask_inputs is not None:
+ prompt_size = (prompt_encoder.image_embedding_size[0] * 4, prompt_encoder.image_embedding_size[1] * 4)
+ if mask_inputs.shape[-2:] != prompt_size:
+ sam_mask_prompt = F.interpolate(mask_inputs, size=prompt_size, mode="bilinear", align_corners=False, antialias=True)
+ else:
+ sam_mask_prompt = mask_inputs
+ else:
+ sam_mask_prompt = None
+
+ sparse, dense = prompt_encoder(points=(sam_point_coords, sam_point_labels), boxes=box_inputs, masks=sam_mask_prompt)
+ sparse = cast_to_input(sparse, backbone_features)
+ dense = cast_to_input(dense, backbone_features)
+ image_pe = cast_to_input(prompt_encoder.get_dense_pe(), backbone_features)
+
+ low_res_multimasks, ious, sam_output_tokens, object_score_logits = mask_decoder(
+ image_embeddings=backbone_features, image_pe=image_pe,
+ sparse_prompt_embeddings=sparse, dense_prompt_embeddings=dense,
+ high_res_features=high_res_features, multimask_output=multimask_output, return_all=True,
+ )
+
+ is_obj_appearing = object_score_logits > 0
+ low_res_multimasks = torch.where(is_obj_appearing[:, None, None], low_res_multimasks,
+ torch.tensor(NO_OBJ_SCORE, device=device, dtype=low_res_multimasks.dtype))
+ high_res_multimasks = F.interpolate(low_res_multimasks, size=(image_size, image_size), mode="bilinear", align_corners=False)
+
+ sam_output_token = sam_output_tokens[:, 0]
+ if multimask_output:
+ best_iou_inds = torch.argmax(ious, dim=-1)
+ batch_inds = torch.arange(B, device=device)
+ low_res_masks = low_res_multimasks[batch_inds, best_iou_inds].unsqueeze(1)
+ high_res_masks = high_res_multimasks[batch_inds, best_iou_inds].unsqueeze(1)
+ if sam_output_tokens.size(1) > 1:
+ sam_output_token = sam_output_tokens[batch_inds, best_iou_inds]
+ else:
+ low_res_masks, high_res_masks = low_res_multimasks, high_res_multimasks
+
+ obj_ptr = obj_ptr_proj(sam_output_token)
+ obj_ptr = no_obj_fn(obj_ptr, is_obj_appearing)
+
+ return low_res_masks, high_res_masks, obj_ptr, object_score_logits
+
+
+def use_mask_as_output(backbone_features, high_res_features, mask_inputs, mask_downsample,
+ prompt_encoder, mask_decoder, obj_ptr_proj, no_obj_fn, image_size, backbone_stride):
+ """Shared mask-as-output for both SAM3 and SAM3.1 trackers."""
+ out_scale, out_bias = 20.0, -10.0
+ mask_inputs_float = cast_to_input(mask_inputs, backbone_features)
+ high_res_masks = mask_inputs_float * out_scale + out_bias
+ low_res_masks = F.interpolate(high_res_masks, size=(image_size // backbone_stride * 4,) * 2,
+ mode="bilinear", align_corners=False, antialias=True)
+ _, _, obj_ptr, _ = forward_sam_heads(
+ backbone_features, prompt_encoder, mask_decoder, obj_ptr_proj, no_obj_fn,
+ image_size, mask_inputs=mask_downsample(mask_inputs_float), high_res_features=high_res_features,
+ )
+ is_obj_appearing = torch.any(mask_inputs.flatten(1) > 0.0, dim=1)[..., None]
+ alpha = is_obj_appearing.to(obj_ptr.dtype)
+ object_score_logits = out_scale * alpha + out_bias
+ return low_res_masks, high_res_masks, obj_ptr, object_score_logits
+
+
+# Split attention with configurable input dims (for asymmetric cross-attention)
+class SplitAttn(nn.Module):
+ def __init__(self, embed_dim, num_heads=1, kv_dim=None, internal_dim=None, device=None, dtype=None, operations=None):
+ super().__init__()
+ self.num_heads = num_heads
+ kv_dim = kv_dim or embed_dim
+ internal_dim = internal_dim or embed_dim
+ self.q_proj = operations.Linear(embed_dim, internal_dim, device=device, dtype=dtype)
+ self.k_proj = operations.Linear(kv_dim, internal_dim, device=device, dtype=dtype)
+ self.v_proj = operations.Linear(kv_dim, internal_dim, device=device, dtype=dtype)
+ self.out_proj = operations.Linear(internal_dim, embed_dim, device=device, dtype=dtype)
+
+ def forward(self, q, k=None, v=None, rope=None, num_k_exclude_rope=0):
+ if k is None:
+ k = q
+ if v is None:
+ v = k
+ q = self.q_proj(q)
+ k = self.k_proj(k)
+ v = self.v_proj(v)
+ if rope is not None:
+ q, k = apply_rope_memory(q, k, rope, self.num_heads, num_k_exclude_rope)
+ out = optimized_attention(q, k, v, self.num_heads, low_precision_attention=False)
+ return self.out_proj(out)
+
+
+class MemoryAttnLayer(nn.Module):
+ def __init__(self, d_model=256, num_heads=1, kv_dim=64, dim_ff=2048, device=None, dtype=None, operations=None):
+ super().__init__()
+ self.num_heads = num_heads
+ self.self_attn = SplitAttn(d_model, num_heads, device=device, dtype=dtype, operations=operations)
+ self.cross_attn_image = SplitAttn(d_model, num_heads, kv_dim=kv_dim, device=device, dtype=dtype, operations=operations)
+ self.linear1 = operations.Linear(d_model, dim_ff, device=device, dtype=dtype)
+ self.linear2 = operations.Linear(dim_ff, d_model, device=device, dtype=dtype)
+ self.norm1 = operations.LayerNorm(d_model, device=device, dtype=dtype)
+ self.norm2 = operations.LayerNorm(d_model, device=device, dtype=dtype)
+ self.norm3 = operations.LayerNorm(d_model, device=device, dtype=dtype)
+
+ def forward(self, x, memory, memory_pos=None, rope=None, num_k_exclude_rope=0):
+ x = x + self.self_attn(self.norm1(x), rope=rope)
+ mem_k = memory + memory_pos if memory_pos is not None else memory
+ x = x + self.cross_attn_image(self.norm2(x), mem_k, memory, rope=rope, num_k_exclude_rope=num_k_exclude_rope)
+ normed = self.norm3(x)
+ x = x + self.linear2(F.relu(self.linear1(normed)))
+ return x
+
+
+class MemoryAttnEncoder(nn.Module):
+ def __init__(self, d_model=256, num_heads=1, kv_dim=64, dim_ff=2048, num_layers=4, image_size=1008, patch_size=14,
+ device=None, dtype=None, operations=None):
+ super().__init__()
+ self.layers = nn.ModuleList([
+ MemoryAttnLayer(d_model, num_heads, kv_dim, dim_ff, device=device, dtype=dtype, operations=operations)
+ for _ in range(num_layers)
+ ])
+ self.norm = operations.LayerNorm(d_model, device=device, dtype=dtype)
+ hw = image_size // patch_size
+ self.register_buffer("_rope", rope_2d(hw, hw, d_model // num_heads), persistent=False)
+
+ def forward(self, x, memory, src_pos=None, memory_pos=None, num_k_exclude_rope=0):
+ if src_pos is not None:
+ x = x + 0.1 * src_pos
+
+ rope = self._rope.to(device=x.device)
+ for layer in self.layers:
+ x = layer(x, memory, memory_pos=memory_pos, rope=rope, num_k_exclude_rope=num_k_exclude_rope)
+ return self.norm(x)
+
+
+class MemoryTransformer(nn.Module):
+ def __init__(self, d_model=256, num_heads=1, kv_dim=64, dim_ff=2048, num_layers=4, device=None, dtype=None, operations=None):
+ super().__init__()
+ self.encoder = MemoryAttnEncoder(d_model, num_heads, kv_dim, dim_ff, num_layers, device=device, dtype=dtype, operations=operations)
+
+
+def _upscale_masks(output_upscaling, conv_s0, conv_s1, src_out, high_res_features):
+ """Shared upscaling for SAM mask decoders: deconv + high-res feature integration."""
+ dc1, ln1, act1, dc2, act2 = output_upscaling
+ if high_res_features is not None:
+ upscaled = act1(ln1(dc1(src_out) + conv_s1(high_res_features[1])))
+ upscaled = act2(dc2(upscaled) + conv_s0(high_res_features[0]))
+ else:
+ upscaled = act2(dc2(act1(ln1(dc1(src_out)))))
+ return upscaled
+
+
+class SAMMaskDecoder(nn.Module):
+ def __init__(self, d_model=256, num_multimask_outputs=3, device=None, dtype=None, operations=None):
+ super().__init__()
+ self.num_mask_tokens = num_multimask_outputs + 1
+
+ self.transformer = SAMTwoWayTransformer(depth=2, embedding_dim=d_model, num_heads=8, mlp_dim=2048, device=device, dtype=dtype, operations=operations)
+
+ self.iou_token = operations.Embedding(1, d_model, device=device, dtype=dtype)
+ self.mask_tokens = operations.Embedding(self.num_mask_tokens, d_model, device=device, dtype=dtype)
+ self.obj_score_token = operations.Embedding(1, d_model, device=device, dtype=dtype)
+
+ # Output upscaling: d_model -> d_model//4 -> d_model//8 at 4x resolution
+ LN2d = LayerNorm2d_op(operations)
+ self.output_upscaling = nn.Sequential(
+ operations.ConvTranspose2d(d_model, d_model // 4, kernel_size=2, stride=2, device=device, dtype=dtype), LN2d(d_model // 4, device=device, dtype=dtype), nn.GELU(),
+ operations.ConvTranspose2d(d_model // 4, d_model // 8, kernel_size=2, stride=2, device=device, dtype=dtype), nn.GELU(),
+ )
+
+ # High-res feature integration
+ self.conv_s0 = operations.Conv2d(d_model, d_model // 8, kernel_size=1, device=device, dtype=dtype)
+ self.conv_s1 = operations.Conv2d(d_model, d_model // 4, kernel_size=1, device=device, dtype=dtype)
+
+ # Per-mask hypernetwork MLPs
+ self.output_hypernetworks_mlps = nn.ModuleList([
+ MLP(d_model, d_model, d_model // 8, 3, device=device, dtype=dtype, operations=operations)
+ for _ in range(self.num_mask_tokens)
+ ])
+
+ self.iou_prediction_head = MLP(d_model, d_model, self.num_mask_tokens, 3, device=device, dtype=dtype, operations=operations)
+ self.pred_obj_score_head = MLP(d_model, d_model, 1, 3, device=device, dtype=dtype, operations=operations)
+
+ def forward(self, image_embeddings, image_pe, sparse_prompt_embeddings, dense_prompt_embeddings,
+ high_res_features=None, multimask_output=False, return_all=False):
+ B = sparse_prompt_embeddings.shape[0]
+ ref = sparse_prompt_embeddings
+ # Token order: [obj_score(1), iou(1), mask(num_mask_tokens)]
+ tokens = torch.cat([cast_to_input(self.obj_score_token.weight, ref),
+ cast_to_input(self.iou_token.weight, ref),
+ cast_to_input(self.mask_tokens.weight, ref)], dim=0)
+ tokens = torch.cat([tokens.unsqueeze(0).expand(B, -1, -1), sparse_prompt_embeddings], dim=1)
+
+ src = image_embeddings
+ if src.shape[0] != B:
+ src = src.expand(B, -1, -1, -1)
+ src = src + dense_prompt_embeddings
+ pos_src = image_pe.expand(B, -1, -1, -1)
+
+ b, c, h, w = src.shape
+ src_flat = src.flatten(2).permute(0, 2, 1)
+ pos_flat = pos_src.flatten(2).permute(0, 2, 1)
+
+ hs, src_out = self.transformer(src_flat, pos_flat, tokens)
+
+ obj_score_token_out = hs[:, 0, :]
+ iou_token_out = hs[:, 1, :]
+ mask_tokens_out = hs[:, 2:2 + self.num_mask_tokens, :]
+
+ src_out = src_out.permute(0, 2, 1).view(b, c, h, w)
+ upscaled = _upscale_masks(self.output_upscaling, self.conv_s0, self.conv_s1, src_out, high_res_features)
+
+ hyper_in = torch.stack([
+ mlp(mask_tokens_out[:, i, :]) for i, mlp in enumerate(self.output_hypernetworks_mlps)
+ ], dim=1)
+
+ masks = (hyper_in @ upscaled.flatten(2)).view(B, self.num_mask_tokens, upscaled.shape[2], upscaled.shape[3])
+ iou_pred = self.iou_prediction_head(iou_token_out)
+ object_score_logits = self.pred_obj_score_head(obj_score_token_out)
+
+ if multimask_output:
+ out_masks = masks[:, 1:]
+ out_iou = iou_pred[:, 1:]
+ out_tokens = mask_tokens_out[:, 1:]
+ else:
+ out_masks = masks[:, 0:1]
+ out_iou = iou_pred[:, 0:1]
+ out_tokens = mask_tokens_out[:, 0:1]
+
+ if return_all:
+ return out_masks, out_iou, out_tokens, object_score_logits
+ return out_masks, out_iou
+
+
+class SAMPromptEncoder(nn.Module):
+ def __init__(self, d_model=256, image_embedding_size=(72, 72), input_image_size=(1008, 1008), device=None, dtype=None, operations=None):
+ super().__init__()
+ self.embed_dim = d_model
+ self.image_embedding_size = image_embedding_size
+ self.input_image_size = input_image_size
+
+ self.pe_layer = PositionEmbeddingRandom(d_model // 2)
+ self.point_embeddings = nn.ModuleList([
+ operations.Embedding(1, d_model, device=device, dtype=dtype) for _ in range(4)
+ ])
+ self.not_a_point_embed = operations.Embedding(1, d_model, device=device, dtype=dtype)
+
+ LN2d = LayerNorm2d_op(operations)
+ self.mask_downscaling = nn.Sequential(
+ operations.Conv2d(1, 4, kernel_size=2, stride=2, device=device, dtype=dtype),
+ LN2d(4, device=device, dtype=dtype), nn.GELU(),
+ operations.Conv2d(4, 16, kernel_size=2, stride=2, device=device, dtype=dtype),
+ LN2d(16, device=device, dtype=dtype), nn.GELU(),
+ operations.Conv2d(16, d_model, kernel_size=1, device=device, dtype=dtype),
+ )
+ self.no_mask_embed = operations.Embedding(1, d_model, device=device, dtype=dtype)
+
+ def get_dense_pe(self):
+ return self.pe_layer(self.image_embedding_size)
+
+ def forward(self, points=None, boxes=None, masks=None):
+ ref = points[0] if points is not None else boxes if boxes is not None else masks
+ B = 1
+ sparse = torch.empty((B, 0, self.embed_dim), device=ref.device, dtype=ref.dtype)
+
+ if points is not None:
+ coords, labels = points
+ B = coords.shape[0]
+ # Pad with an extra point (label=-1) when no boxes are provided (matching reference)
+ if boxes is None:
+ coords = torch.cat([coords, torch.zeros(B, 1, 2, device=coords.device, dtype=coords.dtype)], dim=1)
+ labels = torch.cat([labels, -torch.ones(B, 1, device=labels.device, dtype=labels.dtype)], dim=1)
+ pe = self.pe_layer.forward_with_coords(coords + 0.5, self.input_image_size)
+ for i in range(4):
+ pe[labels == i] += cast_to_input(self.point_embeddings[i].weight, ref)
+ invalid = (labels == -1)
+ pe[invalid] = 0.0
+ pe[invalid] += cast_to_input(self.not_a_point_embed.weight, ref)
+ sparse = torch.cat([sparse.expand(B, -1, -1), pe], dim=1)
+
+ if boxes is not None:
+ B = boxes.shape[0]
+ corners = self.pe_layer.forward_with_coords((boxes.reshape(-1, 2, 2) + 0.5), self.input_image_size)
+ corners[:, 0] += cast_to_input(self.point_embeddings[2].weight, ref)
+ corners[:, 1] += cast_to_input(self.point_embeddings[3].weight, ref)
+ sparse = torch.cat([sparse.expand(B, -1, -1), corners], dim=1)
+
+ if masks is not None:
+ dense = self.mask_downscaling(masks)
+ else:
+ dense = cast_to_input(self.no_mask_embed.weight, ref).reshape(1, -1, 1, 1).expand(
+ B, -1, self.image_embedding_size[0], self.image_embedding_size[1])
+
+ return sparse, dense
+
+
+class CXBlock(nn.Module):
+ def __init__(self, dim=256, kernel_size=7, device=None, dtype=None, operations=None):
+ super().__init__()
+ self.dwconv = operations.Conv2d(dim, dim, kernel_size=kernel_size, padding=kernel_size // 2, groups=dim, device=device, dtype=dtype)
+ self.norm = operations.LayerNorm(dim, device=device, dtype=dtype)
+ self.pwconv1 = operations.Linear(dim, 4 * dim, device=device, dtype=dtype)
+ self.pwconv2 = operations.Linear(4 * dim, dim, device=device, dtype=dtype)
+ self.gamma = nn.Parameter(torch.ones(dim, device=device, dtype=dtype))
+
+ def forward(self, x):
+ residual = x
+ x = self.dwconv(x).permute(0, 2, 3, 1)
+ x = self.pwconv2(F.gelu(self.pwconv1(self.norm(x))))
+ x.mul_(cast_to_input(self.gamma, x))
+ return residual + x.permute(0, 3, 1, 2)
+
+
+class MaskDownSampler(nn.Module):
+ def __init__(self, out_dim=256, in_chans=1, channels=None, interpol_size=(1152, 1152), device=None, dtype=None, operations=None):
+ super().__init__()
+ self.interpol_size = list(interpol_size) if interpol_size else None
+ if channels is None:
+ channels = [4, 16, 64, out_dim] # SAM3 default
+ LN2d = LayerNorm2d_op(operations)
+ layers = []
+ prev = in_chans
+ for ch in channels:
+ layers += [operations.Conv2d(prev, ch, kernel_size=3, stride=2, padding=1, device=device, dtype=dtype),
+ LN2d(ch, device=device, dtype=dtype), nn.GELU()]
+ prev = ch
+ layers.append(operations.Conv2d(prev, out_dim, kernel_size=1, device=device, dtype=dtype))
+ self.encoder = nn.Sequential(*layers)
+
+ def forward(self, x):
+ if self.interpol_size is not None and list(x.shape[-2:]) != self.interpol_size:
+ x = F.interpolate(x, size=self.interpol_size, mode="bilinear", align_corners=False, antialias=True)
+ return self.encoder(x)
+
+
+class Fuser(nn.Module):
+ def __init__(self, dim=256, num_layers=2, device=None, dtype=None, operations=None):
+ super().__init__()
+ self.layers = nn.Sequential(*[CXBlock(dim, device=device, dtype=dtype, operations=operations) for _ in range(num_layers)])
+
+ def forward(self, x):
+ return self.layers(x)
+
+
+# --- SAM3.1 Multiplex components ---
+
+class DecoupledMemoryAttnLayer(nn.Module):
+ """Decoupled cross-attention layer for SAM3.1: fuses image and memory projections."""
+
+ def __init__(self, d_model=256, num_heads=1, dim_ff=2048, device=None, dtype=None, operations=None):
+ super().__init__()
+ self.num_heads = num_heads
+ # Self-attention projections (flat, not nested)
+ self.self_attn_q_proj = operations.Linear(d_model, d_model, device=device, dtype=dtype)
+ self.self_attn_k_proj = operations.Linear(d_model, d_model, device=device, dtype=dtype)
+ self.self_attn_v_proj = operations.Linear(d_model, d_model, device=device, dtype=dtype)
+ self.self_attn_out_proj = operations.Linear(d_model, d_model, device=device, dtype=dtype)
+ # Cross-attention projections
+ self.cross_attn_q_proj = operations.Linear(d_model, d_model, device=device, dtype=dtype)
+ self.cross_attn_k_proj = operations.Linear(d_model, d_model, device=device, dtype=dtype)
+ self.cross_attn_v_proj = operations.Linear(d_model, d_model, device=device, dtype=dtype)
+ self.cross_attn_out_proj = operations.Linear(d_model, d_model, device=device, dtype=dtype)
+ # Image cross-attention (q/k only, fused with cross_attn)
+ self.image_cross_attn_q_proj = operations.Linear(d_model, d_model, device=device, dtype=dtype)
+ self.image_cross_attn_k_proj = operations.Linear(d_model, d_model, device=device, dtype=dtype)
+ # FFN
+ self.linear1 = operations.Linear(d_model, dim_ff, device=device, dtype=dtype)
+ self.linear2 = operations.Linear(dim_ff, d_model, device=device, dtype=dtype)
+ self.norm1 = operations.LayerNorm(d_model, device=device, dtype=dtype)
+ self.norm2 = operations.LayerNorm(d_model, device=device, dtype=dtype)
+ self.norm3 = operations.LayerNorm(d_model, device=device, dtype=dtype)
+
+ def forward(self, image, x, memory_image, memory, memory_image_pos=None,
+ rope=None, num_k_exclude_rope=0):
+ # Self-attention with RoPE
+ normed = self.norm1(x)
+ q = self.self_attn_q_proj(normed)
+ k = self.self_attn_k_proj(normed)
+ v = self.self_attn_v_proj(normed)
+ if rope is not None:
+ q, k = apply_rope_memory(q, k, rope, self.num_heads, 0)
+ x = x + self.self_attn_out_proj(optimized_attention(q, k, v, self.num_heads, low_precision_attention=False))
+
+ # Decoupled cross-attention: fuse image and memory projections
+ normed = self.norm2(x)
+ q = self.image_cross_attn_q_proj(image) + self.cross_attn_q_proj(normed)
+ k = self.image_cross_attn_k_proj(memory_image) + self.cross_attn_k_proj(memory)
+ if memory_image_pos is not None:
+ k = k + memory_image_pos
+ v = self.cross_attn_v_proj(memory)
+ if rope is not None:
+ q, k = apply_rope_memory(q, k, rope, self.num_heads, num_k_exclude_rope)
+ x = x + self.cross_attn_out_proj(optimized_attention(q, k, v, self.num_heads, low_precision_attention=False))
+
+ # FFN
+ x = x + self.linear2(F.gelu(self.linear1(self.norm3(x))))
+ return image, x
+
+
+class DecoupledMemoryEncoder(nn.Module):
+ """Memory attention encoder for SAM3.1 with decoupled cross-attention."""
+
+ def __init__(self, d_model=256, num_heads=1, dim_ff=2048, num_layers=4, image_size=1008, patch_size=14,
+ device=None, dtype=None, operations=None):
+ super().__init__()
+ self.layers = nn.ModuleList([
+ DecoupledMemoryAttnLayer(d_model, num_heads, dim_ff, device=device, dtype=dtype, operations=operations)
+ for _ in range(num_layers)
+ ])
+ self.norm = operations.LayerNorm(d_model, device=device, dtype=dtype)
+ hw = image_size // patch_size
+ self.register_buffer("_rope", rope_2d(hw, hw, d_model // num_heads), persistent=False)
+
+ def forward(self, x, memory, memory_pos=None, src_pos=None, num_k_exclude_rope=0,
+ memory_image=None, memory_image_pos=None):
+ image = x # constant residual for decoupled cross-attention
+ output = x
+ if src_pos is not None:
+ output = output + 0.1 * src_pos
+
+ B, _, C = x.shape
+ rope = self._rope.to(device=x.device)
+
+ # memory_image: raw backbone features from past frames for decoupled cross-attention
+ if memory_image is None:
+ # Fallback: use spatial portion of memory (without obj pointers)
+ num_spatial = memory.shape[1] - num_k_exclude_rope
+ memory_image = memory[:, :num_spatial]
+ memory_image_pos = memory_pos[:, :num_spatial] if memory_pos is not None else None
+ # Pad memory_image to match memory length (zeros for obj pointer tokens)
+ if memory_image.shape[1] < memory.shape[1]:
+ pad_len = memory.shape[1] - memory_image.shape[1]
+ pad = torch.zeros(B, pad_len, C, device=memory.device, dtype=memory.dtype)
+ memory_image = torch.cat([memory_image, pad], dim=1)
+ if memory_image_pos is not None:
+ ptr_pos = memory_pos[:, -pad_len:] if memory_pos is not None else torch.zeros_like(pad)
+ memory_image_pos = torch.cat([memory_image_pos, ptr_pos], dim=1)
+
+ for layer in self.layers:
+ image, output = layer(image, output, memory_image, memory,
+ memory_image_pos=memory_image_pos, rope=rope,
+ num_k_exclude_rope=num_k_exclude_rope)
+
+ return self.norm(output)
+
+
+class DecoupledMemoryTransformer(nn.Module):
+ def __init__(self, d_model=256, num_heads=1, dim_ff=2048, num_layers=4, device=None, dtype=None, operations=None):
+ super().__init__()
+ self.encoder = DecoupledMemoryEncoder(d_model, num_heads, dim_ff, num_layers,
+ device=device, dtype=dtype, operations=operations)
+
+
+class MemoryBackbone(nn.Module):
+ """Memory encoder: downsamples mask, fuses with pixel features, optionally compresses."""
+
+ def __init__(self, d_model=256, out_dim=None, in_chans=1, channels=None, device=None, dtype=None, operations=None):
+ super().__init__()
+ self.mask_downsampler = MaskDownSampler(d_model, in_chans=in_chans, channels=channels, device=device, dtype=dtype, operations=operations)
+ self.pix_feat_proj = operations.Conv2d(d_model, d_model, kernel_size=1, device=device, dtype=dtype)
+ self.fuser = Fuser(d_model, num_layers=2, device=device, dtype=dtype, operations=operations)
+ self.has_out_proj = out_dim is not None and out_dim != d_model
+ if self.has_out_proj:
+ self.out_proj = operations.Conv2d(d_model, out_dim, kernel_size=1, device=device, dtype=dtype)
+ feat_dim = out_dim
+ else:
+ feat_dim = d_model
+ self.position_encoding = PositionEmbeddingSine(num_pos_feats=feat_dim, normalize=True)
+
+ def forward(self, image_features, mask_for_mem, skip_mask_sigmoid=False):
+ if not skip_mask_sigmoid:
+ mask_for_mem = mask_for_mem.sigmoid()
+ mask_features = self.mask_downsampler(cast_to_input(mask_for_mem, image_features))
+ if mask_features.shape[-2:] != image_features.shape[-2:]:
+ mask_features = F.interpolate(mask_features, size=image_features.shape[-2:], mode="bilinear", align_corners=False)
+ features = self.pix_feat_proj(image_features) + mask_features
+ features = self.fuser(features)
+ if self.has_out_proj:
+ features = self.out_proj(features)
+ pos = cast_to_input(self.position_encoding(features), features)
+ return {"vision_features": features, "vision_pos_enc": [pos]}
+
+
+class MultiplexMaskDecoder(nn.Module):
+ """SAM mask decoder for SAM3.1 multiplex: predicts masks for num_multiplex objects simultaneously.
+
+ Uses multimask_outputs_only=True: num_mask_output_per_object = num_multimask_outputs (no +1).
+ Hypernetwork MLPs are shared across multiplex objects.
+ Token order: [obj_score_token(M), iou_token(M), mask_tokens(M*T)].
+ """
+
+ def __init__(self, d_model=256, num_multiplex=16, num_multimask_outputs=3, device=None, dtype=None, operations=None):
+ super().__init__()
+ self.num_multiplex = num_multiplex
+ self.num_mask_output_per_object = num_multimask_outputs # 3 (multimask_outputs_only)
+ total_mask_tokens = num_multiplex * self.num_mask_output_per_object # 48
+
+ self.transformer = SAMTwoWayTransformer(depth=2, embedding_dim=d_model, num_heads=8, mlp_dim=2048, device=device, dtype=dtype, operations=operations)
+
+ self.obj_score_token = operations.Embedding(num_multiplex, d_model, device=device, dtype=dtype)
+ self.iou_token = operations.Embedding(num_multiplex, d_model, device=device, dtype=dtype)
+ self.mask_tokens = operations.Embedding(total_mask_tokens, d_model, device=device, dtype=dtype)
+
+ LN2d = LayerNorm2d_op(operations)
+ self.output_upscaling = nn.Sequential(
+ operations.ConvTranspose2d(d_model, d_model // 4, kernel_size=2, stride=2, device=device, dtype=dtype),
+ LN2d(d_model // 4, device=device, dtype=dtype), nn.GELU(),
+ operations.ConvTranspose2d(d_model // 4, d_model // 8, kernel_size=2, stride=2, device=device, dtype=dtype), nn.GELU(),
+ )
+ self.conv_s0 = operations.Conv2d(d_model, d_model // 8, kernel_size=1, device=device, dtype=dtype)
+ self.conv_s1 = operations.Conv2d(d_model, d_model // 4, kernel_size=1, device=device, dtype=dtype)
+
+ # Shared across all multiplex objects (one per mask output)
+ self.output_hypernetworks_mlps = nn.ModuleList([
+ MLP(d_model, d_model, d_model // 8, 3, device=device, dtype=dtype, operations=operations)
+ for _ in range(self.num_mask_output_per_object)
+ ])
+ self.iou_prediction_head = MLP(d_model, d_model, self.num_mask_output_per_object, 3, device=device, dtype=dtype, operations=operations)
+ self.pred_obj_score_head = MLP(d_model, d_model, 1, 3, device=device, dtype=dtype, operations=operations)
+
+ def forward(self, image_embeddings, image_pe, sparse_prompt_embeddings, dense_prompt_embeddings,
+ high_res_features=None, multimask_output=False, return_all=False, extra_per_object_embeddings=None):
+ B = sparse_prompt_embeddings.shape[0]
+ M = self.num_multiplex
+ T = self.num_mask_output_per_object
+
+ # Token order: [obj_score(M), iou(M), mask(M*T)]
+ ref = sparse_prompt_embeddings
+ mask_tokens = cast_to_input(self.mask_tokens.weight, ref)
+ if extra_per_object_embeddings is not None:
+ mask_tokens = mask_tokens.view(1, M, T, -1).expand(B, -1, -1, -1) + extra_per_object_embeddings.unsqueeze(2)
+ mask_tokens = mask_tokens.flatten(1, 2) # [B, M*T, C]
+ other_tokens = torch.cat([cast_to_input(self.obj_score_token.weight, ref),
+ cast_to_input(self.iou_token.weight, ref)], dim=0).unsqueeze(0).expand(B, -1, -1)
+ tokens = torch.cat([other_tokens, mask_tokens, sparse_prompt_embeddings], dim=1)
+ else:
+ tokens = torch.cat([cast_to_input(self.obj_score_token.weight, ref),
+ cast_to_input(self.iou_token.weight, ref), mask_tokens], dim=0)
+ tokens = torch.cat([tokens.unsqueeze(0).expand(B, -1, -1), sparse_prompt_embeddings], dim=1)
+
+ src = image_embeddings
+ if src.shape[0] != B:
+ src = src.expand(B, -1, -1, -1)
+ src = src + dense_prompt_embeddings
+ pos_src = image_pe.expand(B, -1, -1, -1)
+
+ b, c, h, w = src.shape
+ hs, src_out = self.transformer(src.flatten(2).permute(0, 2, 1), pos_src.flatten(2).permute(0, 2, 1), tokens)
+
+ # Parse output tokens
+ obj_score_token_out = hs[:, :M]
+ iou_token_out = hs[:, M:2 * M]
+ mask_tokens_out = hs[:, 2 * M:2 * M + M * T]
+
+ src_out = src_out.permute(0, 2, 1).view(b, c, h, w)
+ upscaled = _upscale_masks(self.output_upscaling, self.conv_s0, self.conv_s1, src_out, high_res_features)
+
+ # Reshape mask tokens to [B, M, T, C] and apply shared hypernetwork MLPs per mask output index
+ mask_tokens_2d = mask_tokens_out.view(B, M, T, -1)
+ hyper_in = torch.stack([
+ self.output_hypernetworks_mlps[i](mask_tokens_2d[:, :, i, :]) # [B, M, C//8]
+ for i in range(T)
+ ], dim=2) # [B, M, T, C//8]
+
+ # Generate masks: [B, M*T, H*W] -> [B, M, T, H, W]
+ masks = torch.bmm(hyper_in.flatten(1, 2), upscaled.flatten(2)).view(b, M, T, upscaled.shape[2], upscaled.shape[3])
+
+ # IoU and object scores
+ iou_pred = self.iou_prediction_head(iou_token_out).view(b, M, T)
+ object_score_logits = self.pred_obj_score_head(obj_score_token_out) # [B, M, 1]
+
+ # multimask_outputs_only: always output all T masks (no singlemask token)
+ sam_tokens_out = mask_tokens_2d[:, :, 0:1] # [B, M, 1, C]
+
+ if return_all:
+ return masks, iou_pred, sam_tokens_out, object_score_logits
+ return masks, iou_pred
+
+
+class SAM3Tracker(nn.Module):
+ def __init__(self, d_model=256, mem_dim=64, num_maskmem=7, device=None, dtype=None, operations=None, **kwargs):
+ super().__init__()
+
+ # Memory attention transformer
+ self.transformer = MemoryTransformer(d_model, num_heads=1, kv_dim=mem_dim, dim_ff=2048, num_layers=4,
+ device=device, dtype=dtype, operations=operations)
+ # SAM components
+ self.sam_mask_decoder = SAMMaskDecoder(d_model, device=device, dtype=dtype, operations=operations)
+ self.sam_prompt_encoder = SAMPromptEncoder(d_model, device=device, dtype=dtype, operations=operations)
+
+ # Memory backbone
+ self.maskmem_backbone = MemoryBackbone(d_model, out_dim=mem_dim, device=device, dtype=dtype, operations=operations)
+
+ # Standalone parameters
+ self.maskmem_tpos_enc = nn.Parameter(torch.zeros(num_maskmem, 1, 1, mem_dim, device=device, dtype=dtype))
+ self.no_mem_embed = nn.Parameter(torch.zeros(1, 1, d_model, device=device, dtype=dtype))
+ self.register_buffer("no_mem_pos_enc", torch.zeros(1, 1, d_model, device=device, dtype=dtype)) # checkpoint key, unused in forward
+ self.no_obj_embed_spatial = nn.Parameter(torch.zeros(1, mem_dim, device=device, dtype=dtype))
+ self.no_obj_ptr = nn.Parameter(torch.zeros(1, d_model, device=device, dtype=dtype))
+
+ # Object pointer projection
+ self.obj_ptr_proj = MLP(d_model, d_model, d_model, 3, device=device, dtype=dtype, operations=operations)
+ self.obj_ptr_tpos_proj = operations.Linear(d_model, mem_dim, device=device, dtype=dtype)
+
+ # Mask downsample: Conv2d stride 4 to reduce GT mask to SAM logit scale
+ self.mask_downsample = operations.Conv2d(1, 1, kernel_size=4, stride=4, device=device, dtype=dtype)
+
+ # Config
+ self.d_model = d_model
+ self.mem_dim = mem_dim
+ self.num_maskmem = num_maskmem
+ self.image_size = 1008
+ self.backbone_stride = 14
+ self.max_obj_ptrs_in_encoder = 16
+ self.sigmoid_scale_for_mem_enc = 20.0
+ self.sigmoid_bias_for_mem_enc = -10.0
+
+ def _no_obj_blend(self, obj_ptr, is_obj):
+ alpha = is_obj.to(obj_ptr.dtype)
+ return torch.lerp(cast_to_input(self.no_obj_ptr, obj_ptr), obj_ptr, alpha)
+
+ def _forward_sam_heads(self, backbone_features, point_inputs=None, mask_inputs=None, box_inputs=None,
+ high_res_features=None, multimask_output=False):
+ return forward_sam_heads(backbone_features, self.sam_prompt_encoder, self.sam_mask_decoder,
+ self.obj_ptr_proj, self._no_obj_blend, self.image_size,
+ point_inputs, mask_inputs, box_inputs, high_res_features, multimask_output)
+
+ def _use_mask_as_output(self, backbone_features, high_res_features, mask_inputs):
+ return use_mask_as_output(backbone_features, high_res_features, mask_inputs,
+ self.mask_downsample, self.sam_prompt_encoder, self.sam_mask_decoder,
+ self.obj_ptr_proj, self._no_obj_blend, self.image_size, self.backbone_stride)
+
+ def _prepare_memory_conditioned_features(self, frame_idx, is_init_cond_frame, current_vision_feats, current_vision_pos_embeds, feat_sizes, output_dict, num_frames):
+ """Fuse current frame features with memory from previous frames."""
+ B = current_vision_feats[-1].shape[0]
+ C = self.d_model
+ H, W = feat_sizes[-1]
+ device = current_vision_feats[-1].device
+
+ if self.num_maskmem == 0:
+ return current_vision_feats[-1].permute(0, 2, 1).view(B, C, H, W)
+
+ if is_init_cond_frame:
+ # First conditioning frame: no memory yet, add no_mem_embed
+ pix_feat = current_vision_feats[-1] + cast_to_input(self.no_mem_embed, current_vision_feats[-1])
+ return to_spatial(pix_feat, H, W)
+
+ to_cat_memory, to_cat_memory_pos, _, _, cond_outputs = collect_memory_tokens(
+ output_dict, frame_idx, self.num_maskmem, self.maskmem_tpos_enc, device)
+
+ max_obj_ptrs = min(num_frames, self.max_obj_ptrs_in_encoder)
+ pos_and_ptrs = []
+ for t, out in cond_outputs.items():
+ if t <= frame_idx:
+ pos_and_ptrs.append(((frame_idx - t), out["obj_ptr"].to(device)))
+ for t_diff in range(1, max_obj_ptrs):
+ t = frame_idx - t_diff
+ if t < 0:
+ break
+ out = output_dict["non_cond_frame_outputs"].get(t, None)
+ if out is not None:
+ pos_and_ptrs.append((t_diff, out["obj_ptr"].to(device)))
+
+ num_obj_ptr_tokens = 0
+ if len(pos_and_ptrs) > 0:
+ pos_list, ptrs_list = zip(*pos_and_ptrs)
+ obj_ptrs = torch.stack(ptrs_list, dim=1) # [B, N, C=256]
+
+ # Temporal position encoding for pointers
+ obj_pos = compute_tpos_enc(
+ list(pos_list), device, self.d_model, self.obj_ptr_tpos_proj,
+ max_abs_pos=max_obj_ptrs, dtype=current_vision_feats[-1].dtype
+ ) # [N, mem_dim=64]
+ obj_pos = obj_pos.unsqueeze(0).expand(B, -1, -1) # [B, N, 64]
+
+ # Split each 256-dim pointer into 4 x 64-dim tokens
+ if self.mem_dim < C:
+ N = obj_ptrs.shape[1]
+ obj_ptrs = obj_ptrs.view(B, N, C // self.mem_dim, self.mem_dim) # [B, N, 4, 64]
+ obj_ptrs = obj_ptrs.reshape(B, N * (C // self.mem_dim), self.mem_dim) # [B, N*4, 64]
+ obj_pos = obj_pos.unsqueeze(2).expand(-1, -1, C // self.mem_dim, -1)
+ obj_pos = obj_pos.reshape(B, N * (C // self.mem_dim), self.mem_dim) # [B, N*4, 64]
+
+ to_cat_memory.append(obj_ptrs)
+ to_cat_memory_pos.append(obj_pos)
+ num_obj_ptr_tokens = obj_ptrs.shape[1]
+
+ if len(to_cat_memory) == 0:
+ # No memory available yet, add no_mem_embed
+ pix_feat = current_vision_feats[-1] + cast_to_input(self.no_mem_embed, current_vision_feats[-1])
+ return to_spatial(pix_feat, H, W)
+
+ # Concatenate all memory and position encodings [B, total_mem, mem_dim=64]
+ memory = torch.cat(to_cat_memory, dim=1)
+ memory_pos = torch.cat(to_cat_memory_pos, dim=1)
+
+ # Run memory attention encoder
+ pix_feat = current_vision_feats[-1] # [B, HW, C]
+ src_pos = current_vision_pos_embeds[-1] # [B, HW, C]
+
+ pix_feat_with_mem = self.transformer.encoder(
+ x=pix_feat,
+ memory=memory,
+ src_pos=src_pos,
+ memory_pos=memory_pos,
+ num_k_exclude_rope=num_obj_ptr_tokens,
+ )
+ return to_spatial(pix_feat_with_mem, H, W)
+
+ def _encode_new_memory(self, pix_feat, pred_masks_high_res, object_score_logits, is_mask_from_pts=False):
+ """Encode predicted mask into memory features."""
+ if is_mask_from_pts:
+ mask_for_mem = (pred_masks_high_res > 0).to(pix_feat.dtype)
+ else:
+ mask_for_mem = torch.sigmoid(pred_masks_high_res)
+
+ mask_for_mem.mul_(self.sigmoid_scale_for_mem_enc).add_(self.sigmoid_bias_for_mem_enc)
+
+ maskmem_out = self.maskmem_backbone(pix_feat, mask_for_mem, skip_mask_sigmoid=True)
+ maskmem_features = maskmem_out["vision_features"]
+ maskmem_pos_enc = maskmem_out["vision_pos_enc"]
+
+ # Add no_obj_embed for occluded objects
+ alpha = (object_score_logits > 0).to(maskmem_features.dtype)[..., None, None]
+ no_obj = cast_to_input(self.no_obj_embed_spatial, maskmem_features)[..., None, None].expand_as(maskmem_features)
+ return maskmem_features + (1 - alpha) * no_obj, maskmem_pos_enc
+
+ def track_step(self, frame_idx, is_init_cond_frame, current_vision_feats, current_vision_pos_embeds, feat_sizes, mask_inputs, output_dict,
+ num_frames, point_inputs=None):
+ """Track one frame: fuse with memory, predict mask, encode memory."""
+ current_out = {}
+
+ # High-res features for SAM head [stride-8, stride-4]
+ if len(current_vision_feats) > 1:
+ high_res_features = [
+ x.view(x.shape[0], feat_sizes[i][0], feat_sizes[i][1], -1).permute(0, 3, 1, 2)
+ for i, x in enumerate(current_vision_feats[:-1])
+ ]
+ else:
+ high_res_features = None
+
+ # Top-level feature for memory
+ H, W = feat_sizes[-1]
+
+ if mask_inputs is not None:
+ # Conditioning frame: use mask directly
+ pix_feat = to_spatial(current_vision_feats[-1], H, W)
+ sam_outputs = self._use_mask_as_output(pix_feat, high_res_features, mask_inputs)
+ else:
+ # Track frame: fuse with memory, then SAM decoder
+ pix_feat_with_mem = self._prepare_memory_conditioned_features(
+ frame_idx=frame_idx,
+ is_init_cond_frame=is_init_cond_frame,
+ current_vision_feats=current_vision_feats,
+ current_vision_pos_embeds=current_vision_pos_embeds,
+ feat_sizes=feat_sizes,
+ output_dict=output_dict,
+ num_frames=num_frames,
+ )
+ # Use multimask for point prompts on init frames (picks best of 3 candidates)
+ num_pts = 0 if point_inputs is None else point_inputs["point_labels"].size(1)
+ multimask_output = is_init_cond_frame and 0 < num_pts <= 1
+ sam_outputs = self._forward_sam_heads(
+ backbone_features=pix_feat_with_mem,
+ point_inputs=point_inputs,
+ high_res_features=high_res_features,
+ multimask_output=multimask_output,
+ )
+
+ (low_res_masks, high_res_masks, obj_ptr, object_score_logits) = sam_outputs
+
+ # Clean low-res masks: remove sprinkles and fill holes
+ low_res_masks = fill_holes_in_mask_scores(low_res_masks, max_area=200)
+ high_res_masks = F.interpolate(low_res_masks, size=(self.image_size, self.image_size), mode="bilinear", align_corners=False)
+
+ current_out["pred_masks"] = low_res_masks
+ current_out["pred_masks_high_res"] = high_res_masks
+ current_out["obj_ptr"] = obj_ptr
+ current_out["object_score_logits"] = object_score_logits
+
+ # Encode memory
+ if self.num_maskmem > 0:
+ pix_feat = to_spatial(current_vision_feats[-1], H, W)
+ maskmem_features, maskmem_pos_enc = self._encode_new_memory(
+ pix_feat=pix_feat,
+ pred_masks_high_res=high_res_masks,
+ object_score_logits=object_score_logits,
+ is_mask_from_pts=(point_inputs is not None),
+ )
+ current_out["maskmem_features"] = maskmem_features
+ current_out["maskmem_pos_enc"] = maskmem_pos_enc
+ else:
+ current_out["maskmem_features"] = None
+ current_out["maskmem_pos_enc"] = None
+
+ return current_out
+
+ def _compute_backbone_frame(self, backbone_fn, frame, frame_idx=None):
+ vision_feats, vision_pos, feat_sizes, _, _ = _compute_backbone(backbone_fn, frame, frame_idx)
+ # SAM3: drop last FPN level
+ return vision_feats[:-1], vision_pos[:-1], feat_sizes[:-1]
+
+ def _track_single_object(self, backbone_fn, images, initial_mask, pbar=None,
+ target_device=None, target_dtype=None):
+ """Track one object, computing backbone per frame to save VRAM."""
+ N = images.shape[0]
+ device = target_device if target_device is not None else images.device
+ dt = target_dtype if target_dtype is not None else images.dtype
+ size = self.image_size
+ output_dict = {"cond_frame_outputs": {}, "non_cond_frame_outputs": {}}
+ all_masks = []
+
+ for frame_idx in tqdm(range(N), desc="tracking"):
+ vision_feats, vision_pos, feat_sizes = self._compute_backbone_frame(
+ backbone_fn, _prep_frame(images, slice(frame_idx, frame_idx + 1), device, dt, size), frame_idx=frame_idx)
+ mask_input = None
+ if frame_idx == 0:
+ mask_input = F.interpolate(initial_mask.to(device=device, dtype=dt),
+ size=(self.image_size, self.image_size), mode="bilinear", align_corners=False)
+ mask_input = (mask_input > 0.5).to(dt)
+
+ current_out = self.track_step(
+ frame_idx=frame_idx, is_init_cond_frame=(frame_idx == 0),
+ current_vision_feats=vision_feats, current_vision_pos_embeds=vision_pos,
+ feat_sizes=feat_sizes, mask_inputs=mask_input, output_dict=output_dict, num_frames=N)
+
+ if frame_idx == 0:
+ output_dict["cond_frame_outputs"][frame_idx] = current_out
+ else:
+ output_dict["non_cond_frame_outputs"][frame_idx] = current_out
+ lookback = max(self.num_maskmem, self.max_obj_ptrs_in_encoder)
+ for old_idx in list(output_dict["non_cond_frame_outputs"]):
+ if old_idx < frame_idx - lookback:
+ del output_dict["non_cond_frame_outputs"][old_idx]
+ # Move masks to CPU immediately to free VRAM
+ all_masks.append(current_out["pred_masks_high_res"].to(comfy.model_management.intermediate_device()))
+ if pbar is not None:
+ pbar.update(1)
+
+ return torch.cat(all_masks, dim=0) # [N, 1, H, W]
+
+ def track_video(self, backbone_fn, images, initial_masks, pbar=None,
+ target_device=None, target_dtype=None, **kwargs):
+ """Track one or more objects across video frames.
+
+ Args:
+ backbone_fn: callable that returns (sam2_features, sam2_positions, trunk_out) for a frame
+ images: [N, 3, H, W] CPU full-res video frames (resized per-frame to self.image_size)
+ initial_masks: [N_obj, 1, H, W] binary masks for first frame (one per object)
+ pbar: optional progress bar
+
+ Returns:
+ [N, N_obj, image_size, image_size] predicted mask logits per frame per object
+ """
+ N_obj = initial_masks.shape[0]
+ per_object = []
+ for obj_idx in range(N_obj):
+ obj_masks = self._track_single_object(
+ backbone_fn, images, initial_masks[obj_idx:obj_idx + 1], pbar=pbar,
+ target_device=target_device, target_dtype=target_dtype)
+ per_object.append(obj_masks)
+
+ return torch.cat(per_object, dim=1) # [N, N_obj, H, W]
+
+
+class SAM31Tracker(nn.Module):
+ """SAM3.1 multiplex tracker: decoupled memory attention, dual decoder, 16-object multiplex."""
+
+ def __init__(self, d_model=256, mem_dim=256, num_maskmem=7, num_multiplex=16, device=None, dtype=None, operations=None, **kwargs):
+ super().__init__()
+ self.d_model = d_model
+ self.mem_dim = mem_dim
+ self.num_maskmem = num_maskmem
+ self.num_multiplex = num_multiplex
+ self.image_size = 1008
+ self.backbone_stride = 14
+ self.max_obj_ptrs_in_encoder = 16
+ self.sigmoid_scale_for_mem_enc = 2.0
+ self.sigmoid_bias_for_mem_enc = -1.0
+
+ # Memory attention (decoupled cross-attention, 8 heads matching reference)
+ self.transformer = DecoupledMemoryTransformer(d_model, num_heads=8, dim_ff=2048, num_layers=4,
+ device=device, dtype=dtype, operations=operations)
+
+ # Propagation decoder (multiplex: 16 objects, multimask_outputs_only)
+ self.sam_mask_decoder = MultiplexMaskDecoder(d_model, num_multiplex, num_multimask_outputs=3,
+ device=device, dtype=dtype, operations=operations)
+ # Interactive decoder (single object, same as SAM3)
+ self.interactive_sam_mask_decoder = SAMMaskDecoder(d_model, num_multimask_outputs=3,
+ device=device, dtype=dtype, operations=operations)
+ self.interactive_sam_prompt_encoder = SAMPromptEncoder(d_model, device=device, dtype=dtype, operations=operations)
+
+ # Memory backbone (mem_dim=256, no out_proj compression)
+ self.maskmem_backbone = MemoryBackbone(d_model, in_chans=num_multiplex * 2, channels=[16, 64, 256, 1024],
+ device=device, dtype=dtype, operations=operations)
+
+ # Standalone parameters
+ self.maskmem_tpos_enc = nn.Parameter(torch.zeros(num_maskmem, 1, 1, mem_dim, device=device, dtype=dtype))
+ self.no_obj_embed_spatial = nn.Parameter(torch.zeros(num_multiplex, mem_dim, device=device, dtype=dtype))
+ self.interactivity_no_mem_embed = nn.Parameter(torch.zeros(1, 1, d_model, device=device, dtype=dtype))
+
+ # Object pointer projection
+ self.obj_ptr_proj = MLP(d_model, d_model, d_model, 3, device=device, dtype=dtype, operations=operations)
+ self.obj_ptr_tpos_proj = operations.Linear(d_model, mem_dim, device=device, dtype=dtype)
+ self.no_obj_ptr_linear = operations.Linear(d_model, d_model, device=device, dtype=dtype)
+ self.interactive_obj_ptr_proj = MLP(d_model, d_model, d_model, 3, device=device, dtype=dtype, operations=operations)
+
+ # Interactive mask downsample
+ self.interactive_mask_downsample = operations.Conv2d(1, 1, kernel_size=4, stride=4, device=device, dtype=dtype)
+
+ # Multiplex validity embeddings
+ self.output_valid_embed = nn.Parameter(torch.zeros(num_multiplex, d_model, device=device, dtype=dtype))
+ self.output_invalid_embed = nn.Parameter(torch.zeros(num_multiplex, d_model, device=device, dtype=dtype))
+
+ # Position encoding for image (used by multiplex decoder)
+ self.image_pe_layer = PositionEmbeddingRandom(d_model // 2)
+
+ def _no_obj_blend(self, obj_ptr, is_obj):
+ alpha = is_obj.to(obj_ptr.dtype)
+ return torch.lerp(self.no_obj_ptr_linear(obj_ptr), obj_ptr, alpha)
+
+ def _forward_sam_heads(self, backbone_features, point_inputs=None, mask_inputs=None, box_inputs=None,
+ high_res_features=None, multimask_output=False):
+ return forward_sam_heads(backbone_features, self.interactive_sam_prompt_encoder, self.interactive_sam_mask_decoder,
+ self.interactive_obj_ptr_proj, self._no_obj_blend, self.image_size,
+ point_inputs, mask_inputs, box_inputs, high_res_features, multimask_output)
+
+ def _use_mask_as_output(self, backbone_features, high_res_features, mask_inputs):
+ return use_mask_as_output(backbone_features, high_res_features, mask_inputs,
+ self.interactive_mask_downsample, self.interactive_sam_prompt_encoder,
+ self.interactive_sam_mask_decoder, self.interactive_obj_ptr_proj,
+ self._no_obj_blend, self.image_size, self.backbone_stride)
+
+ def _prepare_memory_conditioned_features(self, frame_idx, is_init_cond_frame, current_vision_feats,
+ current_vision_pos_embeds, feat_sizes, output_dict, num_frames,
+ multiplex_state=None):
+ B = current_vision_feats[-1].shape[0]
+ C = self.d_model
+ H, W = feat_sizes[-1]
+ device = current_vision_feats[-1].device
+ num_buc = multiplex_state.num_buckets if multiplex_state is not None else None
+
+ if self.num_maskmem == 0:
+ return current_vision_feats[-1].permute(0, 2, 1).view(B, C, H, W)
+
+ if is_init_cond_frame:
+ pix_feat = current_vision_feats[-1] + cast_to_input(self.interactivity_no_mem_embed, current_vision_feats[-1])
+ return to_spatial(pix_feat, H, W)
+
+ to_cat_memory, to_cat_memory_pos, to_cat_image_feat, to_cat_image_pos, cond_outputs = collect_memory_tokens(
+ output_dict, frame_idx, self.num_maskmem, self.maskmem_tpos_enc, device,
+ collect_image_feats=True, tpos_v2=True, num_buckets=num_buc)
+
+ max_obj_ptrs = min(num_frames, self.max_obj_ptrs_in_encoder)
+ pos_and_ptrs = []
+ for t, out in cond_outputs.items():
+ if t <= frame_idx and "obj_ptr" in out:
+ ptr = out["obj_ptr"].to(device)
+ if num_buc is not None:
+ ptr = _pad_to_buckets(ptr, num_buc)
+ pos_and_ptrs.append(((frame_idx - t), ptr))
+ for t_diff in range(1, max_obj_ptrs):
+ t = frame_idx - t_diff
+ if t < 0:
+ break
+ out = output_dict["non_cond_frame_outputs"].get(t, None)
+ if out is not None and "obj_ptr" in out:
+ ptr = out["obj_ptr"].to(device)
+ if num_buc is not None:
+ ptr = _pad_to_buckets(ptr, num_buc)
+ pos_and_ptrs.append((t_diff, ptr))
+
+ num_obj_ptr_tokens = 0
+ if len(pos_and_ptrs) > 0:
+ pos_list, ptrs_list = zip(*pos_and_ptrs)
+ obj_ptrs = torch.stack(ptrs_list, dim=1) # [num_buckets, N, M, C]
+ B_ptr = obj_ptrs.shape[0]
+ N_ptrs = obj_ptrs.shape[1]
+ M = obj_ptrs.shape[2]
+ obj_ptrs = obj_ptrs.reshape(B_ptr, N_ptrs * M, -1)
+ obj_pos = compute_tpos_enc(list(pos_list), device, self.d_model, self.obj_ptr_tpos_proj,
+ max_abs_pos=max_obj_ptrs, dtype=current_vision_feats[-1].dtype)
+ obj_pos = obj_pos.unsqueeze(0).expand(B_ptr, -1, -1)
+ obj_pos = obj_pos.unsqueeze(2).expand(-1, -1, M, -1).reshape(B_ptr, N_ptrs * M, -1)
+ to_cat_memory.append(obj_ptrs)
+ to_cat_memory_pos.append(obj_pos)
+ num_obj_ptr_tokens = obj_ptrs.shape[1]
+
+ if len(to_cat_memory) == 0:
+ pix_feat = current_vision_feats[-1] + cast_to_input(self.interactivity_no_mem_embed, current_vision_feats[-1])
+ return to_spatial(pix_feat, H, W)
+
+ memory = torch.cat(to_cat_memory, dim=1)
+ memory_pos = torch.cat(to_cat_memory_pos, dim=1)
+
+ # Expand vision features to num_buckets if memory has more buckets than B
+ mem_B = memory.shape[0]
+ x = current_vision_feats[-1]
+ x_pos = current_vision_pos_embeds[-1]
+ if x.shape[0] < mem_B:
+ x = x.expand(mem_B, -1, -1)
+ x_pos = x_pos.expand(mem_B, -1, -1)
+
+ if len(to_cat_image_feat) > 0:
+ # Decoupled cross-attention: separate image features from memory
+ memory_image = cast_to_input(torch.cat(to_cat_image_feat, dim=1), x)
+ memory_image_pos = cast_to_input(torch.cat(to_cat_image_pos, dim=1), x)
+ if memory_image.shape[0] < mem_B:
+ memory_image = memory_image.expand(mem_B, -1, -1)
+ memory_image_pos = memory_image_pos.expand(mem_B, -1, -1)
+ pix_feat_with_mem = self.transformer.encoder(
+ x=x,
+ memory=cast_to_input(memory, x),
+ memory_pos=cast_to_input(memory_pos, x),
+ src_pos=cast_to_input(x_pos, x),
+ num_k_exclude_rope=num_obj_ptr_tokens,
+ memory_image=memory_image,
+ memory_image_pos=memory_image_pos,
+ )
+ else:
+ pix_feat_with_mem = self.transformer.encoder(
+ x=x,
+ memory=memory,
+ memory_pos=memory_pos,
+ src_pos=x_pos,
+ num_k_exclude_rope=num_obj_ptr_tokens,
+ )
+ return to_spatial(pix_feat_with_mem, H, W)
+
+ def _encode_new_memory(self, pix_feat, pred_masks_high_res, object_score_logits, is_mask_from_pts=False,
+ multiplex_state=None, is_conditioning=False, cond_obj_mask=None):
+ if is_mask_from_pts:
+ mask_for_mem = (pred_masks_high_res > 0).to(pix_feat.dtype)
+ else:
+ mask_for_mem = torch.sigmoid(pred_masks_high_res)
+ mask_for_mem.mul_(self.sigmoid_scale_for_mem_enc).add_(self.sigmoid_bias_for_mem_enc)
+
+ # Mux masks: [N_obj, 1, H, W] -> [num_buckets, M, H, W]
+ mux_masks = multiplex_state.mux(mask_for_mem[:, 0])
+
+ # Conditioning channel: 1.0 = clean mask (trust it), 0.0 = propagation (noisy)
+ N_obj = mask_for_mem.shape[0]
+ cond_values = torch.full((N_obj,), 0.0, device=mask_for_mem.device, dtype=mask_for_mem.dtype)
+ if is_conditioning:
+ cond_values[:] = 1.0
+ elif cond_obj_mask is not None:
+ cond_values[cond_obj_mask] = 1.0
+ cond_spatial = cond_values.view(-1, 1, 1, 1).expand_as(mask_for_mem[:, 0:1, :, :]).squeeze(1)
+ mux_cond = multiplex_state.mux(cond_spatial) # [num_buckets, M, H, W]
+ mux_input = torch.cat([mux_masks, mux_cond], dim=1) # [num_buckets, 2*M, H, W]
+
+ maskmem_out = self.maskmem_backbone(pix_feat, mux_input, skip_mask_sigmoid=True)
+ maskmem_features = maskmem_out["vision_features"]
+ maskmem_pos_enc = maskmem_out["vision_pos_enc"]
+
+ # Add no_obj_embed_spatial for occluded objects
+ is_obj = (object_score_logits > 0).float() # [N_obj, 1]
+ mux_is_obj = multiplex_state.mux(is_obj) # [num_buckets, M, 1]
+ no_obj_embed = cast_to_input(self.no_obj_embed_spatial, maskmem_features) # [M, C]
+ no_obj_spatial = no_obj_embed.unsqueeze(0)[..., None, None] # [1, M, C, 1, 1]
+ # Expand and sum across multiplex slots weighted by (1 - is_obj)
+ alpha = mux_is_obj[..., None, None] # [num_buckets, M, 1, 1, 1]
+ per_slot_no_obj = ((1 - alpha) * no_obj_spatial).sum(dim=1) # [num_buckets, C, 1, 1]
+ maskmem_features = maskmem_features + per_slot_no_obj.expand_as(maskmem_features)
+
+ return maskmem_features, maskmem_pos_enc
+
+ def _forward_propagation(self, backbone_features, high_res_features=None, multiplex_state=None):
+ """Propagation path using the multiplex SAM decoder (no prompts)."""
+ B = backbone_features.shape[0]
+ device = backbone_features.device
+
+ # Suppression embeddings from valid object mask
+ valid_mask = cast_to_input(multiplex_state.get_valid_object_mask().unsqueeze(-1).float(), backbone_features)
+ output_valid = cast_to_input(self.output_valid_embed, backbone_features).unsqueeze(0)
+ output_invalid = cast_to_input(self.output_invalid_embed, backbone_features).unsqueeze(0)
+ extra_embed = valid_mask * output_valid + (1 - valid_mask) * output_invalid
+
+ image_pe = self.image_pe_layer((backbone_features.shape[-2], backbone_features.shape[-1]), device=backbone_features.device)
+ image_pe = cast_to_input(image_pe, backbone_features)
+
+ masks, iou_pred, sam_tokens_out, object_score_logits = self.sam_mask_decoder(
+ image_embeddings=backbone_features, image_pe=image_pe,
+ sparse_prompt_embeddings=torch.empty(B, 0, self.d_model, device=device, dtype=backbone_features.dtype),
+ dense_prompt_embeddings=torch.zeros(B, self.d_model, *backbone_features.shape[-2:], device=device, dtype=backbone_features.dtype),
+ high_res_features=high_res_features, multimask_output=True, return_all=True,
+ extra_per_object_embeddings=extra_embed.expand(B, -1, -1),
+ )
+ # masks: [B=num_buckets, M, T, H, W]
+ # Demux to per-object: [N_obj, T, H, W]
+ masks_obj = multiplex_state.demux(masks)
+ iou_obj = multiplex_state.demux(iou_pred)
+ score_obj = multiplex_state.demux(object_score_logits)
+ tokens_obj = multiplex_state.demux(sam_tokens_out)
+
+ # Select best mask by IoU for each object
+ best_idx = torch.argmax(iou_obj, dim=-1) # [N_obj]
+ N_obj = masks_obj.shape[0]
+ obj_range = torch.arange(N_obj, device=device)
+ low_res_masks = masks_obj[obj_range, best_idx].unsqueeze(1) # [N_obj, 1, H, W]
+ # Suppress masks for objects with low confidence
+ is_obj = score_obj > 0
+ low_res_masks = torch.where(is_obj[:, :, None, None], low_res_masks,
+ torch.tensor(NO_OBJ_SCORE, device=device, dtype=low_res_masks.dtype))
+ high_res_masks = F.interpolate(low_res_masks.float(), size=(self.image_size, self.image_size), mode="bilinear", align_corners=False)
+
+ # Object pointer: compute per-object, mux for storage as [num_buckets, M, C]
+ sam_token = tokens_obj[:, 0] # [N_obj, C]
+ obj_ptr = self.obj_ptr_proj(sam_token)
+ is_obj = (score_obj > 0).float()
+ no_obj = self.no_obj_ptr_linear(obj_ptr)
+ obj_ptr = is_obj * obj_ptr + (1 - is_obj) * no_obj
+ obj_ptr_muxed = multiplex_state.mux(obj_ptr) # [num_buckets, M, C]
+
+ return low_res_masks, high_res_masks, obj_ptr_muxed, score_obj
+
+ def track_step(self, frame_idx, is_init_cond_frame, current_vision_feats, current_vision_pos_embeds,
+ feat_sizes, mask_inputs, output_dict, num_frames, point_inputs=None,
+ interactive_high_res=None, interactive_backbone=None, propagation_high_res=None,
+ multiplex_state=None, run_mem_encoder=True):
+ current_out = {}
+ H, W = feat_sizes[-1]
+
+ if mask_inputs is not None:
+ # Conditioning frame: use interactive features if available, else propagation
+ if interactive_backbone is not None:
+ pix_feat = interactive_backbone
+ # Add no_mem_embed for interactive path
+ pix_flat = pix_feat.flatten(2)
+ bf = pix_flat.permute(0, 2, 1) + cast_to_input(self.interactivity_no_mem_embed, pix_flat)
+ pix_feat = to_spatial(bf, H, W)
+ hi_res = interactive_high_res
+ else:
+ # Fallback: interactive backbone not available (e.g. called outside track_video).
+ # Propagation features work but may produce lower-quality conditioning.
+ pix_feat = to_spatial(current_vision_feats[-1], H, W)
+ hi_res = propagation_high_res
+ sam_outputs = self._use_mask_as_output(pix_feat, hi_res, mask_inputs)
+ elif point_inputs is not None:
+ # Interactive path: use interactive SAM decoder
+ pix_feat_with_mem = self._prepare_memory_conditioned_features(
+ frame_idx=frame_idx, is_init_cond_frame=is_init_cond_frame,
+ current_vision_feats=current_vision_feats, current_vision_pos_embeds=current_vision_pos_embeds,
+ feat_sizes=feat_sizes, output_dict=output_dict, num_frames=num_frames,
+ multiplex_state=multiplex_state,
+ )
+ hi_res = interactive_high_res if interactive_high_res is not None else propagation_high_res
+ num_pts = point_inputs["point_labels"].size(1)
+ multimask_output = is_init_cond_frame and 0 < num_pts <= 1
+ sam_outputs = self._forward_sam_heads(
+ backbone_features=pix_feat_with_mem, point_inputs=point_inputs,
+ high_res_features=hi_res, multimask_output=multimask_output,
+ )
+ else:
+ # Propagation path: use multiplex SAM decoder with propagation features
+ pix_feat_with_mem = self._prepare_memory_conditioned_features(
+ frame_idx=frame_idx, is_init_cond_frame=is_init_cond_frame,
+ current_vision_feats=current_vision_feats, current_vision_pos_embeds=current_vision_pos_embeds,
+ feat_sizes=feat_sizes, output_dict=output_dict, num_frames=num_frames,
+ multiplex_state=multiplex_state,
+ )
+ sam_outputs = self._forward_propagation(pix_feat_with_mem, propagation_high_res,
+ multiplex_state=multiplex_state)
+
+ (low_res_masks, high_res_masks, obj_ptr, object_score_logits) = sam_outputs
+
+ # Mux obj_ptr if it came from interactive path (shape [B, C]) vs propagation ([num_buckets, M, C])
+ if multiplex_state is not None and obj_ptr.dim() == 2:
+ obj_ptr = multiplex_state.mux(obj_ptr) # [N_obj, C] -> [num_buckets, M, C]
+
+ # Encode memory (can be deferred with run_mem_encoder=False)
+ if run_mem_encoder and self.num_maskmem > 0:
+ pix_feat = to_spatial(current_vision_feats[-1], H, W)
+ maskmem_features, maskmem_pos_enc = self._encode_new_memory(
+ pix_feat=pix_feat, pred_masks_high_res=high_res_masks,
+ object_score_logits=object_score_logits,
+ is_mask_from_pts=(point_inputs is not None),
+ multiplex_state=multiplex_state,
+ is_conditioning=(mask_inputs is not None),
+ )
+ current_out["maskmem_features"] = maskmem_features
+ current_out["maskmem_pos_enc"] = maskmem_pos_enc
+ else:
+ current_out["maskmem_features"] = None
+ current_out["maskmem_pos_enc"] = None
+
+ # Store propagation image features for decoupled memory attention
+ current_out["image_features"] = current_vision_feats[-1] # [B, HW, C]
+ current_out["image_pos_enc"] = current_vision_pos_embeds[-1] # [B, HW, C]
+
+ current_out["pred_masks"] = low_res_masks
+ current_out["pred_masks_high_res"] = high_res_masks
+ current_out["obj_ptr"] = obj_ptr
+ current_out["object_score_logits"] = object_score_logits
+
+ return current_out
+
+ def _compute_backbone_frame(self, backbone_fn, frame, frame_idx=None):
+ vision_feats, vision_pos, feat_sizes, features, trunk_out = _compute_backbone(backbone_fn, frame, frame_idx)
+ return vision_feats, vision_pos, feat_sizes, list(features[:-1]), trunk_out
+
+ @staticmethod
+ def _suppress_recently_occluded(low_res_masks, last_occluded, frame_idx, threshold=0.3):
+ """Suppress overlapping masks for objects that were most recently occluded.
+ Prevents corrupted masks from occluded objects from contaminating other objects."""
+ N_obj = low_res_masks.shape[0]
+ if N_obj <= 1:
+ return low_res_masks
+ binary = low_res_masks[:, 0] > 0 # [N_obj, H, W]
+ iou = _compute_mask_overlap(low_res_masks[:, 0], low_res_masks[:, 0])
+ overlapping = torch.triu(iou >= threshold, diagonal=1) # [N, N] upper triangle
+ last_occ_i = last_occluded.unsqueeze(1) # [N, 1]
+ last_occ_j = last_occluded.unsqueeze(0) # [1, N]
+ # Suppress the more recently occluded object in each overlapping pair
+ suppress_i = overlapping & (last_occ_i > last_occ_j) & (last_occ_j > -1)
+ suppress_j = overlapping & (last_occ_j > last_occ_i) & (last_occ_i > -1)
+ to_suppress = suppress_i.any(dim=1) | suppress_j.any(dim=0)
+ # Update last_occluded for occluded/suppressed objects
+ is_empty = ~binary.any(dim=(-1, -2))
+ newly_occluded = is_empty | to_suppress
+ last_occluded[newly_occluded] = frame_idx
+ # Suppress masks
+ low_res_masks[to_suppress] = -10.0
+ return low_res_masks
+
+ def _deferred_memory_encode(self, current_out, N_obj, vision_feats, feat_sizes, mux_state, device,
+ cond_obj_mask=None):
+ """Deferred memory encoding for propagation frames. cond_obj_mask: per-object bool for conditioning."""
+ low_res_masks = current_out["pred_masks"] # [N_obj, 1, H_low, W_low]
+
+ if N_obj > 1:
+ lr = low_res_masks.squeeze(1) # [N_obj, H, W]
+ max_obj = torch.argmax(lr, dim=0, keepdim=True)
+ batch_inds = torch.arange(N_obj, device=device)[:, None, None]
+ pixel_nol = torch.where(max_obj == batch_inds, lr, torch.clamp(lr, max=-10.0))
+ area_before = (lr > 0).sum(dim=(-1, -2)).float().clamp(min=1)
+ area_after = (pixel_nol > 0).sum(dim=(-1, -2)).float()
+ shrink_ok = (area_after / area_before) >= 0.3
+ low_res_masks = torch.where(
+ shrink_ok[:, None, None, None].expand_as(low_res_masks),
+ low_res_masks, torch.clamp(low_res_masks, max=-10.0))
+
+ interpol_size = self.maskmem_backbone.mask_downsampler.interpol_size
+ mem_masks = F.interpolate(low_res_masks, size=interpol_size,
+ mode="bilinear", align_corners=False)
+
+ obj_scores = torch.where(
+ (mem_masks > 0).any(dim=(-1, -2)), 10.0, -10.0)
+
+ pix_feat = to_spatial(vision_feats[-1], feat_sizes[-1][0], feat_sizes[-1][1])
+ maskmem_features, maskmem_pos_enc = self._encode_new_memory(
+ pix_feat=pix_feat, pred_masks_high_res=mem_masks,
+ object_score_logits=obj_scores,
+ multiplex_state=mux_state, cond_obj_mask=cond_obj_mask)
+ current_out["maskmem_features"] = maskmem_features
+ current_out["maskmem_pos_enc"] = maskmem_pos_enc
+
+ def _add_detected_objects(self, new_masks, mux_state, vision_feats, feat_sizes, current_out):
+ """Grow MultiplexState with new detections, merge masks, re-encode memory. Modifies current_out."""
+ n_old = mux_state.total_valid_entries
+ mux_state.add_objects(new_masks.shape[0])
+ N_obj = mux_state.total_valid_entries
+ # Stored memory with old bucket counts is padded at read time by _pad_to_buckets
+ for k in ("pred_masks", "pred_masks_high_res"):
+ det = F.interpolate(new_masks.unsqueeze(1), size=current_out[k].shape[-2:],
+ mode="bilinear", align_corners=False)
+ current_out[k] = torch.cat([current_out[k], det], dim=0)
+ if self.num_maskmem > 0:
+ # Mark new objects as conditioning (clean detection masks) so model trusts them
+ cond_mask = torch.zeros(N_obj, dtype=torch.bool, device=new_masks.device)
+ cond_mask[n_old:] = True
+ self._deferred_memory_encode(current_out, N_obj, vision_feats, feat_sizes,
+ mux_state, new_masks.device, cond_obj_mask=cond_mask)
+
+ def _condition_with_masks(self, masks, frame_idx, vision_feats, vision_pos, feat_sizes,
+ high_res_prop, output_dict, N, mux_state, backbone_obj, frame,
+ trunk_out, threshold=0.5):
+ """Condition tracker with masks on a frame."""
+ mask_input = F.interpolate(masks if masks.dim() == 4 else masks.unsqueeze(1),
+ size=(self.image_size, self.image_size), mode="bilinear", align_corners=False)
+ mask_input = (mask_input > threshold).to(masks.dtype)
+ hi_res = lo_feat = None
+ if backbone_obj is not None and backbone_obj.multiplex:
+ _, _, itf, _ = backbone_obj(frame, tracker_mode="interactive", cached_trunk=trunk_out, tracker_only=True)
+ hi_res, lo_feat = itf[:-1], itf[-1]
+ current_out = self.track_step(
+ frame_idx=frame_idx, is_init_cond_frame=True, current_vision_feats=vision_feats,
+ current_vision_pos_embeds=vision_pos, feat_sizes=feat_sizes, mask_inputs=mask_input,
+ output_dict=output_dict, num_frames=N, interactive_high_res=hi_res,
+ interactive_backbone=lo_feat, propagation_high_res=high_res_prop,
+ multiplex_state=mux_state, run_mem_encoder=True)
+ output_dict["cond_frame_outputs"][frame_idx] = current_out
+ return current_out
+
+ def _match_and_add_detections(self, det_masks, det_scores, current_out, mux_state,
+ vision_feats, feat_sizes, device, max_objects=0,
+ keep_alive=None):
+ """Match detections against tracked masks, add new objects, recondition degraded tracks.
+ Updates keep_alive counters: +1 for matched tracks, -1 for unmatched."""
+ N_obj = mux_state.total_valid_entries
+ if det_masks.shape[0] == 0:
+ if keep_alive is not None:
+ for i in range(N_obj):
+ keep_alive[i] = max(-4, keep_alive.get(i, 0) - 1)
+ return []
+
+ # Match at low-res (like reference)
+ trk_masks = current_out["pred_masks"][:, 0] # [N_obj, H_low, W_low]
+ det_resized = F.interpolate(det_masks.unsqueeze(1), size=trk_masks.shape[-2:],
+ mode="bilinear", align_corners=False)[:, 0]
+ overlap = _compute_mask_overlap(det_resized, trk_masks)
+
+ # Update keep_alive and find matched tracks
+ matched = set()
+ if overlap.shape[1] > 0:
+ matched = set((overlap >= 0.5).any(dim=0).nonzero(as_tuple=True)[0].tolist())
+ if keep_alive is not None:
+ for i in range(N_obj):
+ if i in matched:
+ keep_alive[i] = min(8, keep_alive.get(i, 0) + 1)
+ else:
+ keep_alive[i] = max(-4, keep_alive.get(i, 0) - 1)
+
+ # Recondition: high-confidence detections (>=0.8) with high overlap refresh tracked masks
+ reconditioned = False
+ if det_scores is not None and overlap.shape[1] > 0:
+ HIGH_CONF = 0.8
+ for det_idx in range(overlap.shape[0]):
+ if det_scores[det_idx] < HIGH_CONF:
+ continue
+ best_trk = overlap[det_idx].argmax().item()
+ if overlap[det_idx, best_trk] >= 0.5:
+ # Replace tracked mask with fresh detection mask
+ current_out["pred_masks"][best_trk] = det_resized[det_idx].unsqueeze(0)
+ det_hr = F.interpolate(det_masks[det_idx:det_idx+1].unsqueeze(1),
+ size=current_out["pred_masks_high_res"].shape[-2:],
+ mode="bilinear", align_corners=False)
+ current_out["pred_masks_high_res"][best_trk] = det_hr[0]
+ reconditioned = True
+
+ # Re-encode memory if any tracks were reconditioned
+ if reconditioned and self.num_maskmem > 0:
+ self._deferred_memory_encode(current_out, N_obj, vision_feats, feat_sizes, mux_state, device)
+
+ # Add new detections (not matching any track)
+ if max_objects > 0 and N_obj >= max_objects:
+ return []
+ max_overlap = overlap.max(dim=1)[0] if overlap.shape[1] > 0 else torch.zeros(overlap.shape[0], device=device)
+ new_dets = max_overlap < 0.5
+ if new_dets.any():
+ if max_objects > 0:
+ slots = max_objects - N_obj
+ new_dets = new_dets & (torch.cumsum(new_dets.int(), 0) <= slots)
+ self._add_detected_objects(det_masks[new_dets], mux_state,
+ vision_feats, feat_sizes, current_out)
+ if keep_alive is not None:
+ for i in range(N_obj, mux_state.total_valid_entries):
+ keep_alive[i] = 1
+ return det_scores[new_dets].tolist() if det_scores is not None else [0.0] * new_dets.sum().item()
+ return []
+
+ INTERNAL_MAX_OBJECTS = 64 # Hard ceiling on accumulated tracks; max_objects=0 or any value above this is clamped here.
+
+ def track_video_with_detection(self, backbone_fn, images, initial_masks, detect_fn=None,
+ new_det_thresh=0.5, max_objects=0, detect_interval=1,
+ backbone_obj=None, pbar=None, target_device=None, target_dtype=None):
+ """Track with optional per-frame detection. Returns [N, max_N_obj, H, W] mask logits."""
+ if max_objects <= 0 or max_objects > self.INTERNAL_MAX_OBJECTS:
+ max_objects = self.INTERNAL_MAX_OBJECTS
+ N = images.shape[0]
+ device = target_device if target_device is not None else images.device
+ dt = target_dtype if target_dtype is not None else images.dtype
+ size = self.image_size
+ output_dict = {"cond_frame_outputs": {}, "non_cond_frame_outputs": {}}
+ all_masks = []
+ idev = comfy.model_management.intermediate_device()
+ mux_state = None
+ if initial_masks is not None:
+ mux_state = MultiplexState(initial_masks.shape[0], self.num_multiplex, device, dt)
+ obj_scores = [] # per-object detection score (1.0 for initial masks)
+ keep_alive = {} if detect_fn is not None else None
+ last_occluded = torch.empty(0, device=device, dtype=torch.long) # per-object last occluded frame
+
+ # Prefetch next frame's backbone on a separate CUDA stream
+ prefetch = False
+ backbone_stream = None
+ if comfy.model_management.is_device_cuda(device):
+ try:
+ backbone_stream = torch.cuda.Stream(device=device)
+ prefetch = True
+ except RuntimeError:
+ pass
+ cur_bb = self._compute_backbone_frame(backbone_fn, _prep_frame(images, slice(0, 1), device, dt, size), frame_idx=0)
+
+ for frame_idx in tqdm(range(N), desc="tracking"):
+ vision_feats, vision_pos, feat_sizes, high_res_prop, trunk_out = cur_bb
+
+ # Start next frame's backbone on separate stream (overlaps with current frame's work)
+ if prefetch and frame_idx + 1 < N:
+ backbone_stream.wait_stream(torch.cuda.current_stream(device))
+ with torch.cuda.stream(backbone_stream):
+ next_bb = self._compute_backbone_frame(
+ backbone_fn, _prep_frame(images, slice(frame_idx + 1, frame_idx + 2), device, dt, size), frame_idx=frame_idx + 1)
+
+ # Per-frame detection with NMS (skip if no detect_fn, or interval/max not met)
+ det_masks = torch.empty(0, device=device)
+ det_scores = None
+ run_det = (detect_fn is not None
+ and frame_idx % max(detect_interval, 1) == 0
+ and not (max_objects > 0 and mux_state is not None
+ and mux_state.total_valid_entries >= max_objects))
+ if run_det:
+ det_out = detect_fn(trunk_out)
+ scores = det_out["scores"][0].sigmoid()
+ keep = scores > new_det_thresh
+ det_masks, det_scores = det_out["masks"][0][keep], scores[keep]
+ if det_masks.shape[0] > 1:
+ det_masks, det_scores = _nms_masks(det_masks, det_scores)
+
+ if frame_idx == 0 and initial_masks is not None:
+ current_out = self._condition_with_masks(
+ initial_masks.to(device=device, dtype=dt), frame_idx, vision_feats, vision_pos,
+ feat_sizes, high_res_prop, output_dict, N, mux_state, backbone_obj,
+ _prep_frame(images, slice(frame_idx, frame_idx + 1), device, dt, size), trunk_out)
+ last_occluded = torch.full((mux_state.total_valid_entries,), -1, device=device, dtype=torch.long)
+ obj_scores = [1.0] * mux_state.total_valid_entries
+ if keep_alive is not None:
+ for i in range(mux_state.total_valid_entries):
+ keep_alive[i] = 8
+ elif mux_state is None or mux_state.total_valid_entries == 0:
+ if det_masks.shape[0] > 0:
+ if max_objects > 0:
+ det_scores = det_scores[:max_objects]
+ det_masks = det_masks[:max_objects]
+ mux_state = MultiplexState(det_masks.shape[0], self.num_multiplex, device, dt)
+ current_out = self._condition_with_masks(
+ det_masks, frame_idx, vision_feats, vision_pos, feat_sizes, high_res_prop,
+ output_dict, N, mux_state, backbone_obj,
+ _prep_frame(images, slice(frame_idx, frame_idx + 1), device, dt, size), trunk_out, threshold=0.0)
+ last_occluded = torch.full((mux_state.total_valid_entries,), -1, device=device, dtype=torch.long)
+ obj_scores = det_scores[:mux_state.total_valid_entries].tolist()
+ if keep_alive is not None:
+ for i in range(mux_state.total_valid_entries):
+ keep_alive[i] = 1
+ else:
+ all_masks.append(None)
+ if pbar is not None:
+ pbar.update(1)
+ # Skip to backbone advance at end of loop
+ if frame_idx + 1 < N:
+ if prefetch:
+ torch.cuda.current_stream(device).wait_stream(backbone_stream)
+ cur_bb = next_bb
+ else:
+ cur_bb = self._compute_backbone_frame(backbone_fn, _prep_frame(images, slice(frame_idx + 1, frame_idx + 2), device, dt, size), frame_idx=frame_idx + 1)
+ continue
+ else:
+ N_obj = mux_state.total_valid_entries
+ current_out = self.track_step(
+ frame_idx=frame_idx, is_init_cond_frame=False, current_vision_feats=vision_feats,
+ current_vision_pos_embeds=vision_pos, feat_sizes=feat_sizes, mask_inputs=None,
+ output_dict=output_dict, num_frames=N, propagation_high_res=high_res_prop,
+ multiplex_state=mux_state, run_mem_encoder=False)
+ current_out["pred_masks"] = fill_holes_in_mask_scores(
+ current_out["pred_masks"], max_area=16)
+ if last_occluded.shape[0] == N_obj and N_obj > 1:
+ self._suppress_recently_occluded(
+ current_out["pred_masks"], last_occluded, frame_idx)
+ if self.num_maskmem > 0:
+ self._deferred_memory_encode(current_out, N_obj, vision_feats, feat_sizes, mux_state, device)
+ output_dict["non_cond_frame_outputs"][frame_idx] = current_out
+ lookback = max(self.num_maskmem, self.max_obj_ptrs_in_encoder)
+ for old_idx in list(output_dict["non_cond_frame_outputs"]):
+ if old_idx < frame_idx - lookback:
+ del output_dict["non_cond_frame_outputs"][old_idx]
+ n_before = mux_state.total_valid_entries
+ new_obj_scores = self._match_and_add_detections(det_masks, det_scores, current_out, mux_state,
+ vision_feats, feat_sizes, device, max_objects,
+ keep_alive if run_det else None)
+ n_added = mux_state.total_valid_entries - n_before
+ if n_added > 0:
+ last_occluded = torch.cat([last_occluded,
+ torch.full((n_added,), -1, device=device, dtype=torch.long)])
+ obj_scores.extend(new_obj_scores)
+
+ masks_out = current_out["pred_masks_high_res"][:, 0]
+ if keep_alive is not None:
+ for i in range(masks_out.shape[0]):
+ if keep_alive.get(i, 0) <= 0:
+ masks_out[i] = NO_OBJ_SCORE
+ N_obj_now = mux_state.total_valid_entries if mux_state is not None else 0
+ if N_obj_now > 0:
+ all_masks.append(pack_masks(masks_out).to(idev))
+ else:
+ all_masks.append(None)
+ if pbar is not None:
+ pbar.update(1)
+
+ # Next frame's backbone
+ if frame_idx + 1 < N:
+ if prefetch:
+ torch.cuda.current_stream(device).wait_stream(backbone_stream)
+ cur_bb = next_bb
+ else:
+ cur_bb = self._compute_backbone_frame(backbone_fn, _prep_frame(images, slice(frame_idx + 1, frame_idx + 2), device, dt, size), frame_idx=frame_idx + 1)
+
+ if not all_masks or all(m is None for m in all_masks):
+ return {"packed_masks": None, "n_frames": N, "scores": []}
+
+ max_obj = max(m.shape[0] for m in all_masks if m is not None)
+ sample = next(m for m in all_masks if m is not None)
+ empty_packed = torch.zeros(max_obj, *sample.shape[1:], dtype=torch.uint8, device=sample.device)
+ for i, m in enumerate(all_masks):
+ if m is None:
+ all_masks[i] = empty_packed
+ elif m.shape[0] < max_obj:
+ pad = torch.zeros(max_obj - m.shape[0], *m.shape[1:], dtype=torch.uint8, device=m.device)
+ all_masks[i] = torch.cat([m, pad], dim=0)
+ return {"packed_masks": torch.stack(all_masks, dim=0), "n_frames": N, "scores": obj_scores}
diff --git a/ComfyUI/comfy/ldm/seedvr/__pycache__/attention.cpython-312.pyc b/ComfyUI/comfy/ldm/seedvr/__pycache__/attention.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..cfbfdccce9be36e1fafaef62f44cf42dcc41d220
Binary files /dev/null and b/ComfyUI/comfy/ldm/seedvr/__pycache__/attention.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/seedvr/__pycache__/color_fix.cpython-312.pyc b/ComfyUI/comfy/ldm/seedvr/__pycache__/color_fix.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..c0b31eaef8e588a8136af7ace9c97ee2384b576c
Binary files /dev/null and b/ComfyUI/comfy/ldm/seedvr/__pycache__/color_fix.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/seedvr/__pycache__/constants.cpython-312.pyc b/ComfyUI/comfy/ldm/seedvr/__pycache__/constants.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..7a42c4041a70b5142a498fa74d5fb97995a56f84
Binary files /dev/null and b/ComfyUI/comfy/ldm/seedvr/__pycache__/constants.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/seedvr/__pycache__/model.cpython-312.pyc b/ComfyUI/comfy/ldm/seedvr/__pycache__/model.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..7708d7243a328b8c14a07d55994171135adf492a
Binary files /dev/null and b/ComfyUI/comfy/ldm/seedvr/__pycache__/model.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/seedvr/__pycache__/vae.cpython-312.pyc b/ComfyUI/comfy/ldm/seedvr/__pycache__/vae.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..0b259968f096e5090fcc5aac8e6b645ac6def879
Binary files /dev/null and b/ComfyUI/comfy/ldm/seedvr/__pycache__/vae.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/seedvr/attention.py b/ComfyUI/comfy/ldm/seedvr/attention.py
new file mode 100644
index 0000000000000000000000000000000000000000..11b4c1e4a5976bc3f027362fae3c97a2affe66fd
--- /dev/null
+++ b/ComfyUI/comfy/ldm/seedvr/attention.py
@@ -0,0 +1,51 @@
+import torch
+
+from comfy.ldm.modules import attention as _attention
+
+
+def _var_attention_qkv(q, k, v, heads, skip_reshape):
+ if skip_reshape:
+ return q, k, v, q.shape[-1]
+ total_tokens, embed_dim = q.shape
+ head_dim = embed_dim // heads
+ return (
+ q.view(total_tokens, heads, head_dim),
+ k.view(k.shape[0], heads, head_dim),
+ v.view(v.shape[0], heads, head_dim),
+ head_dim,
+ )
+
+
+def _var_attention_output(out, heads, head_dim, skip_output_reshape):
+ if skip_output_reshape:
+ return out
+ return out.reshape(-1, heads * head_dim)
+
+
+def var_attention_optimized_split(q, k, v, heads, cu_seqlens_q, cu_seqlens_k, *args, skip_reshape=False, skip_output_reshape=False, **kwargs):
+ q, k, v, head_dim = _var_attention_qkv(q, k, v, heads, skip_reshape)
+
+ q_split_indices = cu_seqlens_q[1:-1]
+ k_split_indices = cu_seqlens_k[1:-1]
+ if k.shape[0] != v.shape[0]:
+ raise ValueError("cu_seqlens_k does not match v token count")
+
+ q_splits = torch.tensor_split(q, q_split_indices, dim=0)
+ k_splits = torch.tensor_split(k, k_split_indices, dim=0)
+ v_splits = torch.tensor_split(v, k_split_indices, dim=0)
+ if len(q_splits) != len(k_splits) or len(q_splits) != len(v_splits):
+ raise ValueError("cu_seqlens_q and cu_seqlens_k must describe the same sequence count")
+
+ out = []
+ for q_i, k_i, v_i in zip(q_splits, k_splits, v_splits):
+ q_i = q_i.permute(1, 0, 2).unsqueeze(0)
+ k_i = k_i.permute(1, 0, 2).unsqueeze(0)
+ v_i = v_i.permute(1, 0, 2).unsqueeze(0)
+ out_i = _attention.optimized_attention(q_i, k_i, v_i, heads, skip_reshape=True, skip_output_reshape=True)
+ out.append(out_i.squeeze(0).permute(1, 0, 2))
+
+ out = torch.cat(out, dim=0)
+ return _var_attention_output(out, heads, head_dim, skip_output_reshape)
+
+
+optimized_var_attention = var_attention_optimized_split
diff --git a/ComfyUI/comfy/ldm/seedvr/color_fix.py b/ComfyUI/comfy/ldm/seedvr/color_fix.py
new file mode 100644
index 0000000000000000000000000000000000000000..a43cb5270442380707b89cd705d05e97f31edc4e
--- /dev/null
+++ b/ComfyUI/comfy/ldm/seedvr/color_fix.py
@@ -0,0 +1,301 @@
+import torch
+import torch.nn.functional as F
+from torch import Tensor
+
+from comfy.ldm.seedvr.constants import (
+ CIELAB_DELTA,
+ CIELAB_KAPPA,
+ D65_WHITE_X,
+ D65_WHITE_Z,
+ WAVELET_DECOMP_LEVELS,
+)
+
+
+def wavelet_blur(image: Tensor, radius):
+ max_safe_radius = max(1, min(image.shape[-2:]) // 8)
+ if radius > max_safe_radius:
+ radius = max_safe_radius
+
+ num_channels = image.shape[1]
+
+ kernel_vals = [
+ [0.0625, 0.125, 0.0625],
+ [0.125, 0.25, 0.125],
+ [0.0625, 0.125, 0.0625],
+ ]
+ kernel = torch.tensor(kernel_vals, dtype=image.dtype, device=image.device)
+ kernel = kernel[None, None].repeat(num_channels, 1, 1, 1)
+
+ image = F.pad(image, (radius, radius, radius, radius), mode='replicate')
+ output = F.conv2d(image, kernel, groups=num_channels, dilation=radius)
+
+ return output
+
+def wavelet_decomposition(image: Tensor, levels: int = WAVELET_DECOMP_LEVELS):
+ high_freq = torch.zeros_like(image)
+
+ for i in range(levels):
+ radius = 2 ** i
+ low_freq = wavelet_blur(image, radius)
+ high_freq.add_(image).sub_(low_freq)
+ image = low_freq
+
+ return high_freq, low_freq
+
+def wavelet_reconstruction(content_feat: Tensor, style_feat: Tensor) -> Tensor:
+
+ if content_feat.shape != style_feat.shape:
+ if len(content_feat.shape) >= 3:
+ style_feat = F.interpolate(
+ style_feat,
+ size=content_feat.shape[-2:],
+ mode='bilinear',
+ align_corners=False
+ )
+
+ content_high_freq, content_low_freq = wavelet_decomposition(content_feat)
+ del content_low_freq
+
+ style_high_freq, style_low_freq = wavelet_decomposition(style_feat)
+ del style_high_freq
+
+ if content_high_freq.shape != style_low_freq.shape:
+ style_low_freq = F.interpolate(
+ style_low_freq,
+ size=content_high_freq.shape[-2:],
+ mode='bilinear',
+ align_corners=False
+ )
+
+ content_high_freq.add_(style_low_freq)
+
+ return content_high_freq.clamp_(-1.0, 1.0)
+
+def _histogram_matching_channel(source: Tensor, reference: Tensor) -> Tensor:
+ original_shape = source.shape
+
+ source_flat = source.flatten()
+ reference_flat = reference.flatten()
+
+ source_sorted, source_indices = torch.sort(source_flat)
+ reference_sorted, _ = torch.sort(reference_flat)
+ del reference_flat
+
+ n_source = len(source_sorted)
+ n_reference = len(reference_sorted)
+
+ if n_source == n_reference:
+ matched_sorted = reference_sorted
+ else:
+ source_quantiles = torch.linspace(0, 1, n_source, device=source.device)
+ ref_indices = (source_quantiles * (n_reference - 1)).long()
+ ref_indices.clamp_(0, n_reference - 1)
+ matched_sorted = reference_sorted[ref_indices]
+ del source_quantiles, ref_indices, reference_sorted
+
+ del source_sorted, source_flat
+
+ inverse_indices = torch.argsort(source_indices)
+ del source_indices
+ matched_flat = matched_sorted[inverse_indices]
+ del matched_sorted, inverse_indices
+
+ return matched_flat.reshape(original_shape)
+
+def _lab_to_rgb_batch(lab: Tensor, matrix_inv: Tensor, epsilon: float, kappa: float) -> Tensor:
+ L, a, b = lab[:, 0], lab[:, 1], lab[:, 2]
+
+ fy = (L + 16.0) / 116.0
+ fx = a.div(500.0).add_(fy)
+ fz = fy - b / 200.0
+ del L, a, b
+
+ x = torch.where(
+ fx > epsilon,
+ torch.pow(fx, 3.0),
+ fx.mul(116.0).sub_(16.0).div_(kappa)
+ )
+ y = torch.where(
+ fy > epsilon,
+ torch.pow(fy, 3.0),
+ fy.mul(116.0).sub_(16.0).div_(kappa)
+ )
+ z = torch.where(
+ fz > epsilon,
+ torch.pow(fz, 3.0),
+ fz.mul(116.0).sub_(16.0).div_(kappa)
+ )
+ del fx, fy, fz
+
+ x.mul_(D65_WHITE_X)
+ z.mul_(D65_WHITE_Z)
+
+ xyz = torch.stack([x, y, z], dim=1)
+ del x, y, z
+
+ B, _, H, W = xyz.shape
+ xyz_flat = xyz.permute(0, 2, 3, 1).reshape(-1, 3)
+ del xyz
+
+ xyz_flat = xyz_flat.to(dtype=matrix_inv.dtype)
+ rgb_linear_flat = torch.matmul(xyz_flat, matrix_inv.T)
+ del xyz_flat
+
+ rgb_linear = rgb_linear_flat.reshape(B, H, W, 3).permute(0, 3, 1, 2)
+ del rgb_linear_flat
+
+ mask = rgb_linear > 0.0031308
+ rgb = torch.where(
+ mask,
+ torch.pow(torch.clamp(rgb_linear, min=0.0), 1.0 / 2.4).mul_(1.055).sub_(0.055),
+ rgb_linear * 12.92
+ )
+ del mask, rgb_linear
+
+ return torch.clamp(rgb, 0.0, 1.0)
+
+def _rgb_to_lab_batch(rgb: Tensor, matrix: Tensor, epsilon: float, kappa: float) -> Tensor:
+ mask = rgb > 0.04045
+ rgb_linear = torch.where(
+ mask,
+ torch.pow((rgb + 0.055) / 1.055, 2.4),
+ rgb / 12.92
+ )
+ del mask
+
+ B, _, H, W = rgb_linear.shape
+ rgb_flat = rgb_linear.permute(0, 2, 3, 1).reshape(-1, 3)
+ del rgb_linear
+
+ rgb_flat = rgb_flat.to(dtype=matrix.dtype)
+ xyz_flat = torch.matmul(rgb_flat, matrix.T)
+ del rgb_flat
+
+ xyz = xyz_flat.reshape(B, H, W, 3).permute(0, 3, 1, 2)
+ del xyz_flat
+
+ xyz[:, 0].div_(D65_WHITE_X)
+ xyz[:, 2].div_(D65_WHITE_Z)
+
+ epsilon_cubed = epsilon ** 3
+ mask = xyz > epsilon_cubed
+ f_xyz = torch.where(
+ mask,
+ torch.pow(xyz, 1.0 / 3.0),
+ xyz.mul(kappa).add_(16.0).div_(116.0)
+ )
+ del xyz, mask
+
+ L = f_xyz[:, 1].mul(116.0).sub_(16.0)
+ a = (f_xyz[:, 0] - f_xyz[:, 1]).mul_(500.0)
+ b = (f_xyz[:, 1] - f_xyz[:, 2]).mul_(200.0)
+ del f_xyz
+
+ return torch.stack([L, a, b], dim=1)
+
+def lab_color_transfer(
+ content_feat: Tensor,
+ style_feat: Tensor,
+ luminance_weight: float = 0.8
+) -> Tensor:
+ content_feat = wavelet_reconstruction(content_feat, style_feat)
+
+ if content_feat.shape != style_feat.shape:
+ style_feat = F.interpolate(
+ style_feat,
+ size=content_feat.shape[-2:],
+ mode='bilinear',
+ align_corners=False
+ )
+
+ device = content_feat.device
+ original_dtype = content_feat.dtype
+ content_feat = content_feat.float()
+ style_feat = style_feat.float()
+
+ rgb_to_xyz_matrix = torch.tensor([
+ [0.4124564, 0.3575761, 0.1804375],
+ [0.2126729, 0.7151522, 0.0721750],
+ [0.0193339, 0.1191920, 0.9503041]
+ ], dtype=torch.float32, device=device)
+
+ xyz_to_rgb_matrix = torch.tensor([
+ [ 3.2404542, -1.5371385, -0.4985314],
+ [-0.9692660, 1.8760108, 0.0415560],
+ [ 0.0556434, -0.2040259, 1.0572252]
+ ], dtype=torch.float32, device=device)
+
+ epsilon = CIELAB_DELTA
+ kappa = CIELAB_KAPPA
+
+ content_feat.add_(1.0).mul_(0.5).clamp_(0.0, 1.0)
+ style_feat.add_(1.0).mul_(0.5).clamp_(0.0, 1.0)
+
+ content_lab = _rgb_to_lab_batch(content_feat, rgb_to_xyz_matrix, epsilon, kappa)
+ del content_feat
+
+ style_lab = _rgb_to_lab_batch(style_feat, rgb_to_xyz_matrix, epsilon, kappa)
+ del style_feat, rgb_to_xyz_matrix
+
+ matched_a = _histogram_matching_channel(content_lab[:, 1], style_lab[:, 1])
+ matched_b = _histogram_matching_channel(content_lab[:, 2], style_lab[:, 2])
+
+ if luminance_weight < 1.0:
+ matched_L = _histogram_matching_channel(content_lab[:, 0], style_lab[:, 0])
+ result_L = content_lab[:, 0].mul(luminance_weight).add_(matched_L.mul(1.0 - luminance_weight))
+ del matched_L
+ else:
+ result_L = content_lab[:, 0]
+
+ del content_lab, style_lab
+
+ result_lab = torch.stack([result_L, matched_a, matched_b], dim=1)
+ del result_L, matched_a, matched_b
+
+ result_rgb = _lab_to_rgb_batch(result_lab, xyz_to_rgb_matrix, epsilon, kappa)
+ del result_lab, xyz_to_rgb_matrix
+
+ result = result_rgb.mul_(2.0).sub_(1.0)
+ del result_rgb
+
+ result = result.to(original_dtype)
+
+ return result
+
+
+def wavelet_color_transfer(content_feat: Tensor, style_feat: Tensor) -> Tensor:
+ return wavelet_reconstruction(content_feat, style_feat)
+
+
+def adain_color_transfer(content_feat: Tensor, style_feat: Tensor, eps: float = 1e-5) -> Tensor:
+ if content_feat.shape != style_feat.shape:
+ style_feat = F.interpolate(
+ style_feat,
+ size=content_feat.shape[-2:],
+ mode='bilinear',
+ align_corners=False,
+ )
+
+ original_dtype = content_feat.dtype
+ content_feat = content_feat.float()
+ style_feat = style_feat.float()
+
+ b, c = content_feat.shape[:2]
+ content_flat = content_feat.reshape(b, c, -1)
+ style_flat = style_feat.reshape(b, c, -1)
+
+ content_mean = content_flat.mean(dim=2).reshape(b, c, 1, 1)
+ content_std = (content_flat.var(dim=2, correction=0) + eps).sqrt().reshape(b, c, 1, 1)
+ style_mean = style_flat.mean(dim=2).reshape(b, c, 1, 1)
+ style_std = (style_flat.var(dim=2, correction=0) + eps).sqrt().reshape(b, c, 1, 1)
+ del content_flat, style_flat
+
+ normalized = (content_feat - content_mean) / content_std
+ del content_mean, content_std
+ result = normalized * style_std + style_mean
+ del normalized, style_mean, style_std
+
+ result = result.clamp_(-1.0, 1.0)
+ if result.dtype != original_dtype:
+ result = result.to(original_dtype)
+ return result
diff --git a/ComfyUI/comfy/ldm/seedvr/constants.py b/ComfyUI/comfy/ldm/seedvr/constants.py
new file mode 100644
index 0000000000000000000000000000000000000000..12c4b4bef86c6099c08e513b3cf2c4a89db4d1b4
--- /dev/null
+++ b/ComfyUI/comfy/ldm/seedvr/constants.py
@@ -0,0 +1,48 @@
+"""SeedVR2 constants."""
+
+# Temporal chunk-size law: the sampler's activation wall is linear in
+# T_latent * pixel area (17-cell resolution sweep + T bisection, RTX 5090, 3b fp16):
+# max_latent_frames = (free_GiB - RESERVED - K*SIGMA) / (GIB_PER_MPX_FRAME * megapixels)
+# RESERVED covers model staging plus fixed CUDA/torch overhead; SIGMA is the measured
+# run-to-run spread of the wall; K=4 trades ~10% smaller chunks for ~1e-5 OOM odds.
+SEEDVR2_CHUNK_GIB_PER_MPX_FRAME = 0.55
+SEEDVR2_CHUNK_RESERVED_GIB = 8.5
+SEEDVR2_CHUNK_SIGMA_GIB = 0.55
+SEEDVR2_CHUNK_SIGMA_K = 4
+
+SEEDVR2_7B_VID_DIM = 3072
+SEEDVR2_OOM_BACKOFF_DIVISOR = 2
+SEEDVR2_DTYPE_BYTES_FLOOR = 4
+SEEDVR2_7B_MLP_CHUNK = 8192
+SEEDVR2_ROPE_PARTIAL_CHUNK_TOKENS = 4096 # partial-RoPE application token-chunk.
+SEEDVR2_LATENT_CHANNELS = 16
+
+SEEDVR2_COLOR_MEM_HEADROOM = 0.75
+SEEDVR2_LAB_SCALE_MULTIPLIER = 13
+SEEDVR2_WAVELET_SCALE_MULTIPLIER = 10 # per-frame byte multiplier, wavelet path.
+SEEDVR2_ADAIN_SCALE_MULTIPLIER = 6
+
+BYTEDANCE_VAE_SCALING_FACTOR = 0.9152 # configs_3b/main.yaml:57.
+BYTEDANCE_VAE_SHIFTING_FACTOR = 0.0
+BYTEDANCE_VAE_CONV_MEM_GIB = 0.5
+BYTEDANCE_VAE_NORM_MEM_GIB = 0.5
+BYTEDANCE_LOGVAR_CLAMP_MIN = -30.0 # video_vae_v3/modules/types.py:28.
+BYTEDANCE_LOGVAR_CLAMP_MAX = 20.0 # video_vae_v3/modules/types.py:28.
+BYTEDANCE_GN_CHUNKS_FP16 = 4 # causal_inflation_lib.py:351 (GroupNorm chunk count, fp16).
+BYTEDANCE_GN_CHUNKS_FP32 = 2 # causal_inflation_lib.py:351 (GroupNorm chunk count, fp32).
+BYTEDANCE_BLOCK_OUT_CHANNELS = (128, 256, 512, 512) # s8_c16_t4_inflation_sd3.yaml:7-11.
+BYTEDANCE_SLICING_SAMPLE_MIN = 4 # s8_c16_t4_inflation_sd3.yaml:22 (slicing_sample_min_size).
+BYTEDANCE_VAE_TEMPORAL_DOWNSAMPLE = 4 # infer.py:230 (temporal_downsample_factor); the 4n+1 factor.
+BYTEDANCE_VAE_SPATIAL_DOWNSAMPLE = 8 # infer.py:231 (spatial_downsample_factor).
+BYTEDANCE_720P_REF_AREA = 45 * 80 # dit_v2/window.py:32 (720p reference area for window scaling).
+BYTEDANCE_MAX_TEMPORAL_WINDOW = 30 # dit_v2/window.py:35 (max temporal window frames).
+BYTEDANCE_ROPE_MAX_FREQ = 256 # dit_v2/rope.py:31 (pixel-RoPE max frequency).
+BYTEDANCE_SINUSOIDAL_DIM = 256 # dit_3b/nadit.py:120 (timestep sinusoidal embed dim).
+
+ROPE_THETA = 10000 # RoPE base; Su et al., "RoFormer", arXiv:2104.09864.
+
+CIELAB_DELTA = 6.0 / 29.0 # CIE 15 (delta).
+CIELAB_KAPPA = (29.0 / 3.0) ** 3 # CIE 15 (kappa).
+D65_WHITE_X = 0.95047 # CIE D65 standard illuminant Xn (Yn = 1).
+D65_WHITE_Z = 1.08883 # CIE D65 standard illuminant Zn.
+WAVELET_DECOMP_LEVELS = 5 # wavelet color-fix decomposition depth (GIMP/Krita; StableSR).
diff --git a/ComfyUI/comfy/ldm/seedvr/model.py b/ComfyUI/comfy/ldm/seedvr/model.py
new file mode 100644
index 0000000000000000000000000000000000000000..a978698d56c9c501529be42c933d54064328db67
--- /dev/null
+++ b/ComfyUI/comfy/ldm/seedvr/model.py
@@ -0,0 +1,1361 @@
+from dataclasses import dataclass
+from typing import Optional, Tuple, Union, List, Dict, Any, Callable
+import torch.nn.functional as F
+from math import ceil, pi
+import torch
+from itertools import accumulate, chain
+from comfy.ldm.modules.diffusionmodules.model import get_timestep_embedding
+from comfy.ldm.seedvr.attention import optimized_var_attention
+from torch.nn.modules.utils import _triple
+from torch import nn
+import math
+from comfy.ldm.flux.math import apply_rope1
+from comfy.ldm.seedvr.constants import (
+ BYTEDANCE_720P_REF_AREA,
+ BYTEDANCE_MAX_TEMPORAL_WINDOW,
+ BYTEDANCE_ROPE_MAX_FREQ,
+ BYTEDANCE_SINUSOIDAL_DIM,
+ ROPE_THETA,
+ SEEDVR2_7B_MLP_CHUNK,
+ SEEDVR2_7B_VID_DIM,
+ SEEDVR2_LATENT_CHANNELS,
+ SEEDVR2_ROPE_PARTIAL_CHUNK_TOKENS,
+)
+import comfy.model_management
+import comfy.ops
+
+class Cache:
+ def __init__(self, disable=False, prefix="", cache=None):
+ self.cache = cache if cache is not None else {}
+ self.disable = disable
+ self.prefix = prefix
+
+ def __call__(self, key: str, fn: Callable):
+ if self.disable:
+ return fn()
+
+ key = self.prefix + key
+ if key not in self.cache:
+ result = fn()
+ self.cache[key] = result
+ return self.cache[key]
+
+ def namespace(self, namespace: str):
+ return Cache(
+ disable=self.disable,
+ prefix=self.prefix + namespace + ".",
+ cache=self.cache,
+ )
+
+def repeat_concat(
+ vid: torch.FloatTensor, # (VL ... c)
+ txt: torch.FloatTensor, # (TL ... c)
+ vid_len: torch.LongTensor, # (n*b)
+ txt_len: torch.LongTensor, # (b)
+ txt_repeat: List, # (n)
+) -> torch.FloatTensor: # (L ... c)
+ vid = torch.split(vid, vid_len.tolist())
+ txt = torch.split(txt, txt_len.tolist())
+ txt = [[x] * n for x, n in zip(txt, txt_repeat)]
+ txt = list(chain(*txt))
+ return torch.cat(list(chain(*zip(vid, txt))))
+
+def repeat_concat_idx(
+ vid_len: torch.LongTensor, # (n*b)
+ txt_len: torch.LongTensor, # (b)
+ txt_repeat: torch.LongTensor, # (n)
+) -> Tuple[
+ Callable,
+ Callable,
+]:
+ device = vid_len.device
+ vid_idx = torch.arange(vid_len.sum(), device=device)
+ txt_idx = torch.arange(len(vid_idx), len(vid_idx) + txt_len.sum(), device=device)
+ txt_repeat_list = txt_repeat.tolist()
+ tgt_idx = repeat_concat(vid_idx, txt_idx, vid_len, txt_len, txt_repeat_list)
+ src_idx = torch.argsort(tgt_idx)
+ txt_idx_len = len(tgt_idx) - len(vid_idx)
+ repeat_txt_len = (txt_len * txt_repeat).tolist()
+
+ def unconcat_coalesce(all):
+ vid_out, txt_out = all[src_idx].split([len(vid_idx), txt_idx_len])
+ txt_out_coalesced = []
+ for txt, repeat_time in zip(txt_out.split(repeat_txt_len), txt_repeat_list):
+ txt = txt.reshape(-1, repeat_time, *txt.shape[1:]).mean(1)
+ txt_out_coalesced.append(txt)
+ return vid_out, torch.cat(txt_out_coalesced)
+
+ return (
+ lambda vid, txt: torch.cat([vid, txt])[tgt_idx],
+ lambda all: unconcat_coalesce(all),
+ )
+
+def cumulative_lengths(lengths):
+ return [0, *accumulate(lengths)]
+
+
+@dataclass
+class MMArg:
+ vid: Any
+ txt: Any
+
+def get_args(key: str, args: List[Any]) -> List[Any]:
+ return [getattr(v, key) if isinstance(v, MMArg) else v for v in args]
+
+
+def get_kwargs(key: str, kwargs: Dict[str, Any]) -> Dict[str, Any]:
+ return {k: getattr(v, key) if isinstance(v, MMArg) else v for k, v in kwargs.items()}
+
+
+def get_window_op(name: str):
+ if name == "720pwin_by_size_bysize":
+ return make_720Pwindows_bysize
+ if name == "720pswin_by_size_bysize":
+ return make_shifted_720Pwindows_bysize
+ raise ValueError(f"Unknown windowing method: {name}")
+
+
+def make_720Pwindows_bysize(size: Tuple[int, int, int], num_windows: Tuple[int, int, int]):
+ t, h, w = size
+ resized_nt, resized_nh, resized_nw = num_windows
+ scale = math.sqrt(BYTEDANCE_720P_REF_AREA / (h * w))
+ resized_h, resized_w = round(h * scale), round(w * scale)
+ wh, ww = ceil(resized_h / resized_nh), ceil(resized_w / resized_nw)
+ wt = ceil(min(t, BYTEDANCE_MAX_TEMPORAL_WINDOW) / resized_nt)
+ nt, nh, nw = ceil(t / wt), ceil(h / wh), ceil(w / ww)
+ return [
+ (
+ slice(it * wt, min((it + 1) * wt, t)),
+ slice(ih * wh, min((ih + 1) * wh, h)),
+ slice(iw * ww, min((iw + 1) * ww, w)),
+ )
+ for iw in range(nw)
+ if min((iw + 1) * ww, w) > iw * ww
+ for ih in range(nh)
+ if min((ih + 1) * wh, h) > ih * wh
+ for it in range(nt)
+ if min((it + 1) * wt, t) > it * wt
+ ]
+
+def make_shifted_720Pwindows_bysize(size: Tuple[int, int, int], num_windows: Tuple[int, int, int]):
+ t, h, w = size
+ resized_nt, resized_nh, resized_nw = num_windows
+ scale = math.sqrt(BYTEDANCE_720P_REF_AREA / (h * w))
+ resized_h, resized_w = round(h * scale), round(w * scale)
+ wh, ww = ceil(resized_h / resized_nh), ceil(resized_w / resized_nw)
+ wt = ceil(min(t, BYTEDANCE_MAX_TEMPORAL_WINDOW) / resized_nt)
+
+ st, sh, sw = (
+ 0.5 if wt < t else 0,
+ 0.5 if wh < h else 0,
+ 0.5 if ww < w else 0,
+ )
+ nt, nh, nw = ceil((t - st) / wt), ceil((h - sh) / wh), ceil((w - sw) / ww)
+ nt, nh, nw = (
+ nt + 1 if st > 0 else 1,
+ nh + 1 if sh > 0 else 1,
+ nw + 1 if sw > 0 else 1,
+ )
+ return [
+ (
+ slice(max(int((it - st) * wt), 0), min(int((it - st + 1) * wt), t)),
+ slice(max(int((ih - sh) * wh), 0), min(int((ih - sh + 1) * wh), h)),
+ slice(max(int((iw - sw) * ww), 0), min(int((iw - sw + 1) * ww), w)),
+ )
+ for iw in range(nw)
+ if min(int((iw - sw + 1) * ww), w) > max(int((iw - sw) * ww), 0)
+ for ih in range(nh)
+ if min(int((ih - sh + 1) * wh), h) > max(int((ih - sh) * wh), 0)
+ for it in range(nt)
+ if min(int((it - st + 1) * wt), t) > max(int((it - st) * wt), 0)
+ ]
+
+class RotaryEmbedding(nn.Module):
+ def __init__(
+ self,
+ dim,
+ freqs_for = 'lang',
+ theta = 10000,
+ max_freq = 10,
+ ):
+ super().__init__()
+
+ self.freqs_for = freqs_for
+
+ if freqs_for == 'lang':
+ freqs = 1. / (theta ** (torch.arange(0, dim, 2)[:(dim // 2)].float() / dim))
+ elif freqs_for == 'pixel':
+ freqs = torch.linspace(1., max_freq / 2, dim // 2) * pi
+ else:
+ raise ValueError(f"Unknown rotary frequency type: {freqs_for}")
+
+ self.register_buffer("freqs", freqs)
+
+ @property
+ def device(self):
+ return self.freqs.device
+
+ def get_axial_freqs(
+ self,
+ *dims,
+ offsets = None
+ ):
+ Colon = slice(None)
+ all_freqs = []
+
+ if exists(offsets):
+ if len(offsets) != len(dims):
+ raise ValueError(f"SeedVR2 rotary offsets length must match dims length, got {len(offsets)} and {len(dims)}.")
+
+ for ind, dim in enumerate(dims):
+
+ offset = 0
+ if exists(offsets):
+ offset = offsets[ind]
+
+ if self.freqs_for == 'pixel':
+ pos = torch.linspace(-1, 1, steps = dim, device = self.device)
+ else:
+ pos = torch.arange(dim, device = self.device)
+
+ pos = pos + offset
+
+ freqs = self.forward(pos)
+
+ all_axis = [None] * len(dims)
+ all_axis[ind] = Colon
+
+ new_axis_slice = (Ellipsis, *all_axis, Colon)
+ all_freqs.append(freqs[new_axis_slice])
+
+ all_freqs = torch.broadcast_tensors(*all_freqs)
+ return torch.cat(all_freqs, dim = -1)
+
+ def forward(
+ self,
+ t,
+ ):
+ freqs = self.freqs
+
+ freqs = torch.einsum('..., f -> ... f', t.type(freqs.dtype), freqs)
+ freqs = freqs.unsqueeze(-1).expand(*freqs.shape, 2).flatten(-2)
+
+ return freqs
+
+class RotaryEmbeddingBase(nn.Module):
+ def __init__(self, dim: int, rope_dim: int):
+ super().__init__()
+ self.rope = RotaryEmbedding(
+ dim=dim // rope_dim,
+ freqs_for="pixel",
+ max_freq=BYTEDANCE_ROPE_MAX_FREQ,
+ )
+
+ def get_axial_freqs(self, *dims):
+ return self.rope.get_axial_freqs(*dims)
+
+
+class RotaryEmbedding3d(RotaryEmbeddingBase):
+ def __init__(self, dim: int):
+ super().__init__(dim, rope_dim=3)
+ self.mm = False
+
+
+class NaRotaryEmbedding3d(RotaryEmbedding3d):
+ def forward(
+ self,
+ q: torch.FloatTensor,
+ k: torch.FloatTensor,
+ shape: torch.LongTensor,
+ cache: Cache,
+ ) -> Tuple[
+ torch.FloatTensor,
+ torch.FloatTensor,
+ ]:
+ freqs = cache("rope_freqs_3d", lambda: self.get_freqs(shape))
+ freqs = freqs.to(device=q.device)
+ q = q.transpose(0, 1)
+ k = k.transpose(0, 1)
+ q = _apply_seedvr2_rotary_emb(freqs, q.float()).to(q.dtype)
+ k = _apply_seedvr2_rotary_emb(freqs, k.float()).to(k.dtype)
+ q = q.transpose(0, 1)
+ k = k.transpose(0, 1)
+ return q, k
+
+ @torch._dynamo.disable
+ def get_freqs(
+ self,
+ shape: torch.LongTensor,
+ ) -> torch.Tensor:
+ # Primary provenance: ByteDance-Seed/SeedVR models/dit/rope.py builds
+ # 7B pixel RoPE with the interleaved-angle convention, not Comfy's
+ # Flux freqs_cis matrix.
+ plain_rope = RotaryEmbedding(
+ dim=self.rope.freqs.numel() * 2,
+ freqs_for="pixel",
+ max_freq=BYTEDANCE_ROPE_MAX_FREQ,
+ )
+ plain_rope = plain_rope.to(self.rope.device)
+ freq_list = []
+ for f, h, w in shape.tolist():
+ freqs = plain_rope.get_axial_freqs(f, h, w)
+ freq_list.append(freqs.view(-1, freqs.size(-1)))
+ return torch.cat(freq_list, dim=0)
+
+
+class MMRotaryEmbeddingBase(RotaryEmbeddingBase):
+ def __init__(self, dim: int, rope_dim: int):
+ super().__init__(dim, rope_dim)
+ self.rope = RotaryEmbedding(
+ dim=dim // rope_dim,
+ freqs_for="lang",
+ theta=ROPE_THETA,
+ )
+ self.mm = True
+
+def slice_at_dim(t, dim_slice: slice, *, dim):
+ dim += (t.ndim if dim < 0 else 0)
+ colons = [slice(None)] * t.ndim
+ colons[dim] = dim_slice
+ return t[tuple(colons)]
+
+def rotate_half(x):
+ x = x.reshape(*x.shape[:-1], x.shape[-1] // 2, 2)
+ x1, x2 = x.unbind(dim = -1)
+ x = torch.stack((-x2, x1), dim = -1)
+ return x.flatten(-2)
+def exists(val):
+ return val is not None
+
+def _apply_seedvr2_rotary_emb(
+ freqs: torch.Tensor,
+ t: torch.Tensor,
+ start_index: int = 0,
+ scale: float = 1.0,
+ seq_dim: int = -2,
+ freqs_seq_dim: int | None = None,
+) -> torch.Tensor:
+ dtype = t.dtype
+ if freqs_seq_dim is None and (freqs.ndim == 2 or t.ndim == 3):
+ freqs_seq_dim = 0
+
+ if t.ndim == 3 or freqs_seq_dim is not None:
+ seq_len = t.shape[seq_dim]
+ freqs = slice_at_dim(freqs, slice(-seq_len, None), dim=freqs_seq_dim)
+
+ rot_feats = freqs.shape[-1]
+ end_index = start_index + rot_feats
+
+ t_left = t[..., :start_index]
+ t_middle = t[..., start_index:end_index]
+ t_right = t[..., end_index:]
+
+ freqs = freqs.to(device=t_middle.device, dtype=t_middle.dtype)
+ cos = freqs.cos() * scale
+ sin = freqs.sin() * scale
+ t_middle = (t_middle * cos) + (rotate_half(t_middle) * sin)
+ return torch.cat((t_left, t_middle, t_right), dim=-1).to(dtype)
+
+def _to_flux_freqs_cis(freqs_interleaved: torch.Tensor) -> torch.Tensor:
+ angles = freqs_interleaved[..., ::2].float()
+ cos = torch.cos(angles)
+ sin = torch.sin(angles)
+ out = torch.stack([cos, -sin, sin, cos], dim=-1)
+ return out.reshape(*out.shape[:-1], 2, 2)
+
+
+def _apply_rope1_partial(t: torch.Tensor, freqs_cis: torch.Tensor) -> torch.Tensor:
+ out = t.clone() if t.requires_grad or comfy.model_management.in_training else t
+ rot_d = 2 * freqs_cis.shape[-3]
+ seq_len = out.shape[-2]
+ for start in range(0, seq_len, SEEDVR2_ROPE_PARTIAL_CHUNK_TOKENS):
+ end = min(start + SEEDVR2_ROPE_PARTIAL_CHUNK_TOKENS, seq_len)
+ freqs_chunk = freqs_cis[start:end]
+ if rot_d == out.shape[-1]:
+ out[..., start:end, :] = apply_rope1(out[..., start:end, :], freqs_chunk).to(out.dtype)
+ else:
+ out[..., start:end, :rot_d] = apply_rope1(out[..., start:end, :rot_d], freqs_chunk).to(out.dtype)
+ return out
+
+
+class NaMMRotaryEmbedding3d(MMRotaryEmbeddingBase):
+ def __init__(self, dim: int):
+ super().__init__(dim, rope_dim=3)
+
+ def forward(
+ self,
+ vid_q: torch.FloatTensor, # L h d
+ vid_k: torch.FloatTensor, # L h d
+ vid_shape: torch.LongTensor, # B 3
+ txt_q: torch.FloatTensor, # L h d
+ txt_k: torch.FloatTensor, # L h d
+ txt_shape: torch.LongTensor, # B 1
+ cache: Cache,
+ ) -> Tuple[
+ torch.FloatTensor,
+ torch.FloatTensor,
+ torch.FloatTensor,
+ torch.FloatTensor,
+ ]:
+ vid_freqs, txt_freqs = cache(
+ "mmrope_freqs_3d",
+ lambda: self.get_freqs(vid_shape, txt_shape),
+ )
+ target_device = vid_q.device
+ if vid_freqs.device != target_device:
+ vid_freqs = vid_freqs.to(target_device)
+ if txt_freqs.device != target_device:
+ txt_freqs = txt_freqs.to(target_device)
+ vid_q = vid_q.transpose(0, 1)
+ vid_k = vid_k.transpose(0, 1)
+ vid_q = _apply_rope1_partial(vid_q, vid_freqs)
+ vid_k = _apply_rope1_partial(vid_k, vid_freqs)
+ vid_q = vid_q.transpose(0, 1)
+ vid_k = vid_k.transpose(0, 1)
+
+ txt_q = txt_q.transpose(0, 1)
+ txt_k = txt_k.transpose(0, 1)
+ txt_q = _apply_rope1_partial(txt_q, txt_freqs)
+ txt_k = _apply_rope1_partial(txt_k, txt_freqs)
+ txt_q = txt_q.transpose(0, 1)
+ txt_k = txt_k.transpose(0, 1)
+ return vid_q, vid_k, txt_q, txt_k
+
+ @torch._dynamo.disable # Disable compilation: .tolist() is data-dependent and causes graph breaks
+ def get_freqs(
+ self,
+ vid_shape: torch.LongTensor,
+ txt_shape: torch.LongTensor,
+ ) -> Tuple[
+ torch.Tensor,
+ torch.Tensor,
+ ]:
+
+ max_temporal = 0
+ max_height = 0
+ max_width = 0
+ max_txt_len = 0
+
+ for (f, h, w), l in zip(vid_shape.tolist(), txt_shape[:, 0].tolist()):
+ max_temporal = max(max_temporal, l + f)
+ max_height = max(max_height, h)
+ max_width = max(max_width, w)
+ max_txt_len = max(max_txt_len, l)
+
+ autocast_device = "cuda" if torch.cuda.is_available() else "cpu"
+ with torch.amp.autocast(autocast_device, enabled=False):
+ vid_freqs = self.get_axial_freqs(
+ max_temporal + 16,
+ max_height + 4,
+ max_width + 4,
+ ).float()
+ txt_freqs = self.get_axial_freqs(max_txt_len + 16)
+
+ vid_freq_list, txt_freq_list = [], []
+ for (f, h, w), l in zip(vid_shape.tolist(), txt_shape[:, 0].tolist()):
+ vid_freq = vid_freqs[l : l + f, :h, :w].reshape(-1, vid_freqs.size(-1))
+ txt_freq = txt_freqs[:l].repeat(1, 3).reshape(-1, vid_freqs.size(-1))
+ vid_freq_list.append(vid_freq)
+ txt_freq_list.append(txt_freq)
+ vid_freqs_interleaved = torch.cat(vid_freq_list, dim=0)
+ txt_freqs_interleaved = torch.cat(txt_freq_list, dim=0)
+
+ return _to_flux_freqs_cis(vid_freqs_interleaved), _to_flux_freqs_cis(txt_freqs_interleaved)
+
+class MMModule(nn.Module):
+ def __init__(
+ self,
+ module: Callable[..., nn.Module],
+ *args,
+ shared_weights: bool = False,
+ vid_only: bool = False,
+ **kwargs,
+ ):
+ super().__init__()
+ self.shared_weights = shared_weights
+ self.vid_only = vid_only
+ if self.shared_weights:
+ if get_args("vid", args) != get_args("txt", args):
+ raise ValueError("SeedVR2 shared MMModule requires matching vid/txt args.")
+ if get_kwargs("vid", kwargs) != get_kwargs("txt", kwargs):
+ raise ValueError("SeedVR2 shared MMModule requires matching vid/txt kwargs.")
+ self.all = module(*get_args("vid", args), **get_kwargs("vid", kwargs))
+ else:
+ self.vid = module(*get_args("vid", args), **get_kwargs("vid", kwargs))
+ self.txt = (
+ module(*get_args("txt", args), **get_kwargs("txt", kwargs))
+ if not vid_only
+ else None
+ )
+
+ def forward(
+ self,
+ vid: torch.FloatTensor,
+ txt: torch.FloatTensor,
+ *args,
+ **kwargs,
+ ) -> Tuple[
+ torch.FloatTensor,
+ torch.FloatTensor,
+ ]:
+ vid_module = self.vid if not self.shared_weights else self.all
+ vid = vid_module(vid, *get_args("vid", args), **get_kwargs("vid", kwargs))
+ if not self.vid_only:
+ txt_module = self.txt if not self.shared_weights else self.all
+ txt = txt.to(device=vid.device, dtype=vid.dtype)
+ txt = txt_module(txt, *get_args("txt", args), **get_kwargs("txt", kwargs))
+ return vid, txt
+
+def get_na_rope(rope_type: Optional[str], dim: int):
+ if rope_type is None:
+ return None
+ if rope_type == "rope3d":
+ return NaRotaryEmbedding3d(dim=dim)
+ if rope_type == "mmrope3d":
+ return NaMMRotaryEmbedding3d(dim=dim)
+ raise ValueError(f"Unknown SeedVR2 rope type: {rope_type}")
+
+class NaMMAttention(nn.Module):
+ def __init__(
+ self,
+ vid_dim: int,
+ txt_dim: int,
+ heads: int,
+ head_dim: int,
+ qk_bias: bool,
+ qk_norm,
+ qk_norm_eps: float,
+ rope_type: Optional[str],
+ rope_dim: int,
+ shared_weights: bool,
+ device, dtype, operations,
+ ):
+ super().__init__()
+ dim = MMArg(vid_dim, txt_dim)
+ self.heads = heads
+ inner_dim = heads * head_dim
+ qkv_dim = inner_dim * 3
+ self.head_dim = head_dim
+ self.proj_qkv = MMModule(
+ operations.Linear, dim, qkv_dim, bias=qk_bias, shared_weights=shared_weights, device=device, dtype=dtype
+ )
+ self.proj_out = MMModule(operations.Linear, inner_dim, dim, shared_weights=shared_weights, device=device, dtype=dtype)
+ self.norm_q = MMModule(
+ qk_norm,
+ normalized_shape=head_dim,
+ eps=qk_norm_eps,
+ elementwise_affine=True,
+ shared_weights=shared_weights,
+ device=device, dtype=dtype
+ )
+ self.norm_k = MMModule(
+ qk_norm,
+ normalized_shape=head_dim,
+ eps=qk_norm_eps,
+ elementwise_affine=True,
+ shared_weights=shared_weights,
+ device=device, dtype=dtype
+ )
+
+
+ self.rope = get_na_rope(rope_type=rope_type, dim=rope_dim)
+
+def window(
+ hid: torch.FloatTensor, # (L c)
+ hid_shape: torch.LongTensor, # (b n)
+ window_fn: Callable[[torch.Tensor], List[torch.Tensor]],
+):
+ hid = unflatten(hid, hid_shape)
+ hid = list(map(window_fn, hid))
+ hid_windows_list = [len(x) for x in hid]
+ hid_windows = torch.as_tensor(hid_windows_list, device=hid_shape.device)
+ hid = list(chain(*hid))
+ hid_len_list = [math.prod(x.shape[:-1]) for x in hid]
+ hid, hid_shape = flatten(hid)
+ return hid, hid_shape, hid_windows, hid_len_list, hid_windows_list
+
+def window_idx(
+ hid_shape: torch.LongTensor, # (b n)
+ window_fn: Callable[[torch.Tensor], List[torch.Tensor]],
+):
+ hid_idx = torch.arange(hid_shape.prod(-1).sum(), device=hid_shape.device).unsqueeze(-1)
+ tgt_idx, tgt_shape, tgt_windows, tgt_len_list, tgt_windows_list = window(hid_idx, hid_shape, window_fn)
+ tgt_idx = tgt_idx.squeeze(-1)
+ src_idx = torch.argsort(tgt_idx)
+ return (
+ lambda hid: torch.index_select(hid, 0, tgt_idx),
+ lambda hid: torch.index_select(hid, 0, src_idx),
+ tgt_shape,
+ tgt_windows,
+ tgt_len_list,
+ tgt_windows_list,
+ )
+
+class NaSwinAttention(NaMMAttention):
+ def __init__(
+ self,
+ *args,
+ window: Union[int, Tuple[int, int, int]],
+ window_method: str,
+ version: bool = False,
+ **kwargs,
+ ):
+ super().__init__(*args, **kwargs)
+ self.version_7b = version
+ self.window = _triple(window)
+ self.window_method = window_method
+ if not all(isinstance(v, int) and v >= 0 for v in self.window):
+ raise ValueError(f"SeedVR2 window must contain non-negative integers, got {self.window}.")
+
+ self.window_op = get_window_op(window_method)
+
+ def forward(
+ self,
+ vid: torch.FloatTensor, # l c
+ txt: torch.FloatTensor, # l c
+ vid_shape: torch.LongTensor, # b 3
+ txt_shape: torch.LongTensor, # b 1
+ cache: Cache,
+ ) -> Tuple[
+ torch.FloatTensor,
+ torch.FloatTensor,
+ ]:
+
+ vid_qkv, txt_qkv = self.proj_qkv(vid, txt)
+
+ cache_win = cache.namespace(f"{self.window_method}_{self.window}_sd3")
+
+ def make_window(x: torch.Tensor):
+ t, h, w, _ = x.shape
+ window_slices = self.window_op((t, h, w), self.window)
+ return [x[st, sh, sw] for (st, sh, sw) in window_slices]
+
+ window_partition, window_reverse, window_shape, window_count, vid_len_win_list, window_count_list = cache_win(
+ "win_transform",
+ lambda: window_idx(vid_shape, make_window),
+ )
+ vid_qkv_win = window_partition(vid_qkv)
+
+ vid_qkv_win = vid_qkv_win.reshape(vid_qkv_win.shape[0], 3, self.heads, self.head_dim)
+ txt_qkv = txt_qkv.reshape(txt_qkv.shape[0], 3, self.heads, self.head_dim)
+
+ vid_q, vid_k, vid_v = vid_qkv_win.unbind(1)
+ txt_q, txt_k, txt_v = txt_qkv.unbind(1)
+
+ vid_q, txt_q = self.norm_q(vid_q, txt_q)
+ vid_k, txt_k = self.norm_k(vid_k, txt_k)
+
+ txt_len = cache("txt_len", lambda: txt_shape.prod(-1))
+
+ vid_len_win = cache_win("vid_len", lambda: window_shape.prod(-1))
+ txt_len = txt_len.to(window_count.device)
+
+ if self.rope:
+ if self.version_7b:
+ vid_q, vid_k = self.rope(vid_q, vid_k, window_shape, cache_win)
+ elif self.rope.mm:
+ _, num_h, _ = txt_q.shape
+ txt_q_repeat = txt_q.flatten(1, 2)
+ txt_q_repeat = unflatten(txt_q_repeat, txt_shape)
+ txt_q_repeat = [[x] * n for x, n in zip(txt_q_repeat, window_count_list)]
+ txt_q_repeat = list(chain(*txt_q_repeat))
+ txt_q_repeat, txt_shape_repeat = flatten(txt_q_repeat)
+ txt_q_repeat = txt_q_repeat.reshape(txt_q_repeat.shape[0], num_h, self.head_dim)
+
+ txt_k_repeat = txt_k.flatten(1, 2)
+ txt_k_repeat = unflatten(txt_k_repeat, txt_shape)
+ txt_k_repeat = [[x] * n for x, n in zip(txt_k_repeat, window_count_list)]
+ txt_k_repeat = list(chain(*txt_k_repeat))
+ txt_k_repeat, _ = flatten(txt_k_repeat)
+ txt_k_repeat = txt_k_repeat.reshape(txt_k_repeat.shape[0], num_h, self.head_dim)
+
+ vid_q, vid_k, txt_q, txt_k = self.rope(
+ vid_q, vid_k, window_shape, txt_q_repeat, txt_k_repeat, txt_shape_repeat, cache_win
+ )
+ else:
+ vid_q, vid_k = self.rope(vid_q, vid_k, window_shape, cache_win)
+
+ txt_len_win_list = cache_win(
+ "txt_len_list",
+ lambda: [txt_len for txt_len, window_count in zip(txt_len.tolist(), window_count_list) for _ in range(window_count)],
+ )
+ all_len_win = cache_win("all_len", lambda: [vid_len + txt_len for vid_len, txt_len in zip(vid_len_win_list, txt_len_win_list)])
+ concat_win, unconcat_win = cache_win(
+ "mm_pnp", lambda: repeat_concat_idx(vid_len_win, txt_len, window_count)
+ )
+ out = optimized_var_attention(
+ q=concat_win(vid_q, txt_q),
+ k=concat_win(vid_k, txt_k),
+ v=concat_win(vid_v, txt_v),
+ heads=self.heads, skip_reshape=True, skip_output_reshape=True,
+ cu_seqlens_q=cache_win("vid_seqlens_q", lambda: cumulative_lengths(all_len_win)),
+ cu_seqlens_k=cache_win("vid_seqlens_k", lambda: cumulative_lengths(all_len_win)),
+ )
+ vid_out, txt_out = unconcat_win(out)
+
+ vid_out = vid_out.flatten(1, 2)
+ txt_out = txt_out.flatten(1, 2)
+ vid_out = window_reverse(vid_out)
+
+ vid_out, txt_out = self.proj_out(vid_out, txt_out)
+
+ return vid_out, txt_out
+
+class MLP(nn.Module):
+ def __init__(
+ self,
+ dim: int,
+ expand_ratio: int,
+ device, dtype, operations
+ ):
+ super().__init__()
+ self.proj_in = operations.Linear(dim, dim * expand_ratio, device=device, dtype=dtype)
+ self.act = nn.GELU("tanh")
+ self.proj_out = operations.Linear(dim * expand_ratio, dim, device=device, dtype=dtype)
+
+ def forward(self, x: torch.FloatTensor) -> torch.FloatTensor:
+ x = self.proj_in(x)
+ x = self.act(x)
+ x = self.proj_out(x)
+ return x
+
+
+class SwiGLUMLP(nn.Module):
+ def __init__(
+ self,
+ dim: int,
+ expand_ratio: int,
+ multiple_of: int = 256,
+ device=None, dtype=None, operations=None
+ ):
+ super().__init__()
+ hidden_dim = int(2 * dim * expand_ratio / 3)
+ hidden_dim = multiple_of * ((hidden_dim + multiple_of - 1) // multiple_of)
+ self.proj_in_gate = operations.Linear(dim, hidden_dim, bias=False, device=device, dtype=dtype)
+ self.proj_out = operations.Linear(hidden_dim, dim, bias=False, device=device, dtype=dtype)
+ self.proj_in = operations.Linear(dim, hidden_dim, bias=False, device=device, dtype=dtype)
+
+ def forward(self, x: torch.FloatTensor) -> torch.FloatTensor:
+ return self.proj_out(F.silu(self.proj_in_gate(x)) * self.proj_in(x))
+
+def get_mlp(mlp_type: Optional[str] = "normal"):
+ if mlp_type == "normal":
+ return MLP
+ if mlp_type == "swiglu":
+ return SwiGLUMLP
+ raise ValueError(f"Unknown SeedVR2 MLP type: {mlp_type}")
+
+class NaMMSRTransformerBlock(nn.Module):
+ def __init__(
+ self,
+ *,
+ vid_dim: int,
+ txt_dim: int,
+ emb_dim: int,
+ heads: int,
+ head_dim: int,
+ expand_ratio: int,
+ norm,
+ norm_eps: float,
+ ada,
+ qk_bias: bool,
+ qk_norm,
+ mlp_type: str,
+ shared_weights: bool,
+ rope_type: str,
+ rope_dim: int,
+ is_last_layer: bool,
+ window: Union[int, Tuple[int, int, int]],
+ window_method: str,
+ version: bool,
+ device, dtype, operations,
+ ):
+ super().__init__()
+ dim = MMArg(vid_dim, txt_dim)
+ self.attn_norm = MMModule(norm, normalized_shape=dim, eps=norm_eps, elementwise_affine=False, shared_weights=shared_weights, device=device, dtype=dtype)
+
+ self.attn = NaSwinAttention(
+ vid_dim=vid_dim,
+ txt_dim=txt_dim,
+ heads=heads,
+ head_dim=head_dim,
+ qk_bias=qk_bias,
+ qk_norm=qk_norm,
+ qk_norm_eps=norm_eps,
+ rope_type=rope_type,
+ rope_dim=rope_dim,
+ shared_weights=shared_weights,
+ window=window,
+ window_method=window_method,
+ version=version,
+ device=device, dtype=dtype, operations=operations
+ )
+
+ self.mlp_norm = MMModule(norm, normalized_shape=dim, eps=norm_eps, elementwise_affine=False, shared_weights=shared_weights, vid_only=is_last_layer, device=device, dtype=dtype)
+ self.mlp = MMModule(
+ get_mlp(mlp_type),
+ dim=dim,
+ expand_ratio=expand_ratio,
+ shared_weights=shared_weights,
+ vid_only=is_last_layer,
+ device=device, dtype=dtype, operations=operations
+ )
+ self.ada = MMModule(ada, dim=dim, emb_dim=emb_dim, layers=["attn", "mlp"], shared_weights=shared_weights, vid_only=is_last_layer, device=device, dtype=dtype)
+ self.is_last_layer = is_last_layer
+ self.version = version
+
+ def _seedvr2_7b_mlp(
+ self,
+ vid: torch.FloatTensor,
+ txt: torch.FloatTensor,
+ ) -> Tuple[
+ torch.FloatTensor,
+ torch.FloatTensor,
+ ]:
+ vid_module = self.mlp.vid if not self.mlp.shared_weights else self.mlp.all
+ if comfy.model_management.in_training or vid.requires_grad:
+ vid = torch.cat([vid_module(chunk) for chunk in vid.split(SEEDVR2_7B_MLP_CHUNK, dim=0)], dim=0)
+ else:
+ vid_out = None
+ offset = 0
+ for chunk in vid.split(SEEDVR2_7B_MLP_CHUNK, dim=0):
+ chunk_out = vid_module(chunk)
+ if vid_out is None:
+ vid_out = chunk_out.new_empty((vid.shape[0], *chunk_out.shape[1:]))
+ vid_out[offset:offset + chunk_out.shape[0]] = chunk_out
+ offset += chunk_out.shape[0]
+ vid = vid_out
+ if not self.mlp.vid_only:
+ txt_module = self.mlp.txt if not self.mlp.shared_weights else self.mlp.all
+ txt = txt.to(device=vid.device, dtype=vid.dtype)
+ txt = txt_module(txt)
+ return vid, txt
+
+ def forward(
+ self,
+ vid: torch.FloatTensor, # l c
+ txt: torch.FloatTensor, # l c
+ vid_shape: torch.LongTensor, # b 3
+ txt_shape: torch.LongTensor, # b 1
+ emb: torch.FloatTensor,
+ cache: Cache,
+ ) -> Tuple[
+ torch.FloatTensor,
+ torch.FloatTensor,
+ torch.LongTensor,
+ torch.LongTensor,
+ ]:
+ hid_len = MMArg(
+ cache("vid_len", lambda: vid_shape.prod(-1)),
+ cache("txt_len", lambda: txt_shape.prod(-1)),
+ )
+ ada_kwargs = {
+ "emb": emb,
+ "hid_len": hid_len,
+ "cache": cache,
+ "branch_tag": MMArg("vid", "txt"),
+ }
+
+ vid_attn, txt_attn = self.attn_norm(vid, txt)
+ vid_attn, txt_attn = self.ada(vid_attn, txt_attn, layer="attn", mode="in", **ada_kwargs)
+ vid_attn, txt_attn = self.attn(vid_attn, txt_attn, vid_shape, txt_shape, cache)
+ vid_attn, txt_attn = self.ada(vid_attn, txt_attn, layer="attn", mode="out", **ada_kwargs)
+ vid_attn, txt_attn = (vid_attn + vid), (txt_attn + txt)
+
+ vid_mlp, txt_mlp = self.mlp_norm(vid_attn, txt_attn)
+ vid_mlp, txt_mlp = self.ada(vid_mlp, txt_mlp, layer="mlp", mode="in", **ada_kwargs)
+ if self.version:
+ vid_mlp, txt_mlp = self._seedvr2_7b_mlp(vid_mlp, txt_mlp)
+ else:
+ vid_mlp, txt_mlp = self.mlp(vid_mlp, txt_mlp)
+ vid_mlp, txt_mlp = self.ada(vid_mlp, txt_mlp, layer="mlp", mode="out", **ada_kwargs)
+ vid_mlp, txt_mlp = (vid_mlp + vid_attn), (txt_mlp + txt_attn)
+
+ return vid_mlp, txt_mlp, vid_shape, txt_shape
+
+class PatchOut(nn.Module):
+ def __init__(
+ self,
+ out_channels: int,
+ patch_size: Union[int, Tuple[int, int, int]],
+ dim: int,
+ device, dtype, operations
+ ):
+ super().__init__()
+ t, h, w = _triple(patch_size)
+ self.patch_size = t, h, w
+ self.proj = operations.Linear(dim, out_channels * t * h * w, device=device, dtype=dtype)
+
+ def forward(
+ self,
+ vid: torch.Tensor,
+ ) -> torch.Tensor:
+ t, h, w = self.patch_size
+ vid = self.proj(vid)
+ b, T, H, W, channels = vid.shape
+ c = channels // (t * h * w)
+ vid = vid.view(b, T, H, W, t, h, w, c).permute(0, 7, 1, 4, 2, 5, 3, 6).reshape(b, c, T * t, H * h, W * w)
+ if t > 1:
+ vid = vid[:, :, (t - 1) :]
+ return vid
+
+class NaPatchOut(PatchOut):
+ def forward(
+ self,
+ vid: torch.FloatTensor, # l c
+ vid_shape: torch.LongTensor,
+ cache: Optional[Cache] = None,
+ vid_shape_before_patchify = None
+ ) -> Tuple[
+ torch.FloatTensor,
+ torch.LongTensor,
+ ]:
+ if cache is None:
+ cache = Cache(disable=True)
+
+ t, h, w = self.patch_size
+ vid = self.proj(vid)
+
+ if not (t == h == w == 1):
+ vid = unflatten(vid, vid_shape)
+ for i in range(len(vid)):
+ T, H, W, channels = vid[i].shape
+ c = channels // (t * h * w)
+ vid[i] = vid[i].view(T, H, W, t, h, w, c).permute(0, 3, 1, 4, 2, 5, 6).reshape(T * t, H * h, W * w, c)
+ if t > 1 and vid_shape_before_patchify[i, 0] % t != 0:
+ vid[i] = vid[i][(t - vid_shape_before_patchify[i, 0] % t) :]
+ vid, vid_shape = flatten(vid)
+
+ return vid, vid_shape
+
+class PatchIn(nn.Module):
+ def __init__(
+ self,
+ in_channels: int,
+ patch_size: Union[int, Tuple[int, int, int]],
+ dim: int,
+ device, dtype, operations
+ ):
+ super().__init__()
+ t, h, w = _triple(patch_size)
+ self.patch_size = t, h, w
+ self.proj = operations.Linear(in_channels * t * h * w, dim, device=device, dtype=dtype)
+
+ def forward(
+ self,
+ vid: torch.Tensor,
+ ) -> torch.Tensor:
+ t, h, w = self.patch_size
+ if t > 1:
+ if vid.size(2) % t != 1:
+ raise ValueError(
+ f"SeedVR2 patch input temporal size must satisfy T % {t} == 1, got {vid.size(2)}."
+ )
+ vid = torch.cat([vid[:, :, :1]] * (t - 1) + [vid], dim=2)
+ b, c, Tt, Hh, Ww = vid.shape
+ vid = vid.view(b, c, Tt // t, t, Hh // h, h, Ww // w, w).permute(0, 2, 4, 6, 3, 5, 7, 1).reshape(b, Tt // t, Hh // h, Ww // w, t * h * w * c)
+ vid = self.proj(vid)
+ return vid
+
+class NaPatchIn(PatchIn):
+ def forward(
+ self,
+ vid: torch.Tensor, # l c
+ vid_shape: torch.LongTensor,
+ cache: Optional[Cache] = None,
+ ) -> torch.Tensor:
+ if cache is None:
+ cache = Cache(disable=True)
+ cache = cache.namespace("patch")
+ vid_shape_before_patchify = cache("vid_shape_before_patchify", lambda: vid_shape)
+ t, h, w = self.patch_size
+ if not (t == h == w == 1):
+ vid = unflatten(vid, vid_shape)
+ for i in range(len(vid)):
+ if t > 1 and vid_shape_before_patchify[i, 0] % t != 0:
+ vid[i] = torch.cat([vid[i][:1]] * (t - vid[i].size(0) % t) + [vid[i]], dim=0)
+ Tt, Hh, Ww, c = vid[i].shape
+ vid[i] = vid[i].view(Tt // t, t, Hh // h, h, Ww // w, w, c).permute(0, 2, 4, 1, 3, 5, 6).reshape(Tt // t, Hh // h, Ww // w, t * h * w * c)
+ vid, vid_shape = flatten(vid)
+
+ vid = self.proj(vid)
+ return vid, vid_shape
+
+def expand_dims(x: torch.Tensor, dim: int, ndim: int):
+ shape = x.shape
+ shape = shape[:dim] + (1,) * (ndim - len(shape)) + shape[dim:]
+ return x.reshape(shape)
+
+
+class AdaSingle(nn.Module):
+ def __init__(
+ self,
+ dim: int,
+ emb_dim: int,
+ layers: List[str],
+ modes: Tuple[str, ...] = ("in", "out"),
+ device = None, dtype = None,
+ ):
+ if emb_dim != 6 * dim:
+ raise ValueError(f"SeedVR2 AdaSingle requires emb_dim == 6 * dim, got emb_dim={emb_dim}, dim={dim}.")
+ super().__init__()
+ self.dim = dim
+ self.emb_dim = emb_dim
+ self.layers = layers
+
+ param_kwargs = {"device": device, "dtype": dtype}
+
+ for l in layers:
+ if "in" in modes:
+ self.register_parameter(f"{l}_shift", nn.Parameter(torch.empty(dim, **param_kwargs)))
+ self.register_parameter(f"{l}_scale", nn.Parameter(torch.empty(dim, **param_kwargs)))
+ if "out" in modes:
+ self.register_parameter(f"{l}_gate", nn.Parameter(torch.empty(dim, **param_kwargs)))
+
+ def forward(
+ self,
+ hid: torch.FloatTensor, # b ... c
+ emb: torch.FloatTensor, # b d
+ layer: str,
+ mode: str,
+ cache: Optional[Cache] = None,
+ branch_tag: str = "",
+ hid_len: Optional[torch.LongTensor] = None, # b
+ ) -> torch.FloatTensor:
+ if cache is None:
+ cache = Cache(disable=True)
+ idx = self.layers.index(layer)
+ emb = emb.reshape(emb.shape[0], -1, len(self.layers), 3)[:, :, idx, :]
+ emb = expand_dims(emb, 1, hid.ndim + 1)
+
+ if hid_len is not None:
+ emb = cache(
+ f"emb_repeat_{idx}_{branch_tag}",
+ lambda: torch.repeat_interleave(emb, hid_len, dim=0),
+ )
+
+ shiftA, scaleA, gateA = emb.unbind(-1)
+ shiftB, scaleB, gateB = (
+ getattr(self, f"{layer}_shift", None),
+ getattr(self, f"{layer}_scale", None),
+ getattr(self, f"{layer}_gate", None),
+ )
+
+ if mode == "in":
+ shiftB = comfy.ops.cast_to_input(shiftB, hid)
+ scaleB = comfy.ops.cast_to_input(scaleB, hid)
+ return hid.mul_(scaleA + scaleB).add_(shiftA + shiftB)
+ if mode == "out":
+ if gateB is not None:
+ gateB = comfy.ops.cast_to_input(gateB, hid)
+ return hid.mul_(gateA + gateB)
+ else:
+ return hid.mul_(gateA)
+
+ raise ValueError(f"Unknown AdaSingle mode: {mode}")
+
+
+class TimeEmbedding(nn.Module):
+ def __init__(
+ self,
+ sinusoidal_dim: int,
+ hidden_dim: int,
+ output_dim: int,
+ device, dtype, operations
+ ):
+ super().__init__()
+ self.sinusoidal_dim = sinusoidal_dim
+ self.proj_in = operations.Linear(sinusoidal_dim, hidden_dim, device=device, dtype=dtype)
+ self.proj_hid = operations.Linear(hidden_dim, hidden_dim, device=device, dtype=dtype)
+ self.proj_out = operations.Linear(hidden_dim, output_dim, device=device, dtype=dtype)
+ self.act = nn.SiLU()
+
+ def forward(
+ self,
+ timestep: Union[int, float, torch.IntTensor, torch.FloatTensor],
+ device: torch.device,
+ dtype: torch.dtype,
+ ) -> torch.FloatTensor:
+ if not torch.is_tensor(timestep):
+ timestep = torch.tensor([timestep], device=device, dtype=dtype)
+ if timestep.ndim == 0:
+ timestep = timestep[None]
+
+ emb = get_timestep_embedding(
+ timesteps=timestep,
+ embedding_dim=self.sinusoidal_dim,
+ flip_sin_to_cos=False,
+ downscale_freq_shift=0,
+ ).to(dtype)
+ emb = self.proj_in(emb)
+ emb = self.act(emb)
+ emb = self.proj_hid(emb)
+ emb = self.act(emb)
+ emb = self.proj_out(emb)
+ return emb
+
+def flatten(
+ hid: List[torch.FloatTensor], # List of (*** c)
+) -> Tuple[
+ torch.FloatTensor, # (L c)
+ torch.LongTensor, # (b n)
+]:
+ if len(hid) == 0:
+ raise ValueError("SeedVR2 flatten requires at least one tensor.")
+ shape = torch.as_tensor([x.shape[:-1] for x in hid], device=hid[0].device)
+ hid = torch.cat([x.flatten(0, -2) for x in hid])
+ return hid, shape
+
+
+def unflatten(
+ hid: torch.FloatTensor, # (L c) or (L ... c)
+ hid_shape: torch.LongTensor, # (b n)
+) -> List[torch.Tensor]: # List of (*** c) or (*** ... c)
+ hid_len = hid_shape.prod(-1)
+ hid = hid.split(hid_len.tolist())
+ hid = [x.unflatten(0, s.tolist()) for x, s in zip(hid, hid_shape)]
+ return hid
+
+class NaDiT(nn.Module):
+
+ def __init__(
+ self,
+ norm_eps,
+ num_layers,
+ mlp_type,
+ vid_in_channels = 33,
+ vid_out_channels = SEEDVR2_LATENT_CHANNELS,
+ vid_dim = 2560,
+ txt_in_dim = 5120,
+ heads = 20,
+ head_dim = 128,
+ mm_layers = 10,
+ expand_ratio = 4,
+ qk_bias = False,
+ patch_size = (1, 2, 2),
+ rope_dim = 128,
+ rope_type = "mmrope3d",
+ vid_out_norm: Optional[str] = None,
+ image_model = None,
+ device = None,
+ dtype = None,
+ operations = None,
+ ):
+ if image_model not in (None, "seedvr2"):
+ raise ValueError(f"SeedVR2 NaDiT expected image_model='seedvr2', got {image_model!r}.")
+ self._7b_version = vid_dim == SEEDVR2_7B_VID_DIM
+ if self._7b_version:
+ rope_type = "rope3d"
+ self.dtype = dtype
+ factory_kwargs = {"device": device, "dtype": dtype}
+ window_method = num_layers // 2 * ["720pwin_by_size_bysize","720pswin_by_size_bysize"]
+ txt_dim = vid_dim
+ emb_dim = vid_dim * 6
+ window = num_layers * [(4,3,3)]
+ ada = AdaSingle
+ norm = operations.RMSNorm
+ qk_norm = operations.RMSNorm
+ super().__init__()
+ self.register_buffer("positive_conditioning", torch.empty((58, 5120), device=device, dtype=dtype))
+ self.register_buffer("negative_conditioning", torch.empty((64, 5120), device=device, dtype=dtype))
+ self.vid_in = NaPatchIn(
+ in_channels=vid_in_channels,
+ patch_size=patch_size,
+ dim=vid_dim,
+ device=device, dtype=dtype, operations=operations
+ )
+ self.txt_in = (
+ operations.Linear(txt_in_dim, txt_dim, **factory_kwargs)
+ if txt_in_dim and txt_in_dim != txt_dim
+ else nn.Identity()
+ )
+ self.emb_in = TimeEmbedding(
+ sinusoidal_dim=BYTEDANCE_SINUSOIDAL_DIM,
+ hidden_dim=max(vid_dim, txt_dim),
+ output_dim=emb_dim,
+ device=device, dtype=dtype, operations=operations
+ )
+
+ if window is None or isinstance(window[0], int):
+ window = [window] * num_layers
+
+ rope_dim = rope_dim if rope_dim is not None else head_dim // 2
+ self.blocks = nn.ModuleList(
+ [
+ NaMMSRTransformerBlock(
+ vid_dim=vid_dim,
+ txt_dim=txt_dim,
+ emb_dim=emb_dim,
+ heads=heads,
+ head_dim=head_dim,
+ expand_ratio=expand_ratio,
+ norm=norm,
+ norm_eps=norm_eps,
+ ada=ada,
+ qk_bias=qk_bias,
+ qk_norm=qk_norm,
+ mlp_type=mlp_type,
+ rope_dim = rope_dim,
+ window=window[i],
+ window_method=window_method[i],
+ version = self._7b_version,
+ is_last_layer=(i == num_layers - 1) and not self._7b_version,
+ rope_type = rope_type,
+ shared_weights=not (
+ (i < mm_layers) if isinstance(mm_layers, int) else mm_layers[i]
+ ),
+ operations = operations,
+ **factory_kwargs
+ )
+ for i in range(num_layers)
+ ]
+ )
+ self.vid_out = NaPatchOut(
+ out_channels=vid_out_channels,
+ patch_size=patch_size,
+ dim=vid_dim,
+ device=device, dtype=dtype, operations=operations
+ )
+
+ self.vid_out_norm = None
+ if vid_out_norm is not None:
+ self.vid_out_norm = operations.RMSNorm(
+ normalized_shape=vid_dim,
+ eps=norm_eps,
+ elementwise_affine=True,
+ device=device, dtype=dtype
+ )
+ self.vid_out_ada = ada(
+ dim=vid_dim,
+ emb_dim=emb_dim,
+ layers=["out"],
+ modes=["in"],
+ device=device, dtype=dtype
+ )
+
+ def _resolve_text_conditioning(self, context, cond_or_uncond=None):
+ if context is None or context.numel() == 0:
+ context = self.positive_conditioning
+ return flatten([context])
+ if NaDiT._seedvr2_is_single_conditioning_branch(cond_or_uncond):
+ if context.shape[0] == 1:
+ context = context.squeeze(0)
+ return flatten([context])
+ return flatten(context.unbind(0))
+ if context.shape[0] % 2 != 0:
+ raise ValueError(f"SeedVR2 expected an even text-conditioning batch, got shape {tuple(context.shape)}")
+ neg_cond, pos_cond = context.chunk(2, dim=0)
+ if pos_cond.shape[0] == 1:
+ pos_cond, neg_cond = pos_cond.squeeze(0), neg_cond.squeeze(0)
+ return flatten([pos_cond, neg_cond])
+ return flatten((*pos_cond.unbind(0), *neg_cond.unbind(0)))
+
+ @staticmethod
+ def _seedvr2_is_single_conditioning_branch(cond_or_uncond):
+ if cond_or_uncond is None or len(cond_or_uncond) == 0:
+ return False
+ first = cond_or_uncond[0]
+ return all(entry == first for entry in cond_or_uncond)
+
+ @staticmethod
+ def _check_seedvr2_video_latent(x, channels, name):
+ if x.ndim != 5:
+ raise ValueError(f"SeedVR2 expected {name} to be 5-D native latent, got shape {tuple(x.shape)}.")
+ if x.shape[1] != channels:
+ raise ValueError(f"SeedVR2 expected {name} channels to be {channels}, got shape {tuple(x.shape)}.")
+ return x
+
+ def _swap_pos_neg_halves(self, out, cond_or_uncond=None):
+ if NaDiT._seedvr2_is_single_conditioning_branch(cond_or_uncond):
+ return out
+ pos, neg = out.chunk(2, dim=0)
+ return torch.cat([neg, pos], dim=0)
+
+ def forward(
+ self,
+ x,
+ timestep,
+ context, # l c
+ disable_cache: bool = False,
+ **kwargs
+ ):
+ transformer_options = kwargs.get("transformer_options", {})
+ patches_replace = transformer_options.get("patches_replace", {})
+ blocks_replace = patches_replace.get("dit", {})
+ conditions = kwargs.get("condition")
+ if conditions is None:
+ raise ValueError("SeedVR2 requires conditioning latents from the SeedVR2Conditioning node.")
+ x = self._check_seedvr2_video_latent(x, SEEDVR2_LATENT_CHANNELS, "latent")
+ conditions = self._check_seedvr2_video_latent(conditions, SEEDVR2_LATENT_CHANNELS + 1, "conditioning")
+ b, _, t, h, w = x.shape
+ if conditions.shape[0] != b or conditions.shape[2:] != (t, h, w):
+ raise ValueError(
+ f"SeedVR2 conditioning shape must match latent batch/temporal/spatial dimensions; got latent {tuple(x.shape)} and conditioning {tuple(conditions.shape)}."
+ )
+ x = x.movedim(1, -1)
+ conditions = conditions.movedim(1, -1)
+ cache = Cache(disable=disable_cache)
+
+ txt, txt_shape = self._resolve_text_conditioning(context, transformer_options.get("cond_or_uncond"))
+
+ vid, vid_shape = flatten(x)
+ cond_latent, _ = flatten(conditions)
+
+ vid = torch.cat([vid, cond_latent], dim=-1)
+
+ txt = self.txt_in(txt)
+
+ vid_shape_before_patchify = vid_shape
+ vid, vid_shape = self.vid_in(vid, vid_shape, cache=cache)
+
+ emb = self.emb_in(timestep, device=vid.device, dtype=vid.dtype)
+
+ for i, block in enumerate(self.blocks):
+ if ("block", i) in blocks_replace:
+ def block_wrap(args):
+ out = {}
+ out["vid"], out["txt"], out["vid_shape"], out["txt_shape"] = block(
+ vid=args["vid"],
+ txt=args["txt"],
+ vid_shape=args["vid_shape"],
+ txt_shape=args["txt_shape"],
+ emb=args["emb"],
+ cache=args["cache"],
+ )
+ return out
+ out = blocks_replace[("block", i)]({
+ "vid":vid,
+ "txt":txt,
+ "vid_shape":vid_shape,
+ "txt_shape":txt_shape,
+ "emb":emb,
+ "cache":cache,
+ }, {"original_block": block_wrap})
+ vid, txt, vid_shape, txt_shape = out["vid"], out["txt"], out["vid_shape"], out["txt_shape"]
+ else:
+ vid, txt, vid_shape, txt_shape = block(
+ vid=vid,
+ txt=txt,
+ vid_shape=vid_shape,
+ txt_shape=txt_shape,
+ emb=emb,
+ cache=cache,
+ )
+
+ if self.vid_out_norm:
+ vid = self.vid_out_norm(vid)
+ vid = self.vid_out_ada(
+ vid,
+ emb=emb,
+ layer="out",
+ mode="in",
+ hid_len=cache("vid_len", lambda: vid_shape.prod(-1)),
+ cache=cache,
+ branch_tag="vid",
+ )
+
+ vid, vid_shape = self.vid_out(vid, vid_shape, cache, vid_shape_before_patchify = vid_shape_before_patchify)
+ vid = unflatten(vid, vid_shape)
+ out = torch.stack(vid)
+ out = out.movedim(-1, 1)
+ return self._swap_pos_neg_halves(out, transformer_options.get("cond_or_uncond"))
diff --git a/ComfyUI/comfy/ldm/seedvr/vae.py b/ComfyUI/comfy/ldm/seedvr/vae.py
new file mode 100644
index 0000000000000000000000000000000000000000..7a8070b6509e96d61cb87cb04149e57df40133eb
--- /dev/null
+++ b/ComfyUI/comfy/ldm/seedvr/vae.py
@@ -0,0 +1,1610 @@
+from typing import Literal, Optional, Tuple
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+from torch import Tensor
+from contextlib import contextmanager
+from comfy.utils import ProgressBar
+
+from comfy.ldm.seedvr.constants import (
+ BYTEDANCE_BLOCK_OUT_CHANNELS,
+ BYTEDANCE_GN_CHUNKS_FP16,
+ BYTEDANCE_GN_CHUNKS_FP32,
+ BYTEDANCE_LOGVAR_CLAMP_MAX,
+ BYTEDANCE_LOGVAR_CLAMP_MIN,
+ BYTEDANCE_SLICING_SAMPLE_MIN,
+ BYTEDANCE_VAE_CONV_MEM_GIB,
+ BYTEDANCE_VAE_NORM_MEM_GIB,
+ BYTEDANCE_VAE_SCALING_FACTOR,
+ BYTEDANCE_VAE_SHIFTING_FACTOR,
+ BYTEDANCE_VAE_SPATIAL_DOWNSAMPLE,
+ BYTEDANCE_VAE_TEMPORAL_DOWNSAMPLE,
+ SEEDVR2_LATENT_CHANNELS,
+)
+from comfy.ldm.modules.attention import optimized_attention
+from comfy.ldm.modules.diffusionmodules.model import vae_attention
+
+import math
+from enum import Enum
+
+import logging
+import comfy.model_management
+import comfy.ops
+ops = comfy.ops.manual_cast
+
+
+def _seedvr2_temporal_slicing_min_size(temporal_size, temporal_overlap, temporal_scale=1):
+ if temporal_size is None:
+ return None
+
+ temporal_size = int(temporal_size)
+ if temporal_size <= 0:
+ return None
+
+ temporal_overlap = max(0, int(temporal_overlap or 0))
+ temporal_overlap = min(temporal_overlap, temporal_size - 1)
+ temporal_step = temporal_size - temporal_overlap
+ temporal_scale = max(1, int(temporal_scale))
+ return max(1, math.ceil(temporal_step / temporal_scale))
+
+
+def _seedvr2_clamped_spatial_overlap(overlap, tile_size):
+ overlap = max(0, int(overlap))
+ tile_size = max(1, int(tile_size))
+ return min(overlap, tile_size - 1)
+
+
+def tiled_vae(
+ x,
+ vae_model,
+ tile_size=(512, 512),
+ tile_overlap=(64, 64),
+ temporal_size=16,
+ temporal_overlap=0,
+ encode=True,
+):
+ if x.ndim != 5:
+ x = x.unsqueeze(2)
+
+ _, _, d, h, w = x.shape
+
+ sf_s = getattr(vae_model, "spatial_downsample_factor", BYTEDANCE_VAE_SPATIAL_DOWNSAMPLE)
+ sf_t = getattr(vae_model, "temporal_downsample_factor", BYTEDANCE_VAE_TEMPORAL_DOWNSAMPLE)
+ if encode:
+ slicing_attr = "slicing_sample_min_size"
+ slicing_min_size = _seedvr2_temporal_slicing_min_size(temporal_size, temporal_overlap)
+ else:
+ slicing_attr = "slicing_latent_min_size"
+ slicing_min_size = _seedvr2_temporal_slicing_min_size(temporal_size, temporal_overlap, sf_t)
+ if encode:
+ ti_h, ti_w = tile_size
+ ov_h = _seedvr2_clamped_spatial_overlap(tile_overlap[0], ti_h)
+ ov_w = _seedvr2_clamped_spatial_overlap(tile_overlap[1], ti_w)
+ blend_ov_h = max(0, ov_h // sf_s)
+ blend_ov_w = max(0, ov_w // sf_s)
+ target_d = (d + sf_t - 1) // sf_t
+ target_h = (h + sf_s - 1) // sf_s
+ target_w = (w + sf_s - 1) // sf_s
+ else:
+ ti_h = max(1, tile_size[0] // sf_s)
+ ti_w = max(1, tile_size[1] // sf_s)
+ ov_h = _seedvr2_clamped_spatial_overlap(tile_overlap[0] // sf_s, ti_h)
+ ov_w = _seedvr2_clamped_spatial_overlap(tile_overlap[1] // sf_s, ti_w)
+ blend_ov_h = ov_h * sf_s
+ blend_ov_w = ov_w * sf_s
+
+ target_d = max(1, d * sf_t - (sf_t - 1))
+ target_h = h * sf_s
+ target_w = w * sf_s
+
+ stride_h = max(1, ti_h - ov_h)
+ stride_w = max(1, ti_w - ov_w)
+
+ storage_device = vae_model.device
+ result = None
+ count = None
+ def run_temporal_chunks(spatial_tile, model=vae_model):
+ t_chunk = spatial_tile.contiguous()
+ old_device = getattr(model, "device", None)
+ model.device = t_chunk.device
+ old_slicing_min_size = getattr(model, slicing_attr, None)
+ if old_slicing_min_size is not None and slicing_min_size is not None:
+ if slicing_min_size <= 0:
+ setattr(model, slicing_attr, t_chunk.shape[2])
+ else:
+ setattr(model, slicing_attr, slicing_min_size)
+ try:
+ if encode:
+ out = model.encode(t_chunk)
+ else:
+ out = model.decode_(t_chunk)
+ finally:
+ if old_slicing_min_size is not None and slicing_min_size is not None:
+ setattr(model, slicing_attr, old_slicing_min_size)
+ if old_device is not None:
+ model.device = old_device
+ if out.ndim == 4:
+ out = out.unsqueeze(2)
+ return out.to(storage_device)
+
+ ramp_cache = {}
+ def get_ramp(steps):
+ if steps not in ramp_cache:
+ t = torch.linspace(0, 1, steps=steps, device=storage_device, dtype=torch.float32)
+ ramp_cache[steps] = 0.5 - 0.5 * torch.cos(t * torch.pi)
+ return ramp_cache[steps]
+
+ tile_ranges = []
+ for y_idx in range(0, h, stride_h):
+ y_end = min(y_idx + ti_h, h)
+ if y_idx > 0 and (y_end - y_idx) <= ov_h:
+ continue
+ for x_idx in range(0, w, stride_w):
+ x_end = min(x_idx + ti_w, w)
+ if x_idx > 0 and (x_end - x_idx) <= ov_w:
+ continue
+ tile_ranges.append((y_idx, y_end, x_idx, x_end))
+
+ total_tiles = len(tile_ranges)
+ bar = ProgressBar(total_tiles)
+ single_spatial_tile = h <= ti_h and w <= ti_w
+
+ def run_tile(tile_index, tile_range):
+ y_idx, y_end, x_idx, x_end = tile_range
+ tile_x = x[:, :, :, y_idx:y_end, x_idx:x_end]
+ tile_out = run_temporal_chunks(tile_x)
+ return tile_index, y_idx, y_end, x_idx, x_end, tile_out
+
+ ordered_tile_outputs = (
+ run_tile(tile_index, tile_range)
+ for tile_index, tile_range in enumerate(tile_ranges)
+ )
+
+ for _, y_idx, y_end, x_idx, x_end, tile_out in ordered_tile_outputs:
+
+ if single_spatial_tile:
+ result = tile_out[:, :, :target_d, :target_h, :target_w]
+ if result.device != x.device or result.dtype != x.dtype:
+ result = result.to(device=x.device, dtype=x.dtype)
+ if x.shape[2] == 1 and sf_t == 1:
+ result = result.squeeze(2)
+ bar.update(1)
+ return result
+
+ if result is None:
+ b_out, c_out = tile_out.shape[0], tile_out.shape[1]
+ result = torch.zeros((b_out, c_out, target_d, target_h, target_w), device=storage_device, dtype=torch.float32)
+ count = torch.zeros((1, 1, 1, target_h, target_w), device=storage_device, dtype=torch.float32)
+
+ if encode:
+ ys, ye = y_idx // sf_s, (y_idx // sf_s) + tile_out.shape[3]
+ xs, xe = x_idx // sf_s, (x_idx // sf_s) + tile_out.shape[4]
+ cur_ov_h = max(0, min(blend_ov_h, tile_out.shape[3] // 2))
+ cur_ov_w = max(0, min(blend_ov_w, tile_out.shape[4] // 2))
+ else:
+ ys, ye = y_idx * sf_s, (y_idx * sf_s) + tile_out.shape[3]
+ xs, xe = x_idx * sf_s, (x_idx * sf_s) + tile_out.shape[4]
+ cur_ov_h = max(0, min(blend_ov_h, tile_out.shape[3] // 2))
+ cur_ov_w = max(0, min(blend_ov_w, tile_out.shape[4] // 2))
+
+ w_h = torch.ones((tile_out.shape[3],), device=storage_device)
+ w_w = torch.ones((tile_out.shape[4],), device=storage_device)
+
+ if cur_ov_h > 0:
+ r = get_ramp(cur_ov_h)
+ if y_idx > 0:
+ w_h[:cur_ov_h] = r
+ if y_end < h:
+ w_h[-cur_ov_h:] = 1.0 - r
+
+ if cur_ov_w > 0:
+ r = get_ramp(cur_ov_w)
+ if x_idx > 0:
+ w_w[:cur_ov_w] = r
+ if x_end < w:
+ w_w[-cur_ov_w:] = 1.0 - r
+
+ final_weight = w_h.view(1,1,1,-1,1) * w_w.view(1,1,1,1,-1)
+
+ valid_d = min(tile_out.shape[2], result.shape[2])
+ tile_out = tile_out[:, :, :valid_d, :, :]
+
+ tile_out.mul_(final_weight)
+
+ result[:, :, :valid_d, ys:ye, xs:xe] += tile_out
+ count[:, :, :, ys:ye, xs:xe] += final_weight
+
+ del tile_out, final_weight, w_h, w_w
+ bar.update(1)
+
+ result.div_(count.clamp(min=1e-6))
+
+ if result.device != x.device or result.dtype != x.dtype:
+ result = result.to(device=x.device, dtype=x.dtype)
+
+ if x.shape[2] == 1 and sf_t == 1:
+ result = result.squeeze(2)
+
+ return result
+
+_NORM_LIMIT = float("inf")
+def get_norm_limit():
+ return _NORM_LIMIT
+
+
+def set_norm_limit(value: Optional[float] = None):
+ global _NORM_LIMIT
+ if value is None:
+ value = float("inf")
+ _NORM_LIMIT = value
+
+@contextmanager
+def ignore_padding(model):
+ orig_padding = model.padding
+ model.padding = (0, 0, 0)
+ try:
+ yield
+ finally:
+ model.padding = orig_padding
+
+class MemoryState(Enum):
+ DISABLED = 0
+ INITIALIZING = 1
+ ACTIVE = 2
+ UNSET = 3
+
+def get_cache_size(conv_module, input_len, pad_len, dim=0):
+ dilated_kernel_size = conv_module.dilation[dim] * (conv_module.kernel_size[dim] - 1) + 1
+ output_len = (input_len + pad_len - dilated_kernel_size) // conv_module.stride[dim] + 1
+ remain_len = (
+ input_len + pad_len - ((output_len - 1) * conv_module.stride[dim] + dilated_kernel_size)
+ )
+ overlap_len = dilated_kernel_size - conv_module.stride[dim]
+ cache_len = overlap_len + remain_len
+
+ if output_len <= 0:
+ raise ValueError(
+ f"SeedVR2 VAE cache input is too short for convolution: input_len={input_len}, pad_len={pad_len}."
+ )
+ return cache_len
+
+class DiagonalGaussianDistribution(object):
+ def __init__(self, parameters: torch.Tensor):
+ self.parameters = parameters
+ self.mean, self.logvar = torch.chunk(parameters, 2, dim=1)
+ self.logvar = torch.clamp(self.logvar, BYTEDANCE_LOGVAR_CLAMP_MIN, BYTEDANCE_LOGVAR_CLAMP_MAX)
+
+ def mode(self):
+ return self.mean
+
+class SpatialNorm(nn.Module):
+ def __init__(
+ self,
+ f_channels: int,
+ zq_channels: int,
+ ):
+ super().__init__()
+ self.norm_layer = ops.GroupNorm(num_channels=f_channels, num_groups=32, eps=1e-6, affine=True)
+ self.conv_y = ops.Conv2d(zq_channels, f_channels, kernel_size=1, stride=1, padding=0)
+ self.conv_b = ops.Conv2d(zq_channels, f_channels, kernel_size=1, stride=1, padding=0)
+
+ def forward(self, f: torch.Tensor, zq: torch.Tensor) -> torch.Tensor:
+ f_size = f.shape[-2:]
+ zq = F.interpolate(zq, size=f_size, mode="nearest")
+ norm_f = self.norm_layer(f)
+ new_f = norm_f * self.conv_y(zq) + self.conv_b(zq)
+ return new_f
+
+class Attention(nn.Module):
+ def __init__(
+ self,
+ query_dim: int,
+ heads: int = 8,
+ dim_head: int = 64,
+ bias: bool = False,
+ norm_num_groups: Optional[int] = None,
+ spatial_norm_dim: Optional[int] = None,
+ out_bias: bool = True,
+ eps: float = 1e-5,
+ rescale_output_factor: float = 1.0,
+ residual_connection: bool = False,
+ ):
+ super().__init__()
+
+ self.inner_dim = dim_head * heads
+ self.rescale_output_factor = rescale_output_factor
+ self.residual_connection = residual_connection
+ self.out_dim = query_dim
+ self.heads = heads
+
+ if norm_num_groups is not None:
+ self.group_norm = ops.GroupNorm(num_channels=query_dim, num_groups=norm_num_groups, eps=eps, affine=True)
+ else:
+ self.group_norm = None
+
+ if spatial_norm_dim is not None:
+ self.spatial_norm = SpatialNorm(f_channels=query_dim, zq_channels=spatial_norm_dim)
+ else:
+ self.spatial_norm = None
+
+ self.to_q = ops.Linear(query_dim, self.inner_dim, bias=bias)
+ self.to_k = ops.Linear(query_dim, self.inner_dim, bias=bias)
+ self.to_v = ops.Linear(query_dim, self.inner_dim, bias=bias)
+ self.to_out = nn.ModuleList([])
+ self.to_out.append(ops.Linear(self.inner_dim, self.out_dim, bias=out_bias))
+ self.to_out.append(nn.Identity())
+
+ self.optimized_vae_attention = vae_attention()
+
+ def forward(
+ self,
+ hidden_states: torch.Tensor,
+ temb: Optional[torch.Tensor] = None,
+ ) -> torch.Tensor:
+
+ residual = hidden_states
+ if self.spatial_norm is not None:
+ hidden_states = self.spatial_norm(hidden_states, temb)
+
+ input_ndim = hidden_states.ndim
+
+ if input_ndim == 4:
+ batch_size, channel, height, width = hidden_states.shape
+ hidden_states = hidden_states.view(batch_size, channel, height * width).transpose(1, 2)
+
+ batch_size = hidden_states.shape[0]
+
+ if self.group_norm is not None:
+ hidden_states = self.group_norm(hidden_states.transpose(1, 2)).transpose(1, 2)
+
+ query = self.to_q(hidden_states)
+ key = self.to_k(hidden_states)
+ value = self.to_v(hidden_states)
+
+ inner_dim = key.shape[-1]
+ head_dim = inner_dim // self.heads
+
+ query = query.view(batch_size, -1, self.heads, head_dim).transpose(1, 2)
+
+ key = key.view(batch_size, -1, self.heads, head_dim).transpose(1, 2)
+ value = value.view(batch_size, -1, self.heads, head_dim).transpose(1, 2)
+
+ if input_ndim == 4 and self.heads == 1:
+ query = query.squeeze(1).transpose(1, 2).reshape(batch_size, head_dim, height, width)
+ key = key.squeeze(1).transpose(1, 2).reshape(batch_size, head_dim, height, width)
+ value = value.squeeze(1).transpose(1, 2).reshape(batch_size, head_dim, height, width)
+ hidden_states = self.optimized_vae_attention(query, key, value).reshape(batch_size, self.heads, head_dim, height * width).transpose(2, 3)
+ else:
+ hidden_states = optimized_attention(query, key, value, heads = self.heads, skip_reshape=True, skip_output_reshape=True)
+
+ hidden_states = hidden_states.transpose(1, 2).reshape(batch_size, -1, self.heads * head_dim)
+ hidden_states = hidden_states.to(query.dtype)
+
+ hidden_states = self.to_out[0](hidden_states)
+ hidden_states = self.to_out[1](hidden_states)
+
+ if input_ndim == 4:
+ hidden_states = hidden_states.transpose(-1, -2).reshape(batch_size, channel, height, width)
+
+ if self.residual_connection:
+ hidden_states = hidden_states + residual
+
+ hidden_states = hidden_states / self.rescale_output_factor
+
+ return hidden_states
+
+
+def causal_norm_wrapper(norm_layer: nn.Module, x: torch.Tensor) -> torch.Tensor:
+ input_dtype = x.dtype
+ if isinstance(norm_layer, (nn.LayerNorm, nn.RMSNorm)):
+ if x.ndim == 4:
+ x = x.permute(0, 2, 3, 1)
+ x = norm_layer(x)
+ x = x.permute(0, 3, 1, 2)
+ return x.to(input_dtype)
+ if x.ndim == 5:
+ x = x.permute(0, 2, 3, 4, 1)
+ x = norm_layer(x)
+ x = x.permute(0, 4, 1, 2, 3)
+ return x.to(input_dtype)
+ if isinstance(norm_layer, (nn.GroupNorm, nn.BatchNorm2d, nn.SyncBatchNorm)):
+ if x.ndim <= 4:
+ return norm_layer(x).to(input_dtype)
+ if x.ndim == 5:
+ b, c, t, h, w = x.shape
+ x = x.transpose(1, 2).reshape(b * t, c, h, w)
+ memory_occupy = x.numel() * x.element_size() / 1024**3
+ if isinstance(norm_layer, nn.GroupNorm) and memory_occupy > get_norm_limit():
+ num_chunks = min(BYTEDANCE_GN_CHUNKS_FP16 if x.element_size() == 2 else BYTEDANCE_GN_CHUNKS_FP32, norm_layer.num_groups)
+ if norm_layer.num_groups % num_chunks != 0:
+ raise ValueError(
+ f"SeedVR2 VAE GroupNorm groups must divide chunks: groups={norm_layer.num_groups}, chunks={num_chunks}."
+ )
+ num_groups_per_chunk = norm_layer.num_groups // num_chunks
+
+ weights = comfy.ops.cast_to_input(norm_layer.weight, x).chunk(num_chunks, dim=0)
+ biases = comfy.ops.cast_to_input(norm_layer.bias, x).chunk(num_chunks, dim=0)
+ x = list(x.chunk(num_chunks, dim=1))
+ for i, (w, bias) in enumerate(zip(weights, biases)):
+ x[i] = F.group_norm(x[i], num_groups_per_chunk, w, bias, norm_layer.eps)
+ x[i] = x[i].to(input_dtype)
+ x = torch.cat(x, dim=1)
+ else:
+ x = norm_layer(x)
+ x = x.reshape((b, t, x.size(1), x.size(2), x.size(3))).transpose(1, 2)
+ return x.to(input_dtype)
+ raise TypeError(f"SeedVR2 VAE unsupported norm layer type: {type(norm_layer).__name__}")
+
+_receptive_field_t = Literal["half", "full"]
+
+def extend_head(tensor, times: int = 2, memory = None):
+ if memory is not None:
+ return torch.cat((memory.to(tensor), tensor), dim=2)
+ if times < 0:
+ raise ValueError(f"SeedVR2 VAE extend_head expected times >= 0, got {times}.")
+ if times == 0:
+ return tensor
+ else:
+ tile_repeat = [1] * tensor.ndim
+ tile_repeat[2] = times
+ return torch.cat(tensors=(torch.tile(tensor[:, :, :1], tile_repeat), tensor), dim=2)
+
+def cache_send_recv(tensor, cache_size, times, memory=None):
+ recv_buffer = None
+
+ if memory is not None:
+ recv_buffer = memory.to(tensor[0])
+ elif times > 0:
+ tile_repeat = [1] * tensor[0].ndim
+ tile_repeat[2] = times
+ recv_buffer = torch.tile(tensor[0][:, :, :1], tile_repeat)
+
+ return recv_buffer
+
+class InflatedCausalConv3d(ops.Conv3d):
+ def __init__(
+ self,
+ *args,
+ inflation_mode,
+ **kwargs,
+ ):
+ self.inflation_mode = inflation_mode
+ super().__init__(*args, **kwargs)
+ self.temporal_padding = self.padding[0]
+ self.padding = (0, *self.padding[1:])
+ self.memory_limit = float("inf")
+ self.logged_once = False
+
+ def set_memory_limit(self, value: float):
+ self.memory_limit = value
+
+ def _conv_forward(self, input, weight, bias, *args, **kwargs):
+ try:
+ return super()._conv_forward(input, weight, bias, *args, **kwargs)
+ except NotImplementedError:
+ # for: Could not run 'aten::cudnn_convolution' with arguments from the 'CPU' backend
+ if not self.logged_once:
+ logging.warning("VAE is on CPU for decoding. This is most likely due to not enough memory")
+ self.logged_once = True
+ return F.conv3d(input, weight, bias, *args, **kwargs)
+
+ def memory_limit_conv(
+ self,
+ x,
+ *,
+ split_dim=3,
+ padding=(0, 0, 0, 0, 0, 0),
+ prev_cache=None,
+ ):
+ if math.isinf(self.memory_limit):
+ if prev_cache is not None:
+ x = torch.cat([prev_cache, x], dim=split_dim - 1)
+ return super().forward(x)
+
+ shape = list(x.size())
+ if prev_cache is not None:
+ shape[split_dim - 1] += prev_cache.size(split_dim - 1)
+ for i, pad_sum in enumerate((padding[4] + padding[5], padding[2] + padding[3], padding[0] + padding[1])):
+ shape[-3 + i] += pad_sum
+ memory_occupy = math.prod(shape) * x.element_size() / 1024**3 # GiB
+ if memory_occupy < self.memory_limit or split_dim == x.ndim:
+ x_concat = x
+ if prev_cache is not None:
+ x_concat = torch.cat([prev_cache, x], dim=split_dim - 1)
+
+ def pad_and_forward():
+ padded = F.pad(x_concat, padding, mode='constant', value=0.0)
+ if not padded.is_contiguous():
+ padded = padded.contiguous()
+ with ignore_padding(self):
+ return torch.nn.Conv3d.forward(self, padded)
+
+ return pad_and_forward()
+
+ num_splits = math.ceil(memory_occupy / self.memory_limit)
+ size_per_split = x.size(split_dim) // num_splits
+ split_sizes = [size_per_split] * (num_splits - 1)
+ split_sizes += [x.size(split_dim) - sum(split_sizes)]
+
+ x = list(x.split(split_sizes, dim=split_dim))
+ if prev_cache is not None:
+ prev_cache = list(prev_cache.split(split_sizes, dim=split_dim))
+ cache = None
+ for idx in range(len(x)):
+ if prev_cache is not None:
+ x[idx] = torch.cat([prev_cache[idx], x[idx]], dim=split_dim - 1)
+
+ lpad_dim = (x[idx].ndim - split_dim - 1) * 2
+ rpad_dim = lpad_dim + 1
+ padding = list(padding)
+ padding[lpad_dim] = self.padding[split_dim - 2] if idx == 0 else 0
+ padding[rpad_dim] = self.padding[split_dim - 2] if idx == len(x) - 1 else 0
+ pad_len = padding[lpad_dim] + padding[rpad_dim]
+ padding = tuple(padding)
+
+ next_cache = None
+ cache_len = cache.size(split_dim) if cache is not None else 0
+ next_cache_size = get_cache_size(
+ conv_module=self,
+ input_len=x[idx].size(split_dim) + cache_len,
+ pad_len=pad_len,
+ dim=split_dim - 2,
+ )
+ if next_cache_size != 0:
+ if next_cache_size > x[idx].size(split_dim):
+ raise ValueError(
+ f"SeedVR2 VAE cache size {next_cache_size} exceeds split size {x[idx].size(split_dim)}."
+ )
+ next_cache = (
+ x[idx].transpose(0, split_dim)[-next_cache_size:].transpose(0, split_dim)
+ )
+
+ x[idx] = self.memory_limit_conv(
+ x[idx],
+ split_dim=split_dim + 1,
+ padding=padding,
+ prev_cache=cache
+ )
+
+ cache = next_cache
+
+ output = torch.cat(x, dim=split_dim)
+ return output
+
+ def forward(
+ self,
+ input,
+ memory_state: MemoryState = MemoryState.UNSET,
+ memory_cache = None,
+ ) -> Tensor:
+ if memory_state == MemoryState.UNSET:
+ raise ValueError("SeedVR2 VAE convolution requires an explicit MemoryState.")
+ if memory_cache is None:
+ memory_cache = {}
+ if memory_state != MemoryState.ACTIVE:
+ memory_cache.pop(self, None)
+ if (
+ math.isinf(self.memory_limit)
+ and torch.is_tensor(input)
+ ):
+ return self.basic_forward(input, memory_state, memory_cache)
+ return self.slicing_forward(input, memory_state, memory_cache)
+
+ def basic_forward(self, input: Tensor, memory_state: MemoryState = MemoryState.UNSET, memory_cache = None):
+ mem_size = self.stride[0] - self.kernel_size[0]
+ memory = memory_cache.get(self) if memory_cache is not None else None
+ if (memory is not None) and (memory_state == MemoryState.ACTIVE):
+ input = extend_head(input, memory=memory, times=-1)
+ else:
+ input = extend_head(input, times=self.temporal_padding * 2)
+ next_memory = (
+ input[:, :, mem_size:].detach()
+ if (mem_size != 0 and memory_state != MemoryState.DISABLED)
+ else None
+ )
+ if memory_cache is not None and memory_state != MemoryState.DISABLED:
+ if next_memory is None:
+ memory_cache.pop(self, None)
+ else:
+ memory_cache[self] = next_memory
+ return super().forward(input)
+
+ def slicing_forward(
+ self,
+ input,
+ memory_state: MemoryState = MemoryState.UNSET,
+ memory_cache = None,
+ ) -> Tensor:
+ if memory_cache is None:
+ memory_cache = {}
+ squeeze_out = False
+ if torch.is_tensor(input):
+ input = [input]
+ squeeze_out = True
+
+ cache_size = self.kernel_size[0] - self.stride[0]
+ memory = memory_cache.get(self) if memory_cache is not None else None
+ cache = cache_send_recv(
+ input, cache_size=cache_size, memory=memory, times=self.temporal_padding * 2
+ )
+
+ if (
+ memory_state in [MemoryState.INITIALIZING, MemoryState.ACTIVE]
+ and cache_size != 0
+ ):
+ if cache_size > input[-1].size(2) and cache is not None and len(input) == 1:
+ input[0] = torch.cat([cache, input[0]], dim=2)
+ cache = None
+ if cache_size <= input[-1].size(2):
+ memory_cache[self] = input[-1][:, :, -cache_size:].detach().contiguous()
+
+ padding = tuple(x for x in reversed(self.padding) for _ in range(2))
+ for i in range(len(input)):
+ next_cache = None
+ cache_size = 0
+ if i < len(input) - 1:
+ cache_len = cache.size(2) if cache is not None else 0
+ cache_size = get_cache_size(self, input[i].size(2) + cache_len, pad_len=0)
+ if cache_size != 0:
+ if cache_size > input[i].size(2) and cache is not None:
+ input[i] = torch.cat([cache, input[i]], dim=2)
+ cache = None
+ if cache_size > input[i].size(2):
+ raise ValueError(f"SeedVR2 VAE cache size {cache_size} exceeds input length {input[i].size(2)}.")
+ next_cache = input[i][:, :, -cache_size:]
+
+ input[i] = self.memory_limit_conv(
+ input[i],
+ padding=padding,
+ prev_cache=cache
+ )
+
+ cache = next_cache
+
+ return input[0] if squeeze_out else input
+
+def remove_head(tensor: Tensor, times: int = 1) -> Tensor:
+ if times == 0:
+ return tensor
+ return torch.cat(tensors=(tensor[:, :, :1], tensor[:, :, times + 1 :]), dim=2)
+
+class Upsample3D(nn.Module):
+
+ def __init__(
+ self,
+ channels,
+ out_channels = None,
+ inflation_mode = "tail",
+ temporal_up: bool = False,
+ spatial_up: bool = True,
+ ):
+ super().__init__()
+ self.channels = channels
+ self.out_channels = out_channels or channels
+
+ conv = InflatedCausalConv3d(
+ self.channels,
+ self.out_channels,
+ 3,
+ padding=1,
+ inflation_mode=inflation_mode,
+ )
+
+ self.temporal_up = temporal_up
+ self.spatial_up = spatial_up
+ self.temporal_ratio = 2 if temporal_up else 1
+ self.spatial_ratio = 2 if spatial_up else 1
+
+ upscale_ratio = (self.spatial_ratio**2) * self.temporal_ratio
+ self.upscale_conv = ops.Conv3d(
+ self.channels, self.channels * upscale_ratio, kernel_size=1, padding=0
+ )
+
+ self.conv = conv
+
+ def forward(
+ self,
+ hidden_states: torch.FloatTensor,
+ memory_state=None,
+ memory_cache=None,
+ ) -> torch.FloatTensor:
+ if hidden_states.shape[1] != self.channels:
+ raise ValueError(f"SeedVR2 upsample expected {self.channels} channels, got {hidden_states.shape[1]}.")
+
+ hidden_states = self.upscale_conv(hidden_states)
+ b, channels, f, h, w = hidden_states.shape
+ c = channels // (self.spatial_ratio * self.spatial_ratio * self.temporal_ratio)
+ hidden_states = hidden_states.view(b, self.spatial_ratio, self.spatial_ratio, self.temporal_ratio, c, f, h, w)
+ hidden_states = hidden_states.permute(0, 4, 5, 3, 6, 1, 7, 2).reshape(
+ b,
+ c,
+ f * self.temporal_ratio,
+ h * self.spatial_ratio,
+ w * self.spatial_ratio,
+ )
+
+ if self.temporal_up and memory_state != MemoryState.ACTIVE:
+ hidden_states = remove_head(hidden_states)
+
+ hidden_states = self.conv(hidden_states, memory_state=memory_state, memory_cache=memory_cache)
+
+ return hidden_states
+
+
+class Downsample3D(nn.Module):
+ def __init__(
+ self,
+ channels,
+ out_channels = None,
+ inflation_mode = "tail",
+ spatial_down: bool = False,
+ temporal_down: bool = False,
+ ):
+ super().__init__()
+ self.channels = channels
+ self.out_channels = out_channels or channels
+ self.temporal_down = temporal_down
+ self.spatial_down = spatial_down
+
+ self.temporal_ratio = 2 if temporal_down else 1
+ self.spatial_ratio = 2 if spatial_down else 1
+
+ self.temporal_kernel = 3 if temporal_down else 1
+ self.spatial_kernel = 3 if spatial_down else 1
+
+ self.conv = InflatedCausalConv3d(
+ self.channels,
+ self.out_channels,
+ kernel_size=(self.temporal_kernel, self.spatial_kernel, self.spatial_kernel),
+ stride=(self.temporal_ratio, self.spatial_ratio, self.spatial_ratio),
+ padding=(1 if self.temporal_down else 0, 0, 0),
+ inflation_mode=inflation_mode,
+ )
+
+
+ def forward(
+ self,
+ hidden_states: torch.FloatTensor,
+ memory_state = None,
+ memory_cache = None,
+ ) -> torch.FloatTensor:
+
+ if hidden_states.shape[1] != self.channels:
+ raise ValueError(f"SeedVR2 downsample expected {self.channels} channels, got {hidden_states.shape[1]}.")
+
+ if self.spatial_down:
+ pad = (0, 1, 0, 1)
+ hidden_states = F.pad(hidden_states, pad, mode="constant", value=0)
+
+ if hidden_states.shape[1] != self.channels:
+ raise ValueError(f"SeedVR2 downsample expected {self.channels} channels after padding, got {hidden_states.shape[1]}.")
+
+ hidden_states = self.conv(hidden_states, memory_state=memory_state, memory_cache=memory_cache)
+
+ return hidden_states
+
+
+class ResnetBlock3D(nn.Module):
+ def __init__(
+ self,
+ in_channels: int,
+ out_channels: Optional[int] = None,
+ temb_channels: int = 512,
+ groups: int = 32,
+ groups_out: Optional[int] = None,
+ eps: float = 1e-6,
+ output_scale_factor: float = 1.0,
+ skip_time_act: bool = False,
+ inflation_mode = "tail",
+ time_receptive_field: _receptive_field_t = "half",
+ ):
+ super().__init__()
+ self.in_channels = in_channels
+ self.out_channels = in_channels if out_channels is None else out_channels
+ self.output_scale_factor = output_scale_factor
+ self.skip_time_act = skip_time_act
+ self.nonlinearity = nn.SiLU()
+ if temb_channels is not None:
+ self.time_emb_proj = ops.Linear(temb_channels, self.out_channels)
+ else:
+ self.time_emb_proj = None
+ self.norm1 = ops.GroupNorm(num_groups=groups, num_channels=in_channels, eps=eps, affine=True)
+ if groups_out is None:
+ groups_out = groups
+ self.norm2 = ops.GroupNorm(num_groups=groups_out, num_channels=self.out_channels, eps=eps, affine=True)
+ self.use_in_shortcut = self.in_channels != self.out_channels
+ self.conv1 = InflatedCausalConv3d(
+ self.in_channels,
+ self.out_channels,
+ kernel_size=(1, 3, 3) if time_receptive_field == "half" else (3, 3, 3),
+ stride=1,
+ padding=(0, 1, 1) if time_receptive_field == "half" else (1, 1, 1),
+ inflation_mode=inflation_mode,
+ )
+
+ self.conv2 = InflatedCausalConv3d(
+ self.out_channels,
+ self.out_channels,
+ kernel_size=3,
+ stride=1,
+ padding=1,
+ inflation_mode=inflation_mode,
+ )
+
+ self.conv_shortcut = None
+ if self.use_in_shortcut:
+ self.conv_shortcut = InflatedCausalConv3d(
+ self.in_channels,
+ self.out_channels,
+ kernel_size=1,
+ stride=1,
+ padding=0,
+ bias=True,
+ inflation_mode=inflation_mode,
+ )
+
+ def forward(self, input_tensor, temb, memory_state = None, memory_cache = None):
+ hidden_states = input_tensor
+
+ hidden_states = causal_norm_wrapper(self.norm1, hidden_states)
+
+ hidden_states = self.nonlinearity(hidden_states)
+
+ hidden_states = self.conv1(hidden_states, memory_state=memory_state, memory_cache=memory_cache)
+
+ if self.time_emb_proj is not None:
+ if not self.skip_time_act:
+ temb = self.nonlinearity(temb)
+ temb = self.time_emb_proj(temb)[:, :, None, None]
+
+ if temb is not None:
+ hidden_states = hidden_states + temb
+
+ hidden_states = causal_norm_wrapper(self.norm2, hidden_states)
+
+ hidden_states = self.nonlinearity(hidden_states)
+
+ hidden_states = self.conv2(hidden_states, memory_state=memory_state, memory_cache=memory_cache)
+
+ if self.conv_shortcut is not None:
+ input_tensor = self.conv_shortcut(input_tensor, memory_state=memory_state, memory_cache=memory_cache)
+
+ output_tensor = (input_tensor + hidden_states) / self.output_scale_factor
+
+ return output_tensor
+
+
+class DownEncoderBlock3D(nn.Module):
+ def __init__(
+ self,
+ in_channels: int,
+ out_channels: int,
+ num_layers: int = 1,
+ resnet_eps: float = 1e-6,
+ resnet_groups: int = 32,
+ output_scale_factor: float = 1.0,
+ add_downsample: bool = True,
+ inflation_mode = "tail",
+ time_receptive_field: _receptive_field_t = "half",
+ temporal_down: bool = True,
+ spatial_down: bool = True,
+ ):
+ super().__init__()
+ resnets = []
+
+ for i in range(num_layers):
+ in_channels = in_channels if i == 0 else out_channels
+ resnets.append(
+ ResnetBlock3D(
+ in_channels=in_channels,
+ out_channels=out_channels,
+ temb_channels=None,
+ eps=resnet_eps,
+ groups=resnet_groups,
+ output_scale_factor=output_scale_factor,
+ inflation_mode=inflation_mode,
+ time_receptive_field=time_receptive_field,
+ )
+ )
+
+ self.resnets = nn.ModuleList(resnets)
+
+ if add_downsample:
+ self.downsamplers = nn.ModuleList(
+ [
+ Downsample3D(
+ out_channels,
+ out_channels=out_channels,
+ temporal_down=temporal_down,
+ spatial_down=spatial_down,
+ inflation_mode=inflation_mode,
+ )
+ ]
+ )
+ else:
+ self.downsamplers = None
+
+ def forward(
+ self,
+ hidden_states: torch.FloatTensor,
+ memory_state = None,
+ memory_cache = None,
+ ) -> torch.FloatTensor:
+ for resnet in self.resnets:
+ hidden_states = resnet(hidden_states, temb=None, memory_state=memory_state, memory_cache=memory_cache)
+
+ if self.downsamplers is not None:
+ for downsampler in self.downsamplers:
+ hidden_states = downsampler(hidden_states, memory_state=memory_state, memory_cache=memory_cache)
+
+ return hidden_states
+
+
+class UpDecoderBlock3D(nn.Module):
+ def __init__(
+ self,
+ in_channels: int,
+ out_channels: int,
+ num_layers: int = 1,
+ resnet_eps: float = 1e-6,
+ resnet_groups: int = 32,
+ output_scale_factor: float = 1.0,
+ add_upsample: bool = True,
+ temb_channels: Optional[int] = None,
+ inflation_mode = "tail",
+ time_receptive_field: _receptive_field_t = "half",
+ temporal_up: bool = True,
+ spatial_up: bool = True,
+ ):
+ super().__init__()
+ resnets = []
+
+ for i in range(num_layers):
+ input_channels = in_channels if i == 0 else out_channels
+
+ resnets.append(
+ ResnetBlock3D(
+ in_channels=input_channels,
+ out_channels=out_channels,
+ temb_channels=temb_channels,
+ eps=resnet_eps,
+ groups=resnet_groups,
+ output_scale_factor=output_scale_factor,
+ inflation_mode=inflation_mode,
+ time_receptive_field=time_receptive_field,
+ )
+ )
+
+ self.resnets = nn.ModuleList(resnets)
+
+ if add_upsample:
+ self.upsamplers = nn.ModuleList(
+ [
+ Upsample3D(
+ out_channels,
+ out_channels=out_channels,
+ temporal_up=temporal_up,
+ spatial_up=spatial_up,
+ inflation_mode=inflation_mode,
+ )
+ ]
+ )
+ else:
+ self.upsamplers = None
+
+ def forward(
+ self,
+ hidden_states: torch.FloatTensor,
+ temb: Optional[torch.FloatTensor] = None,
+ memory_state=None,
+ memory_cache=None,
+ ) -> torch.FloatTensor:
+ for resnet in self.resnets:
+ hidden_states = resnet(hidden_states, temb=None, memory_state=memory_state, memory_cache=memory_cache)
+
+ if self.upsamplers is not None:
+ for upsampler in self.upsamplers:
+ hidden_states = upsampler(hidden_states, memory_state=memory_state, memory_cache=memory_cache)
+
+ return hidden_states
+
+
+class UNetMidBlock3D(nn.Module):
+ def __init__(
+ self,
+ in_channels: int,
+ temb_channels: int,
+ num_layers: int = 1,
+ resnet_eps: float = 1e-6,
+ resnet_time_scale_shift: str = "default", # default, spatial
+ resnet_groups: int = 32,
+ add_attention: bool = True,
+ attention_head_dim: int = 1,
+ output_scale_factor: float = 1.0,
+ inflation_mode = "tail",
+ time_receptive_field: _receptive_field_t = "half",
+ ):
+ super().__init__()
+ resnet_groups = resnet_groups if resnet_groups is not None else min(in_channels // 4, 32)
+ self.add_attention = add_attention
+
+ resnets = [
+ ResnetBlock3D(
+ in_channels=in_channels,
+ out_channels=in_channels,
+ temb_channels=temb_channels,
+ eps=resnet_eps,
+ groups=resnet_groups,
+ output_scale_factor=output_scale_factor,
+ inflation_mode=inflation_mode,
+ time_receptive_field=time_receptive_field,
+ )
+ ]
+ attentions = []
+
+ if attention_head_dim is None:
+ attention_head_dim = in_channels
+
+ for _ in range(num_layers):
+ if self.add_attention:
+ attentions.append(
+ Attention(
+ in_channels,
+ heads=in_channels // attention_head_dim,
+ dim_head=attention_head_dim,
+ rescale_output_factor=output_scale_factor,
+ eps=resnet_eps,
+ norm_num_groups=(
+ resnet_groups if resnet_time_scale_shift == "default" else None
+ ),
+ spatial_norm_dim=(
+ temb_channels if resnet_time_scale_shift == "spatial" else None
+ ),
+ residual_connection=True,
+ bias=True,
+ )
+ )
+ else:
+ attentions.append(None)
+
+ resnets.append(
+ ResnetBlock3D(
+ in_channels=in_channels,
+ out_channels=in_channels,
+ temb_channels=temb_channels,
+ eps=resnet_eps,
+ groups=resnet_groups,
+ output_scale_factor=output_scale_factor,
+ inflation_mode=inflation_mode,
+ time_receptive_field=time_receptive_field,
+ )
+ )
+
+ self.attentions = nn.ModuleList(attentions)
+ self.resnets = nn.ModuleList(resnets)
+
+ def forward(self, hidden_states, temb=None, memory_state=None, memory_cache=None):
+ video_length = hidden_states.size(2)
+ hidden_states = self.resnets[0](hidden_states, temb, memory_state=memory_state, memory_cache=memory_cache)
+ for attn, resnet in zip(self.attentions, self.resnets[1:]):
+ if attn is not None:
+ b, c, f, h, w = hidden_states.shape
+ hidden_states = hidden_states.transpose(1, 2).reshape(b * f, c, h, w)
+ hidden_states = attn(hidden_states, temb=temb)
+ hidden_states = hidden_states.reshape(b, video_length, c, h, w).transpose(1, 2)
+ hidden_states = resnet(hidden_states, temb, memory_state=memory_state, memory_cache=memory_cache)
+
+ return hidden_states
+
+
+class Encoder3D(nn.Module):
+ def __init__(
+ self,
+ in_channels: int = 3,
+ out_channels: int = 3,
+ down_block_types: Tuple[str, ...] = ("DownEncoderBlock3D",),
+ block_out_channels: Tuple[int, ...] = (64,),
+ layers_per_block: int = 2,
+ norm_num_groups: int = 32,
+ mid_block_add_attention=True,
+ temporal_down_num: int = 2,
+ inflation_mode = "tail",
+ time_receptive_field: _receptive_field_t = "half",
+ ):
+ super().__init__()
+ self.layers_per_block = layers_per_block
+ self.temporal_down_num = temporal_down_num
+
+ self.conv_in = InflatedCausalConv3d(
+ in_channels,
+ block_out_channels[0],
+ kernel_size=3,
+ stride=1,
+ padding=1,
+ inflation_mode=inflation_mode,
+ )
+
+ self.mid_block = None
+ self.down_blocks = nn.ModuleList([])
+
+ output_channel = block_out_channels[0]
+ for i, down_block_type in enumerate(down_block_types):
+ input_channel = output_channel
+ output_channel = block_out_channels[i]
+ is_final_block = i == len(block_out_channels) - 1
+ is_temporal_down_block = i >= len(block_out_channels) - self.temporal_down_num - 1
+
+ if down_block_type != "DownEncoderBlock3D":
+ raise ValueError(f"SeedVR2 encoder only supports DownEncoderBlock3D, got {down_block_type}.")
+
+ down_block = DownEncoderBlock3D(
+ num_layers=self.layers_per_block,
+ in_channels=input_channel,
+ out_channels=output_channel,
+ add_downsample=not is_final_block,
+ resnet_eps=1e-6,
+ resnet_groups=norm_num_groups,
+ temporal_down=is_temporal_down_block,
+ spatial_down=True,
+ inflation_mode=inflation_mode,
+ time_receptive_field=time_receptive_field,
+ )
+ self.down_blocks.append(down_block)
+
+ self.mid_block = UNetMidBlock3D(
+ in_channels=block_out_channels[-1],
+ resnet_eps=1e-6,
+ output_scale_factor=1,
+ resnet_time_scale_shift="default",
+ attention_head_dim=block_out_channels[-1],
+ resnet_groups=norm_num_groups,
+ temb_channels=None,
+ add_attention=mid_block_add_attention,
+ inflation_mode=inflation_mode,
+ time_receptive_field=time_receptive_field,
+ )
+
+ self.conv_norm_out = ops.GroupNorm(
+ num_channels=block_out_channels[-1], num_groups=norm_num_groups, eps=1e-6
+ )
+ self.conv_act = nn.SiLU()
+
+ conv_out_channels = 2 * out_channels
+ self.conv_out = InflatedCausalConv3d(
+ block_out_channels[-1], conv_out_channels, 3, padding=1, inflation_mode=inflation_mode
+ )
+
+
+ def forward(
+ self,
+ sample: torch.FloatTensor,
+ memory_state = None,
+ memory_cache = None,
+ ) -> torch.FloatTensor:
+ sample = sample.to(next(self.parameters()).device)
+ sample = self.conv_in(sample, memory_state=memory_state, memory_cache=memory_cache)
+ for down_block in self.down_blocks:
+ sample = down_block(sample, memory_state=memory_state, memory_cache=memory_cache)
+
+ sample = self.mid_block(sample, memory_state=memory_state, memory_cache=memory_cache)
+
+ sample = causal_norm_wrapper(self.conv_norm_out, sample)
+ sample = self.conv_act(sample)
+ sample = self.conv_out(sample, memory_state=memory_state, memory_cache=memory_cache)
+
+ return sample
+
+
+class Decoder3D(nn.Module):
+
+ def __init__(
+ self,
+ in_channels: int = 3,
+ out_channels: int = 3,
+ up_block_types: Tuple[str, ...] = ("UpDecoderBlock3D",),
+ block_out_channels: Tuple[int, ...] = (64,),
+ layers_per_block: int = 2,
+ norm_num_groups: int = 32,
+ mid_block_add_attention=True,
+ inflation_mode = "tail",
+ time_receptive_field: _receptive_field_t = "half",
+ temporal_up_num: int = 2,
+ ):
+ super().__init__()
+ self.layers_per_block = layers_per_block
+ self.temporal_up_num = temporal_up_num
+
+ self.conv_in = InflatedCausalConv3d(
+ in_channels,
+ block_out_channels[-1],
+ kernel_size=3,
+ stride=1,
+ padding=1,
+ inflation_mode=inflation_mode,
+ )
+
+ self.mid_block = None
+ self.up_blocks = nn.ModuleList([])
+
+ temb_channels = None
+
+ self.mid_block = UNetMidBlock3D(
+ in_channels=block_out_channels[-1],
+ resnet_eps=1e-6,
+ output_scale_factor=1,
+ resnet_time_scale_shift="default",
+ attention_head_dim=block_out_channels[-1],
+ resnet_groups=norm_num_groups,
+ temb_channels=temb_channels,
+ add_attention=mid_block_add_attention,
+ inflation_mode=inflation_mode,
+ time_receptive_field=time_receptive_field,
+ )
+
+ reversed_block_out_channels = list(reversed(block_out_channels))
+ output_channel = reversed_block_out_channels[0]
+ for i, up_block_type in enumerate(up_block_types):
+ prev_output_channel = output_channel
+ output_channel = reversed_block_out_channels[i]
+
+ is_final_block = i == len(block_out_channels) - 1
+ is_temporal_up_block = i < self.temporal_up_num
+ if up_block_type != "UpDecoderBlock3D":
+ raise ValueError(f"SeedVR2 decoder only supports UpDecoderBlock3D, got {up_block_type}.")
+ up_block = UpDecoderBlock3D(
+ num_layers=self.layers_per_block + 1,
+ in_channels=prev_output_channel,
+ out_channels=output_channel,
+ add_upsample=not is_final_block,
+ resnet_eps=1e-6,
+ resnet_groups=norm_num_groups,
+ temb_channels=temb_channels,
+ temporal_up=is_temporal_up_block,
+ inflation_mode=inflation_mode,
+ time_receptive_field=time_receptive_field,
+ )
+ self.up_blocks.append(up_block)
+ prev_output_channel = output_channel
+
+ self.conv_norm_out = ops.GroupNorm(
+ num_channels=block_out_channels[0], num_groups=norm_num_groups, eps=1e-6
+ )
+ self.conv_act = nn.SiLU()
+ self.conv_out = InflatedCausalConv3d(
+ block_out_channels[0], out_channels, 3, padding=1, inflation_mode=inflation_mode
+ )
+
+
+ def forward(
+ self,
+ sample: torch.FloatTensor,
+ latent_embeds: Optional[torch.FloatTensor] = None,
+ memory_state = None,
+ memory_cache = None,
+ ) -> torch.FloatTensor:
+
+ sample = sample.to(next(self.parameters()).device)
+ sample = self.conv_in(sample, memory_state=memory_state, memory_cache=memory_cache)
+
+ upscale_dtype = next(iter(self.up_blocks.parameters())).dtype
+ sample = self.mid_block(sample, latent_embeds, memory_state=memory_state, memory_cache=memory_cache)
+ sample = sample.to(upscale_dtype)
+
+ for up_block in self.up_blocks:
+ sample = up_block(sample, latent_embeds, memory_state=memory_state, memory_cache=memory_cache)
+
+ sample = causal_norm_wrapper(self.conv_norm_out, sample)
+ sample = self.conv_act(sample)
+ sample = self.conv_out(sample, memory_state=memory_state, memory_cache=memory_cache)
+
+ return sample
+
+class VideoAutoencoderKL(nn.Module):
+ def __init__(
+ self,
+ in_channels: int = 3,
+ out_channels: int = 3,
+ layers_per_block: int = 2,
+ latent_channels: int = SEEDVR2_LATENT_CHANNELS,
+ norm_num_groups: int = 32,
+ temporal_scale_num: int = 2,
+ inflation_mode = "pad",
+ time_receptive_field: _receptive_field_t = "full",
+ slicing_sample_min_size = BYTEDANCE_SLICING_SAMPLE_MIN,
+ ):
+ self.slicing_sample_min_size = slicing_sample_min_size
+ self.slicing_latent_min_size = slicing_sample_min_size // (2**temporal_scale_num)
+ block_out_channels = BYTEDANCE_BLOCK_OUT_CHANNELS
+ down_block_types = ("DownEncoderBlock3D",) * 4
+ up_block_types = ("UpDecoderBlock3D",) * 4
+ super().__init__()
+
+ self.encoder = Encoder3D(
+ in_channels=in_channels,
+ out_channels=latent_channels,
+ down_block_types=down_block_types,
+ block_out_channels=block_out_channels,
+ layers_per_block=layers_per_block,
+ norm_num_groups=norm_num_groups,
+ temporal_down_num=temporal_scale_num,
+ inflation_mode=inflation_mode,
+ time_receptive_field=time_receptive_field,
+ )
+
+ self.decoder = Decoder3D(
+ in_channels=latent_channels,
+ out_channels=out_channels,
+ up_block_types=up_block_types,
+ block_out_channels=block_out_channels,
+ layers_per_block=layers_per_block,
+ norm_num_groups=norm_num_groups,
+ temporal_up_num=temporal_scale_num,
+ inflation_mode=inflation_mode,
+ time_receptive_field=time_receptive_field,
+ )
+
+ self.use_slicing = True
+
+ def encode(self, x: torch.FloatTensor, return_dict: bool = True):
+ h = self.slicing_encode(x)
+ posterior = DiagonalGaussianDistribution(h).mode()
+
+ if not return_dict:
+ return (posterior,)
+
+ return posterior
+
+ def decode_(
+ self, z: torch.Tensor, return_dict: bool = True
+ ):
+ decoded = self.slicing_decode(z)
+
+ if not return_dict:
+ return (decoded,)
+
+ return decoded
+
+ def _encode(
+ self, x, memory_state = MemoryState.DISABLED, memory_cache = None
+ ) -> torch.Tensor:
+ _x = x.to(self.device)
+ h = self.encoder(_x, memory_state=memory_state, memory_cache=memory_cache)
+ return h.to(x.device)
+
+ def _decode(
+ self, z, memory_state = MemoryState.DISABLED, memory_cache = None
+ ) -> torch.Tensor:
+ _z = z.to(self.device)
+ output = self.decoder(_z, memory_state=memory_state, memory_cache=memory_cache)
+ return output.to(z.device)
+
+ def slicing_encode(self, x: torch.Tensor) -> torch.Tensor:
+ if self.use_slicing and (x.shape[2] - 1) > self.slicing_sample_min_size:
+ memory_cache = {}
+ split_size = max(
+ self.slicing_sample_min_size,
+ getattr(self, "temporal_downsample_factor", 1),
+ )
+ x_slices = list(x[:, :, 1:].split(split_size=split_size, dim=2))
+ min_active_len = getattr(self, "temporal_downsample_factor", 1)
+ if len(x_slices) > 1 and x_slices[-1].shape[2] < min_active_len:
+ x_slices[-2] = torch.cat((x_slices[-2], x_slices[-1]), dim=2)
+ x_slices.pop()
+ encoded_slices = [
+ self._encode(
+ torch.cat((x[:, :, :1], x_slices[0]), dim=2),
+ memory_state=MemoryState.INITIALIZING,
+ memory_cache=memory_cache,
+ )
+ ]
+ for x_idx in range(1, len(x_slices)):
+ encoded_slices.append(
+ self._encode(x_slices[x_idx], memory_state=MemoryState.ACTIVE, memory_cache=memory_cache)
+ )
+ out = torch.cat(encoded_slices, dim=2)
+ return out
+ else:
+ return self._encode(x)
+
+ def slicing_decode(self, z: torch.Tensor) -> torch.Tensor:
+ if self.use_slicing and (z.shape[2] - 1) > self.slicing_latent_min_size:
+ memory_cache = {}
+ z_slices = z[:, :, 1:].split(split_size=self.slicing_latent_min_size, dim=2)
+ decoded_slices = [
+ self._decode(
+ torch.cat((z[:, :, :1], z_slices[0]), dim=2),
+ memory_state=MemoryState.INITIALIZING,
+ memory_cache=memory_cache,
+ )
+ ]
+ for z_idx in range(1, len(z_slices)):
+ decoded_slices.append(
+ self._decode(z_slices[z_idx], memory_state=MemoryState.ACTIVE, memory_cache=memory_cache)
+ )
+ out = torch.cat(decoded_slices, dim=2)
+ return out
+ else:
+ return self._decode(z)
+
+ def forward(self, x: torch.FloatTensor, mode: Literal["encode", "decode", "all"] = "all"):
+ def _unwrap(value):
+ return value[0] if isinstance(value, tuple) else value
+
+ if mode == "encode":
+ return _unwrap(self.encode(x))
+ if mode == "decode":
+ return _unwrap(self.decode_(x))
+ if mode == "all":
+ latent = _unwrap(self.encode(x))
+ return _unwrap(self.decode_(latent))
+ raise ValueError(f"Unknown SeedVR2 VAE forward mode: {mode}")
+
+class VideoAutoencoderKLWrapper(VideoAutoencoderKL):
+ def __init__(
+ self,
+ spatial_downsample_factor = 8,
+ temporal_downsample_factor = 4,
+ ):
+ self.spatial_downsample_factor = spatial_downsample_factor
+ self.temporal_downsample_factor = temporal_downsample_factor
+ super().__init__()
+ self.set_memory_limit(BYTEDANCE_VAE_CONV_MEM_GIB, BYTEDANCE_VAE_NORM_MEM_GIB)
+
+ def forward(self, x: torch.FloatTensor):
+ z, p = self._encode_with_raw_latent(x)
+ x = self.decode(z)
+ return x, z, p
+
+ def _encode_with_raw_latent(self, x):
+ if x.ndim == 4:
+ x = x.unsqueeze(2)
+ self.device = x.device
+ p = super().encode(x)
+ z = p.squeeze(2)
+ return z, p
+
+ def encode(self, x):
+ z, _ = self._encode_with_raw_latent(x)
+ return z
+
+ def decode(self, z, seedvr2_tiling=None):
+ seedvr2_tiling = {} if seedvr2_tiling is None else seedvr2_tiling
+ if not isinstance(seedvr2_tiling, dict):
+ raise RuntimeError(
+ "SeedVR2 VideoAutoencoderKLWrapper.decode: `seedvr2_tiling` must be a dict; "
+ f"got {type(seedvr2_tiling).__name__} with value {seedvr2_tiling!r}."
+ )
+
+ if z.ndim == 5:
+ _, c, _, _, _ = z.shape
+ if c != SEEDVR2_LATENT_CHANNELS:
+ raise RuntimeError(
+ "SeedVR2 VideoAutoencoderKLWrapper.decode: 5-D latent input must "
+ f"have {SEEDVR2_LATENT_CHANNELS} channels; got shape {tuple(z.shape)}."
+ )
+ latent = z
+ elif z.ndim == 4:
+ b, tc, h, w = z.shape
+ if tc % SEEDVR2_LATENT_CHANNELS != 0:
+ raise RuntimeError(
+ "SeedVR2 VideoAutoencoderKLWrapper.decode: 4-D latent input must "
+ f"use collapsed channel layout (B, {SEEDVR2_LATENT_CHANNELS}*T, H, W); "
+ f"got shape {tuple(z.shape)}."
+ )
+ latent = z.reshape(b, SEEDVR2_LATENT_CHANNELS, -1, h, w)
+ else:
+ raise RuntimeError(
+ "SeedVR2 VideoAutoencoderKLWrapper.decode: latent input must be "
+ f"4-D collapsed (B, {SEEDVR2_LATENT_CHANNELS}*T, H, W) or "
+ f"5-D (B, {SEEDVR2_LATENT_CHANNELS}, T, H, W); "
+ f"got shape {tuple(z.shape)}."
+ )
+ scale = BYTEDANCE_VAE_SCALING_FACTOR
+ shift = BYTEDANCE_VAE_SHIFTING_FACTOR
+ latent = latent / scale + shift
+
+ self.device = latent.device
+ enable_tiling = seedvr2_tiling.get("enable_tiling", False)
+
+ if enable_tiling:
+ decode_seedvr2_args = dict(seedvr2_tiling)
+ decode_seedvr2_args.pop("enable_tiling", None)
+ tile_h, tile_w = decode_seedvr2_args.get("tile_size", (512, 512))
+ ov_h, ov_w = decode_seedvr2_args.get("tile_overlap", (64, 64))
+ decode_seedvr2_args["tile_overlap"] = (
+ min(ov_h, max(0, tile_h - 8)),
+ min(ov_w, max(0, tile_w - 8)),
+ )
+ x = tiled_vae(latent, self, **decode_seedvr2_args, encode=False)
+ if x.ndim == 4:
+ # tiled_vae squeezes the temporal axis when
+ # temporal_downsample_factor == 1 AND latent T == 1
+ # (see tiled_vae line 179-180); re-add it so the post-decode
+ # pipeline can keep batch and time distinct on the tiled path.
+ x = x.unsqueeze(2)
+ else:
+ x = super().decode_(latent)
+
+ h, w = x.shape[-2:]
+ w2 = w - (w % 2)
+ h2 = h - (h % 2)
+ x = x[..., :h2, :w2]
+
+ return x
+
+ def decode_tiled(self, z, tile_x=32, tile_y=32, overlap=8, tile_t=None, overlap_t=None):
+ # SeedVR2's causal VAE owns temporal via the MemoryState cache; external
+ # temporal tiling breaks that continuity, so only spatial tiling is applied.
+ sf = self.spatial_downsample_factor
+ seedvr2_tiling = {
+ "enable_tiling": True,
+ "tile_size": (tile_y * sf, tile_x * sf),
+ "tile_overlap": (overlap * sf, overlap * sf),
+ "temporal_size": None,
+ "temporal_overlap": None,
+ }
+ return self.decode(z, seedvr2_tiling=seedvr2_tiling)
+
+ def encode_tiled(self, x, tile_x=None, tile_y=None, overlap=None, tile_t=None, overlap_t=None):
+ # External temporal tiling knobs are discarded; the causal VAE keeps its
+ # own internal MemoryState slicing.
+ if tile_y is None:
+ tile_y = 512
+ if tile_x is None:
+ tile_x = 512
+ if overlap is None:
+ overlap_y = 64
+ overlap_x = 64
+ else:
+ overlap_y = overlap
+ overlap_x = overlap
+ overlap_y = min(overlap_y, max(0, tile_y - 8))
+ overlap_x = min(overlap_x, max(0, tile_x - 8))
+ self.device = x.device
+ return tiled_vae(
+ x,
+ self,
+ tile_size=(tile_y, tile_x),
+ tile_overlap=(overlap_y, overlap_x),
+ temporal_size=None,
+ temporal_overlap=None,
+ encode=True,
+ )
+
+ def comfy_format_encoded(self, samples):
+ if samples.ndim == 4:
+ samples = samples.unsqueeze(2)
+ samples = samples.contiguous()
+ samples = samples * BYTEDANCE_VAE_SCALING_FACTOR
+ return samples
+
+ def comfy_memory_used_decode(self, shape):
+ bytes_per_output_pixel = 160
+
+ def output_pixels(latent_t, latent_h, latent_w):
+ output_t = max(1, (latent_t - 1) * 4 + 1)
+ return output_t * latent_h * 8 * latent_w * 8
+
+ # SeedVR2 decode performs full-frame LAB histogram matching: fp32 channels
+ # plus int64 sort indices dominate peak memory, not the VAE weight dtype.
+ if len(shape) == 5:
+ candidates = []
+ if shape[1] == SEEDVR2_LATENT_CHANNELS:
+ candidates.append((shape[2], shape[3], shape[4]))
+ if shape[-1] == SEEDVR2_LATENT_CHANNELS:
+ candidates.append((shape[1], shape[2], shape[3]))
+ if len(candidates) == 0:
+ candidates.append((shape[2], shape[3], shape[4]))
+ pixels = max(output_pixels(*candidate) for candidate in candidates)
+ elif len(shape) == 4:
+ latent_t = max(1, (shape[1] + SEEDVR2_LATENT_CHANNELS - 1) // SEEDVR2_LATENT_CHANNELS)
+ pixels = output_pixels(latent_t, shape[2], shape[3])
+ else:
+ pixels = output_pixels(1, shape[-2], shape[-1])
+ return pixels * bytes_per_output_pixel
+
+ def set_memory_limit(self, conv_max_mem: Optional[float], norm_max_mem: Optional[float]):
+ set_norm_limit(norm_max_mem)
+ for m in self.modules():
+ if isinstance(m, InflatedCausalConv3d):
+ m.set_memory_limit(conv_max_mem if conv_max_mem is not None else float("inf"))
diff --git a/ComfyUI/comfy/ldm/supir/__init__.py b/ComfyUI/comfy/ldm/supir/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/ComfyUI/comfy/ldm/supir/__pycache__/__init__.cpython-312.pyc b/ComfyUI/comfy/ldm/supir/__pycache__/__init__.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..19554192ec5591a34e8dd9944d9708a0292c6e84
Binary files /dev/null and b/ComfyUI/comfy/ldm/supir/__pycache__/__init__.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/supir/__pycache__/supir_modules.cpython-312.pyc b/ComfyUI/comfy/ldm/supir/__pycache__/supir_modules.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..460f8e02575b5f19f71c82da0fc955e7980a817f
Binary files /dev/null and b/ComfyUI/comfy/ldm/supir/__pycache__/supir_modules.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/supir/__pycache__/supir_patch.cpython-312.pyc b/ComfyUI/comfy/ldm/supir/__pycache__/supir_patch.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..ec1451ae95c0c78a6137fd89b7955aff3af9666a
Binary files /dev/null and b/ComfyUI/comfy/ldm/supir/__pycache__/supir_patch.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/supir/supir_modules.py b/ComfyUI/comfy/ldm/supir/supir_modules.py
new file mode 100644
index 0000000000000000000000000000000000000000..7389b01d2bd55f025b333ba6b1b2e7170a71548a
--- /dev/null
+++ b/ComfyUI/comfy/ldm/supir/supir_modules.py
@@ -0,0 +1,226 @@
+import torch
+import torch.nn as nn
+
+from comfy.ldm.modules.diffusionmodules.util import timestep_embedding
+from comfy.ldm.modules.diffusionmodules.openaimodel import Downsample, TimestepEmbedSequential, ResBlock, SpatialTransformer
+from comfy.ldm.modules.attention import optimized_attention
+
+
+class ZeroSFT(nn.Module):
+ def __init__(self, label_nc, norm_nc, concat_channels=0, dtype=None, device=None, operations=None):
+ super().__init__()
+
+ ks = 3
+ pw = ks // 2
+
+ self.param_free_norm = operations.GroupNorm(32, norm_nc + concat_channels, dtype=dtype, device=device)
+
+ nhidden = 128
+
+ self.mlp_shared = nn.Sequential(
+ operations.Conv2d(label_nc, nhidden, kernel_size=ks, padding=pw, dtype=dtype, device=device),
+ nn.SiLU()
+ )
+ self.zero_mul = operations.Conv2d(nhidden, norm_nc + concat_channels, kernel_size=ks, padding=pw, dtype=dtype, device=device)
+ self.zero_add = operations.Conv2d(nhidden, norm_nc + concat_channels, kernel_size=ks, padding=pw, dtype=dtype, device=device)
+
+ self.zero_conv = operations.Conv2d(label_nc, norm_nc, 1, 1, 0, dtype=dtype, device=device)
+ self.pre_concat = bool(concat_channels != 0)
+
+ def forward(self, c, h, h_ori=None, control_scale=1):
+ if h_ori is not None and self.pre_concat:
+ h_raw = torch.cat([h_ori, h], dim=1)
+ else:
+ h_raw = h
+
+ h = h + self.zero_conv(c)
+ if h_ori is not None and self.pre_concat:
+ h = torch.cat([h_ori, h], dim=1)
+ actv = self.mlp_shared(c)
+ gamma = self.zero_mul(actv)
+ beta = self.zero_add(actv)
+ h = self.param_free_norm(h)
+ h = torch.addcmul(h + beta, h, gamma)
+ if h_ori is not None and not self.pre_concat:
+ h = torch.cat([h_ori, h], dim=1)
+ return torch.lerp(h_raw, h, control_scale)
+
+
+class _CrossAttnInner(nn.Module):
+ """Inner cross-attention module matching the state_dict layout of the original CrossAttention."""
+ def __init__(self, query_dim, context_dim, heads, dim_head, dtype=None, device=None, operations=None):
+ super().__init__()
+ inner_dim = dim_head * heads
+ self.heads = heads
+ self.to_q = operations.Linear(query_dim, inner_dim, bias=False, dtype=dtype, device=device)
+ self.to_k = operations.Linear(context_dim, inner_dim, bias=False, dtype=dtype, device=device)
+ self.to_v = operations.Linear(context_dim, inner_dim, bias=False, dtype=dtype, device=device)
+ self.to_out = nn.Sequential(
+ operations.Linear(inner_dim, query_dim, dtype=dtype, device=device),
+ )
+
+ def forward(self, x, context):
+ q = self.to_q(x)
+ k = self.to_k(context)
+ v = self.to_v(context)
+ return self.to_out(optimized_attention(q, k, v, self.heads))
+
+
+class ZeroCrossAttn(nn.Module):
+ def __init__(self, context_dim, query_dim, dtype=None, device=None, operations=None):
+ super().__init__()
+ heads = query_dim // 64
+ dim_head = 64
+ self.attn = _CrossAttnInner(query_dim, context_dim, heads, dim_head, dtype=dtype, device=device, operations=operations)
+ self.norm1 = operations.GroupNorm(32, query_dim, dtype=dtype, device=device)
+ self.norm2 = operations.GroupNorm(32, context_dim, dtype=dtype, device=device)
+
+ def forward(self, context, x, control_scale=1):
+ b, c, h, w = x.shape
+ x_in = x
+
+ x = self.attn(
+ self.norm1(x).flatten(2).transpose(1, 2),
+ self.norm2(context).flatten(2).transpose(1, 2),
+ ).transpose(1, 2).unflatten(2, (h, w))
+
+ return x_in + x * control_scale
+
+
+class GLVControl(nn.Module):
+ """SUPIR's Guided Latent Vector control encoder. Truncated UNet (input + middle blocks only)."""
+ def __init__(
+ self,
+ in_channels=4,
+ model_channels=320,
+ num_res_blocks=2,
+ attention_resolutions=(4, 2),
+ channel_mult=(1, 2, 4),
+ num_head_channels=64,
+ transformer_depth=(1, 2, 10),
+ context_dim=2048,
+ adm_in_channels=2816,
+ use_linear_in_transformer=True,
+ use_checkpoint=False,
+ dtype=None,
+ device=None,
+ operations=None,
+ **kwargs,
+ ):
+ super().__init__()
+ self.model_channels = model_channels
+ time_embed_dim = model_channels * 4
+
+ self.time_embed = nn.Sequential(
+ operations.Linear(model_channels, time_embed_dim, dtype=dtype, device=device),
+ nn.SiLU(),
+ operations.Linear(time_embed_dim, time_embed_dim, dtype=dtype, device=device),
+ )
+
+ self.label_emb = nn.Sequential(
+ nn.Sequential(
+ operations.Linear(adm_in_channels, time_embed_dim, dtype=dtype, device=device),
+ nn.SiLU(),
+ operations.Linear(time_embed_dim, time_embed_dim, dtype=dtype, device=device),
+ )
+ )
+
+ self.input_blocks = nn.ModuleList([
+ TimestepEmbedSequential(
+ operations.Conv2d(in_channels, model_channels, 3, padding=1, dtype=dtype, device=device)
+ )
+ ])
+ ch = model_channels
+ ds = 1
+ for level, mult in enumerate(channel_mult):
+ for nr in range(num_res_blocks):
+ layers = [
+ ResBlock(ch, time_embed_dim, 0, out_channels=mult * model_channels,
+ dtype=dtype, device=device, operations=operations)
+ ]
+ ch = mult * model_channels
+ if ds in attention_resolutions:
+ num_heads = ch // num_head_channels
+ layers.append(
+ SpatialTransformer(ch, num_heads, num_head_channels,
+ depth=transformer_depth[level], context_dim=context_dim,
+ use_linear=use_linear_in_transformer,
+ use_checkpoint=use_checkpoint,
+ dtype=dtype, device=device, operations=operations)
+ )
+ self.input_blocks.append(TimestepEmbedSequential(*layers))
+ if level != len(channel_mult) - 1:
+ self.input_blocks.append(
+ TimestepEmbedSequential(
+ Downsample(ch, True, out_channels=ch, dtype=dtype, device=device, operations=operations)
+ )
+ )
+ ds *= 2
+
+ num_heads = ch // num_head_channels
+ self.middle_block = TimestepEmbedSequential(
+ ResBlock(ch, time_embed_dim, 0, dtype=dtype, device=device, operations=operations),
+ SpatialTransformer(ch, num_heads, num_head_channels,
+ depth=transformer_depth[-1], context_dim=context_dim,
+ use_linear=use_linear_in_transformer,
+ use_checkpoint=use_checkpoint,
+ dtype=dtype, device=device, operations=operations),
+ ResBlock(ch, time_embed_dim, 0, dtype=dtype, device=device, operations=operations),
+ )
+
+ self.input_hint_block = TimestepEmbedSequential(
+ operations.Conv2d(in_channels, model_channels, 3, padding=1, dtype=dtype, device=device)
+ )
+
+ def forward(self, x, timesteps, xt, context=None, y=None, **kwargs):
+ t_emb = timestep_embedding(timesteps, self.model_channels, repeat_only=False).to(x.dtype)
+ emb = self.time_embed(t_emb) + self.label_emb(y)
+
+ guided_hint = self.input_hint_block(x, emb, context)
+
+ hs = []
+ h = xt
+ for module in self.input_blocks:
+ if guided_hint is not None:
+ h = module(h, emb, context)
+ h += guided_hint
+ guided_hint = None
+ else:
+ h = module(h, emb, context)
+ hs.append(h)
+ h = self.middle_block(h, emb, context)
+ hs.append(h)
+ return hs
+
+
+class SUPIR(nn.Module):
+ """
+ SUPIR model containing GLVControl (control encoder) and project_modules (adapters).
+ State dict keys match the original SUPIR checkpoint layout:
+ control_model.* -> GLVControl
+ project_modules.* -> nn.ModuleList of ZeroSFT/ZeroCrossAttn
+ """
+ def __init__(self, device=None, dtype=None, operations=None):
+ super().__init__()
+
+ self.control_model = GLVControl(dtype=dtype, device=device, operations=operations)
+
+ project_channel_scale = 2
+ cond_output_channels = [320] * 4 + [640] * 3 + [1280] * 3
+ project_channels = [int(c * project_channel_scale) for c in [160] * 4 + [320] * 3 + [640] * 3]
+ concat_channels = [320] * 2 + [640] * 3 + [1280] * 4 + [0]
+ cross_attn_insert_idx = [6, 3]
+
+ self.project_modules = nn.ModuleList()
+ for i in range(len(cond_output_channels)):
+ self.project_modules.append(ZeroSFT(
+ project_channels[i], cond_output_channels[i],
+ concat_channels=concat_channels[i],
+ dtype=dtype, device=device, operations=operations,
+ ))
+
+ for i in cross_attn_insert_idx:
+ self.project_modules.insert(i, ZeroCrossAttn(
+ cond_output_channels[i], concat_channels[i],
+ dtype=dtype, device=device, operations=operations,
+ ))
diff --git a/ComfyUI/comfy/ldm/supir/supir_patch.py b/ComfyUI/comfy/ldm/supir/supir_patch.py
new file mode 100644
index 0000000000000000000000000000000000000000..b67ab4cd89ffc5cb2e325c52af954b40210be233
--- /dev/null
+++ b/ComfyUI/comfy/ldm/supir/supir_patch.py
@@ -0,0 +1,103 @@
+import torch
+from comfy.ldm.modules.diffusionmodules.openaimodel import Upsample
+
+
+class SUPIRPatch:
+ """
+ Holds GLVControl (control encoder) + project_modules (ZeroSFT/ZeroCrossAttn adapters).
+ Runs GLVControl lazily on first patch invocation per step, applies adapters through
+ middle_block_after_patch, output_block_merge_patch, and forward_timestep_embed_patch.
+ """
+ SIGMA_MAX = 14.6146
+
+ def __init__(self, model_patch, project_modules, hint_latent, strength_start, strength_end):
+ self.model_patch = model_patch # CoreModelPatcher wrapping GLVControl
+ self.project_modules = project_modules # nn.ModuleList of ZeroSFT/ZeroCrossAttn
+ self.hint_latent = hint_latent # encoded LQ image latent
+ self.strength_start = strength_start
+ self.strength_end = strength_end
+ self.cached_features = None
+ self.adapter_idx = 0
+ self.control_idx = 0
+ self.current_control_idx = 0
+ self.active = True
+
+ def _ensure_features(self, kwargs):
+ """Run GLVControl on first call per step, cache results."""
+ if self.cached_features is not None:
+ return
+ x = kwargs["x"]
+ b = x.shape[0]
+ hint = self.hint_latent.to(device=x.device, dtype=x.dtype)
+ if hint.shape[0] != b:
+ hint = hint.expand(b, -1, -1, -1) if hint.shape[0] == 1 else hint.repeat((b + hint.shape[0] - 1) // hint.shape[0], 1, 1, 1)[:b]
+ self.cached_features = self.model_patch.model.control_model(
+ hint, kwargs["timesteps"], x,
+ kwargs["context"], kwargs["y"]
+ )
+ self.adapter_idx = len(self.project_modules) - 1
+ self.control_idx = len(self.cached_features) - 1
+
+ def _get_control_scale(self, kwargs):
+ if self.strength_start == self.strength_end:
+ return self.strength_end
+ sigma = kwargs["transformer_options"].get("sigmas")
+ if sigma is None:
+ return self.strength_end
+ s = sigma[0].item() if sigma.dim() > 0 else sigma.item()
+ t = min(s / self.SIGMA_MAX, 1.0)
+ return t * (self.strength_start - self.strength_end) + self.strength_end
+
+ def middle_after(self, kwargs):
+ """middle_block_after_patch: run GLVControl lazily, apply last adapter after middle block."""
+ self.cached_features = None # reset from previous step
+ self.current_scale = self._get_control_scale(kwargs)
+ self.active = self.current_scale > 0
+ if not self.active:
+ return {"h": kwargs["h"]}
+ self._ensure_features(kwargs)
+ h = kwargs["h"]
+ h = self.project_modules[self.adapter_idx](
+ self.cached_features[self.control_idx], h, control_scale=self.current_scale
+ )
+ self.adapter_idx -= 1
+ self.control_idx -= 1
+ return {"h": h}
+
+ def output_block(self, h, hsp, transformer_options):
+ """output_block_patch: ZeroSFT adapter fusion replaces cat([h, hsp]). Returns (h, None) to skip cat."""
+ if not self.active:
+ return h, hsp
+ self.current_control_idx = self.control_idx
+ h = self.project_modules[self.adapter_idx](
+ self.cached_features[self.control_idx], hsp, h, control_scale=self.current_scale
+ )
+ self.adapter_idx -= 1
+ self.control_idx -= 1
+ return h, None
+
+ def pre_upsample(self, layer, x, emb, context, transformer_options, output_shape, *args, **kw):
+ """forward_timestep_embed_patch for Upsample: extra cross-attn adapter before upsample."""
+ block_type, _ = transformer_options["block"]
+ if block_type == "output" and self.active and self.cached_features is not None:
+ x = self.project_modules[self.adapter_idx](
+ self.cached_features[self.current_control_idx], x, control_scale=self.current_scale
+ )
+ self.adapter_idx -= 1
+ return layer(x, output_shape=output_shape)
+
+ def to(self, device_or_dtype):
+ if isinstance(device_or_dtype, torch.device):
+ self.cached_features = None
+ if self.hint_latent is not None:
+ self.hint_latent = self.hint_latent.to(device_or_dtype)
+ return self
+
+ def models(self):
+ return [self.model_patch]
+
+ def register(self, model_patcher):
+ """Register all patches on a cloned model patcher."""
+ model_patcher.set_model_patch(self.middle_after, "middle_block_after_patch")
+ model_patcher.set_model_output_block_patch(self.output_block)
+ model_patcher.set_model_patch((Upsample, self.pre_upsample), "forward_timestep_embed_patch")
diff --git a/ComfyUI/comfy/ldm/triposplat/__pycache__/gaussian.cpython-312.pyc b/ComfyUI/comfy/ldm/triposplat/__pycache__/gaussian.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..534abd5ede104f9e2ba4134cf16b805b05f09a0c
Binary files /dev/null and b/ComfyUI/comfy/ldm/triposplat/__pycache__/gaussian.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/triposplat/__pycache__/model.cpython-312.pyc b/ComfyUI/comfy/ldm/triposplat/__pycache__/model.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..144047c568cf3e3ff1d35fc749f4cade6d05e8c7
Binary files /dev/null and b/ComfyUI/comfy/ldm/triposplat/__pycache__/model.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/triposplat/__pycache__/vae.cpython-312.pyc b/ComfyUI/comfy/ldm/triposplat/__pycache__/vae.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..4da6deffd2e8ba5f010f491e314b4f9c2664bf7b
Binary files /dev/null and b/ComfyUI/comfy/ldm/triposplat/__pycache__/vae.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/triposplat/gaussian.py b/ComfyUI/comfy/ldm/triposplat/gaussian.py
new file mode 100644
index 0000000000000000000000000000000000000000..a4cd2f62fc8fe6c868db2e23d21924532df7900b
--- /dev/null
+++ b/ComfyUI/comfy/ldm/triposplat/gaussian.py
@@ -0,0 +1,199 @@
+# TripoSplat 3D gaussian container. Operates on already-decoded
+# tensors and exposes them as render-ready tensors (render_tensors) for the generic SPLAT type.
+import torch
+import torch.nn.functional as F
+
+import comfy.model_management
+
+
+class GaussianModel:
+ def __init__(self, aabb: list, sh_degree: int = 0, mininum_kernel_size: float = 0.0,
+ scaling_bias: float = 0.01, opacity_bias: float = 0.1,
+ scaling_activation: str = "exp", device=None):
+ self.sh_degree = sh_degree
+ self.mininum_kernel_size = mininum_kernel_size
+ self.scaling_bias = scaling_bias
+ self.opacity_bias = opacity_bias
+ self.device = device
+ self.aabb = torch.tensor(aabb, dtype=torch.float32, device=device)
+
+ if scaling_activation == "exp":
+ self._scaling_activation = torch.exp
+ self._inverse_scaling_activation = torch.log
+ elif scaling_activation == "softplus":
+ self._scaling_activation = F.softplus
+ self._inverse_scaling_activation = lambda x: x + torch.log(-torch.expm1(-x))
+
+ self._opacity_activation = torch.sigmoid
+ self._inverse_opacity_activation = lambda x: torch.log(x / (1 - x))
+
+ self.scale_bias = self._inverse_scaling_activation(torch.tensor(self.scaling_bias)).to(self.device)
+ self.rots_bias = torch.zeros(4, device=self.device)
+ self.rots_bias[0] = 1
+ self.opacity_bias_val = self._inverse_opacity_activation(torch.tensor(self.opacity_bias)).to(self.device)
+
+ self._storage = {}
+
+ def _get_store(self, name):
+ return self._storage.get(name)
+
+ def _set_store(self, name, value):
+ self._storage[name] = value
+
+ @property
+ def _xyz(self):
+ return self._get_store("_xyz")
+ @_xyz.setter
+ def _xyz(self, value):
+ if value is None:
+ self._set_store("_xyz", None)
+ self._set_store("xyz", None)
+ return
+ self._set_store("_xyz", value)
+ self._set_store("xyz", value * self.aabb[None, 3:] + self.aabb[None, :3])
+
+ @property
+ def get_xyz(self):
+ return self._get_store("xyz")
+
+ @property
+ def _features_dc(self):
+ return self._get_store("_features_dc")
+ @_features_dc.setter
+ def _features_dc(self, value):
+ self._set_store("_features_dc", value)
+
+ @property
+ def _opacity(self):
+ return self._get_store("_opacity")
+ @_opacity.setter
+ def _opacity(self, value):
+ if value is None:
+ self._set_store("_opacity", None)
+ self._set_store("opacity", None)
+ return
+ self._set_store("_opacity", value)
+ self._set_store("opacity", self._opacity_activation(value + self.opacity_bias_val))
+
+ @property
+ def get_opacity(self):
+ return self._get_store("opacity")
+
+ @property
+ def _scaling(self):
+ return self._get_store("_scaling")
+ @_scaling.setter
+ def _scaling(self, value):
+ if value is None:
+ self._set_store("_scaling", None)
+ self._set_store("scaling", None)
+ return
+ self._set_store("_scaling", value)
+ s = self._scaling_activation(value + self.scale_bias)
+ s = torch.square(s) + self.mininum_kernel_size ** 2
+ self._set_store("scaling", torch.sqrt(s))
+
+ @property
+ def get_scaling(self):
+ return self._get_store("scaling")
+
+ @property
+ def _rotation(self):
+ return self._get_store("_rotation")
+ @_rotation.setter
+ def _rotation(self, value):
+ self._set_store("_rotation", value)
+
+ _DEFAULT_TRANSFORM = [[1, 0, 0], [0, 0, -1], [0, 1, 0]]
+
+ def render_tensors(self):
+ # Render-ready (activated, world-space) tensors for the generic SPLAT type. The axis transform
+ # (a 3x3 rotation, object frame -> viewer Y-up) is baked into positions and rotations.
+ # Returns float tensors on the intermediate device: positions (N,3), scales (N,3) linear,
+ # rotations (N,4) wxyz, opacities (N,1) in [0,1], sh (N,K,3) coefficients.
+ xyz = self.get_xyz.float()
+ scaling = self.get_scaling.float()
+ opacity = self.get_opacity.float()
+ rotation = (self._rotation + self.rots_bias[None, :]).float()
+ sh = self._features_dc.float() # (N, K, 3)
+ T = torch.as_tensor(self._DEFAULT_TRANSFORM, dtype=torch.float32, device=xyz.device)
+ xyz = xyz @ T.T
+ rotation = _matrix_to_quat(torch.matmul(T, _quat_to_matrix(rotation)))
+ rotation = rotation / torch.linalg.norm(rotation, dim=-1, keepdim=True)
+ out_device = comfy.model_management.intermediate_device()
+ return (
+ xyz.to(out_device).contiguous(), scaling.to(out_device).contiguous(),
+ rotation.to(out_device).contiguous(), opacity.to(out_device).contiguous(),
+ sh.to(out_device).contiguous(),
+ )
+
+
+def _quat_to_matrix(q):
+ q = q / torch.linalg.norm(q, dim=-1, keepdim=True)
+ w, x, y, z = q[:, 0], q[:, 1], q[:, 2], q[:, 3]
+ R = torch.stack([
+ 1 - 2*(y*y + z*z), 2*(x*y - w*z), 2*(x*z + w*y),
+ 2*(x*y + w*z), 1 - 2*(x*x + z*z), 2*(y*z - w*x),
+ 2*(x*z - w*y), 2*(y*z + w*x), 1 - 2*(x*x + y*y),
+ ], dim=-1).reshape(-1, 3, 3)
+ return R
+
+
+def _matrix_to_quat(R):
+ trace = R[:, 0, 0] + R[:, 1, 1] + R[:, 2, 2]
+ q = torch.zeros((R.shape[0], 4), dtype=R.dtype, device=R.device)
+ s = torch.sqrt(torch.clamp(trace + 1, min=0)) * 2
+ q[:, 0] = 0.25 * s
+ denom = torch.where(s != 0, s, torch.ones_like(s))
+ q[:, 1] = (R[:, 2, 1] - R[:, 1, 2]) / denom
+ q[:, 2] = (R[:, 0, 2] - R[:, 2, 0]) / denom
+ q[:, 3] = (R[:, 1, 0] - R[:, 0, 1]) / denom
+ m01 = (R[:, 0, 0] >= R[:, 1, 1]) & (R[:, 0, 0] >= R[:, 2, 2]) & (s == 0)
+ s1 = torch.sqrt(torch.clamp(1 + R[:, 0, 0] - R[:, 1, 1] - R[:, 2, 2], min=0)) * 2
+ q[m01, 0] = (R[m01, 2, 1] - R[m01, 1, 2]) / s1[m01]
+ q[m01, 1] = 0.25 * s1[m01]
+ q[m01, 2] = (R[m01, 0, 1] + R[m01, 1, 0]) / s1[m01]
+ q[m01, 3] = (R[m01, 0, 2] + R[m01, 2, 0]) / s1[m01]
+ m11 = (R[:, 1, 1] > R[:, 0, 0]) & (R[:, 1, 1] >= R[:, 2, 2]) & (s == 0)
+ s2 = torch.sqrt(torch.clamp(1 + R[:, 1, 1] - R[:, 0, 0] - R[:, 2, 2], min=0)) * 2
+ q[m11, 0] = (R[m11, 0, 2] - R[m11, 2, 0]) / s2[m11]
+ q[m11, 1] = (R[m11, 0, 1] + R[m11, 1, 0]) / s2[m11]
+ q[m11, 2] = 0.25 * s2[m11]
+ q[m11, 3] = (R[m11, 1, 2] + R[m11, 2, 1]) / s2[m11]
+ m21 = (R[:, 2, 2] > R[:, 0, 0]) & (R[:, 2, 2] > R[:, 1, 1]) & (s == 0)
+ s3 = torch.sqrt(torch.clamp(1 + R[:, 2, 2] - R[:, 0, 0] - R[:, 1, 1], min=0)) * 2
+ q[m21, 0] = (R[m21, 1, 0] - R[m21, 0, 1]) / s3[m21]
+ q[m21, 1] = (R[m21, 0, 2] + R[m21, 2, 0]) / s3[m21]
+ q[m21, 2] = (R[m21, 1, 2] + R[m21, 2, 1]) / s3[m21]
+ q[m21, 3] = 0.25 * s3[m21]
+ return q / torch.linalg.norm(q, dim=-1, keepdim=True)
+
+
+def build_gaussian_models(decoder, points_pred: dict, pred: dict):
+ # Assemble GaussianModels from the elastic decoder layout. decoder is the ElasticGaussianFixedlenDecoder
+ # (carries layout / rep_config / _get_offset)
+ x = points_pred
+ offset = decoder._get_offset(pred['features'])
+ h = pred["features"]
+ ret = []
+ for i in range(h.shape[0]):
+ g = GaussianModel(
+ sh_degree=0,
+ aabb=[-0.5, -0.5, -0.5, 1.0, 1.0, 1.0],
+ mininum_kernel_size=decoder.rep_config['filter_kernel_size_3d'],
+ scaling_bias=decoder.rep_config['scaling_bias'],
+ opacity_bias=decoder.rep_config['opacity_bias'],
+ scaling_activation=decoder.rep_config['scaling_activation'],
+ device=h.device,
+ )
+ _x = x["points"][i, :, None, :]
+ for k, v in decoder.layout.items():
+ if k == '_xyz':
+ setattr(g, k, (offset[i] + _x).flatten(0, 1))
+ elif k in ('_xyz_center', '_offset_scale'):
+ continue
+ else:
+ feats = h[i][:, v['range'][0]:v['range'][1]].reshape(-1, *v['shape']).flatten(0, 1)
+ setattr(g, k, feats * decoder.rep_config['lr'][k])
+ ret.append(g)
+ return ret
diff --git a/ComfyUI/comfy/ldm/triposplat/model.py b/ComfyUI/comfy/ldm/triposplat/model.py
new file mode 100644
index 0000000000000000000000000000000000000000..d8a531772d49195d628f73f441aa6be0dfc4da02
--- /dev/null
+++ b/ComfyUI/comfy/ldm/triposplat/model.py
@@ -0,0 +1,326 @@
+# TripoSplat flow-matching denoiser (LatentSeqMMFlowModel). Registered as a ModelType.FLOW arch and
+# driven by the standard KSampler; jointly denoises the (B, 8192, 16) latent and a (B, 1, 5) camera token
+# carried as a 2-element nested latent.
+import numpy as np
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+
+import comfy.model_management
+import comfy.patcher_extension
+import comfy.rmsnorm
+from comfy.ldm.modules.attention import optimized_attention
+from comfy.ldm.flux.math import apply_rope
+
+
+class MultiHeadRMSNorm(nn.Module):
+ def __init__(self, dim, heads, dtype=None, device=None):
+ super().__init__()
+ self.gamma = nn.Parameter(torch.empty(heads, dim, dtype=dtype, device=device))
+
+ def forward(self, x):
+ x = comfy.rmsnorm.rms_norm(x)
+ return x * comfy.model_management.cast_to(self.gamma, x.dtype, x.device)
+
+
+# Positional embeddings
+
+class RePo3DRotaryEmbedding(nn.Module):
+ def __init__(self, model_channels, num_heads, head_dim, repo_hidden_ratio=0.125, max_freq=16.0,
+ dtype=None, device=None, operations=None):
+ super().__init__()
+ self.num_heads = num_heads
+ self.head_dim = head_dim
+ repo_hidden_size = int(model_channels * repo_hidden_ratio)
+ self.norm = operations.LayerNorm(model_channels, dtype=dtype, device=device)
+ self.gate_map = operations.Linear(model_channels, repo_hidden_size, bias=False, dtype=dtype, device=device)
+ self.content_map = operations.Linear(model_channels, repo_hidden_size, bias=False, dtype=dtype, device=device)
+ self.act = nn.SiLU()
+ self.final_map = operations.Linear(repo_hidden_size, 3 * num_heads, bias=False, dtype=dtype, device=device)
+ self.dim_0 = 2 * (head_dim // 6)
+ self.dim_1 = 2 * (head_dim // 6)
+ self.dim_2 = head_dim - self.dim_0 - self.dim_1
+ dims = [self.dim_0, self.dim_1, self.dim_2]
+ freqs_list = []
+ for d in dims:
+ freq_dim = d // 2
+ freqs_list.append(torch.linspace(1.0, float(max_freq), steps=freq_dim, dtype=torch.float32))
+ self.freqs_0 = nn.Parameter(freqs_list[0])
+ self.freqs_1 = nn.Parameter(freqs_list[1])
+ self.freqs_2 = nn.Parameter(freqs_list[2])
+
+ def forward(self, hidden_states):
+ h = self.norm(hidden_states)
+ feat = self.act(self.gate_map(h)) * self.content_map(h)
+ out = self.final_map(feat)
+ B, L, _ = out.shape
+ delta_pos = out.reshape(B, L, self.num_heads, 3)
+ f0 = comfy.model_management.cast_to(self.freqs_0, torch.float32, out.device)
+ f1 = comfy.model_management.cast_to(self.freqs_1, torch.float32, out.device)
+ f2 = comfy.model_management.cast_to(self.freqs_2, torch.float32, out.device)
+ ang_0 = delta_pos[..., 0].unsqueeze(-1) * f0 * torch.pi
+ ang_1 = delta_pos[..., 1].unsqueeze(-1) * f1 * torch.pi
+ ang_2 = delta_pos[..., 2].unsqueeze(-1) * f2 * torch.pi
+ ang = torch.cat([ang_0, ang_1, ang_2], dim=-1).float() # (B, L, heads, head_dim/2)
+ cos, sin = ang.cos(), ang.sin()
+ return torch.stack([cos, -sin, sin, cos], dim=-1).reshape(*ang.shape, 2, 2)
+
+
+class PcdAbsolutePositionEmbedder(nn.Module):
+ # Sinusoidal absolute position embedding. Two fixed schedules are used in TripoSplat:
+ # "pow2" (flow-model latent anchors) and "log2" (octree / gaussian decoders).
+ def __init__(self, channels: int, in_channels: int = 3, max_res: int = 16, schedule: str = "pow2"):
+ super().__init__()
+ self.channels = channels
+ self.in_channels = in_channels
+ self.max_res = max_res
+ self.schedule = schedule
+ self.freq_dim = channels // in_channels // 2
+
+ def _freqs(self, device):
+ if self.schedule == "pow2":
+ freqs_2exp = torch.arange(self.max_res, dtype=torch.float32, device=device)
+ res_dim = max(0, self.freq_dim - self.max_res)
+ freqs_res = (torch.arange(res_dim, dtype=torch.float32, device=device) / max(res_dim, 1) * self.max_res
+ if res_dim > 0 else torch.empty(0, device=device))
+ freqs = torch.cat([freqs_2exp, freqs_res], dim=0)[:self.freq_dim]
+ return torch.pow(2.0, freqs) * 2.0 # *2 folds this schedule's 2*pi into the shared *pi below
+ logs = torch.linspace(0.0, float(self.max_res), steps=self.freq_dim, dtype=torch.float32, device=device)
+ return torch.pow(2.0, logs)
+
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
+ orig_dtype = x.dtype
+ x = x.float()
+ *dims, D = x.shape
+ out = torch.outer(x.reshape(-1), self._freqs(x.device)) * torch.pi
+ out = torch.cat([out.sin(), out.cos()], dim=-1).reshape(*dims, -1)
+ if out.shape[-1] < self.channels:
+ out = torch.cat([out, torch.zeros(*dims, self.channels - out.shape[-1],
+ device=out.device, dtype=out.dtype)], dim=-1)
+ return out.to(orig_dtype)
+
+
+def attention(q, k, v, transformer_options=None):
+ # q, k, v: (B, L, heads, dim) -> (B, L, heads, dim). Shared optimized_attention call convention.
+ out = optimized_attention(q.transpose(1, 2), k.transpose(1, 2), v.transpose(1, 2), heads=q.shape[2],
+ skip_reshape=True, skip_output_reshape=True, low_precision_attention=False,
+ transformer_options=transformer_options)
+ return out.transpose(1, 2)
+
+
+# Transformer building blocks
+
+class MLP(nn.Module):
+ def __init__(self, in_channels, hidden_channels, out_channels, dtype=None, device=None, operations=None):
+ super().__init__()
+ self.mlp = nn.Sequential(
+ operations.Linear(in_channels, hidden_channels, dtype=dtype, device=device),
+ nn.GELU(approximate="tanh"),
+ operations.Linear(hidden_channels, out_channels, dtype=dtype, device=device),
+ )
+
+ def forward(self, x):
+ return self.mlp(x)
+
+
+class RopeMultiHeadAttention(nn.Module):
+ def __init__(self, channels, num_heads, qkv_bias=True, qk_rms_norm=False, use_rope=False,
+ dtype=None, device=None, operations=None):
+ super().__init__()
+ self.channels = channels
+ self.num_heads = num_heads
+ self.head_dim = channels // num_heads
+ self.qk_rms_norm = qk_rms_norm
+ self.use_rope = use_rope
+ self.qkv = operations.Linear(channels, channels * 3, bias=qkv_bias, dtype=dtype, device=device)
+ if self.qk_rms_norm:
+ self.q_norm = MultiHeadRMSNorm(self.head_dim, num_heads, dtype=dtype, device=device)
+ self.k_norm = MultiHeadRMSNorm(self.head_dim, num_heads, dtype=dtype, device=device)
+ self.out = operations.Linear(channels, channels, dtype=dtype, device=device)
+
+ def forward(self, x, rope_emb=None, transformer_options=None):
+ B, L, C = x.shape
+ qkv = self.qkv(x).reshape(B, L, 3, self.num_heads, self.head_dim)
+ q, k, v = qkv.unbind(2)
+ if self.use_rope:
+ q, k = apply_rope(q, k, rope_emb)
+ if self.qk_rms_norm:
+ q = self.q_norm(q)
+ k = self.k_norm(k)
+ h = attention(q, k, v, transformer_options) # (B, L, heads, dim)
+ return self.out(h.reshape(B, L, C))
+
+
+class UnifiedTransformerBlock(nn.Module):
+ def __init__(self, channels, num_heads, mlp_ratio=4.0,
+ use_rope=False, qk_rms_norm=False, qkv_bias=True,
+ modulation=True, share_mod=False,
+ dtype=None, device=None, operations=None):
+ super().__init__()
+ self.modulation = modulation
+ self.share_mod = share_mod
+ self.norm1 = operations.LayerNorm(channels, elementwise_affine=not modulation, eps=1e-6, dtype=dtype, device=device)
+ self.norm2 = operations.LayerNorm(channels, elementwise_affine=not modulation, eps=1e-6, dtype=dtype, device=device)
+ self.attn = RopeMultiHeadAttention(channels, num_heads=num_heads,
+ qkv_bias=qkv_bias, use_rope=use_rope, qk_rms_norm=qk_rms_norm,
+ dtype=dtype, device=device, operations=operations)
+ self.mlp = MLP(channels, int(channels * mlp_ratio), channels, dtype=dtype, device=device, operations=operations)
+ if modulation:
+ if not share_mod:
+ self.adaLN_modulation = nn.Sequential(
+ nn.SiLU(), operations.Linear(channels, 6 * channels, bias=True, dtype=dtype, device=device))
+ self.shift_table = nn.Parameter(torch.empty(1, 6 * channels, dtype=dtype, device=device))
+
+ def forward(self, x, mod=None, rotary_emb=None, transformer_options=None):
+ if self.modulation:
+ if not self.share_mod:
+ mod = self.adaLN_modulation(mod)
+ mod = mod + comfy.model_management.cast_to(self.shift_table, mod.dtype, mod.device)
+ shift_msa, scale_msa, gate_msa, shift_mlp, scale_mlp, gate_mlp = mod.chunk(6, dim=1)
+ h = torch.addcmul(shift_msa.unsqueeze(1), self.norm1(x), 1 + scale_msa.unsqueeze(1))
+ x = torch.addcmul(x, self.attn(h, rope_emb=rotary_emb, transformer_options=transformer_options), gate_msa.unsqueeze(1))
+ h = torch.addcmul(shift_mlp.unsqueeze(1), self.norm2(x), 1 + scale_mlp.unsqueeze(1))
+ x = torch.addcmul(x, self.mlp(h), gate_mlp.unsqueeze(1))
+ else:
+ x = x + self.attn(self.norm1(x), rope_emb=rotary_emb, transformer_options=transformer_options)
+ x = x + self.mlp(self.norm2(x))
+ return x
+
+
+class TimestepEmbedder(nn.Module):
+ def __init__(self, hidden_size, frequency_embedding_size=256, dtype=None, device=None, operations=None):
+ super().__init__()
+ self.mlp = nn.Sequential(
+ operations.Linear(frequency_embedding_size, hidden_size, bias=True, dtype=dtype, device=device),
+ nn.SiLU(),
+ operations.Linear(hidden_size, hidden_size, bias=True, dtype=dtype, device=device),
+ )
+ self.frequency_embedding_size = frequency_embedding_size
+
+ @staticmethod
+ def timestep_embedding(t, dim, max_period=10000):
+ half = dim // 2
+ freqs = torch.exp(-np.log(max_period) * torch.arange(start=0, end=half, dtype=torch.float32) / half).to(device=t.device)
+ args = t[:, None].float() * freqs[None]
+ embedding = torch.cat([torch.cos(args), torch.sin(args)], dim=-1)
+ if dim % 2:
+ embedding = torch.cat([embedding, torch.zeros_like(embedding[:, :1])], dim=-1)
+ return embedding
+
+ def forward(self, t):
+ emb = self.timestep_embedding(t, self.frequency_embedding_size)
+ return self.mlp(emb.to(self.mlp[0].weight.dtype))
+
+
+class LatentSeqMMFlowModel(nn.Module):
+ def __init__(self, image_model=None, q_token_length=8192, in_channels=16, model_channels=1024,
+ cond_channels=1280, out_channels=16, num_blocks=24, num_refiner_blocks=2,
+ num_heads=None, num_head_channels=64, cam_channels=5, cond2_channels=128,
+ mlp_ratio=4, share_mod=True, qk_rms_norm=True,
+ dtype=None, device=None, operations=None, **kwargs):
+ super().__init__()
+ self.dtype = dtype
+ self.q_token_length = q_token_length
+ self.in_channels = in_channels
+ self.cam_channels = cam_channels
+ self.model_channels = model_channels
+ self.cond_channels = cond_channels
+ self.cond2_channels = cond2_channels
+ self.out_channels = out_channels
+ self.num_blocks = num_blocks
+ self.num_refiner_blocks = num_refiner_blocks
+ self.num_heads = num_heads or model_channels // num_head_channels
+ self.mlp_ratio = mlp_ratio
+ self.share_mod = share_mod
+ self.qk_rms_norm = qk_rms_norm
+
+ factory_kwargs = dict(dtype=dtype, device=device)
+ op_kwargs = dict(operations=operations, **factory_kwargs)
+
+ self.t_embedder = TimestepEmbedder(model_channels, **op_kwargs)
+ if share_mod:
+ self.adaLN_modulation = nn.Sequential(nn.SiLU(), operations.Linear(model_channels, 6 * model_channels, bias=True, **factory_kwargs))
+
+ self.input_layer = operations.Linear(in_channels, model_channels, **factory_kwargs)
+ self.cond_embedder = operations.Linear(cond_channels, model_channels, **factory_kwargs)
+ self.cond_embedder2 = operations.Linear(cond2_channels, model_channels, **factory_kwargs) if cond2_channels is not None else None
+
+ # Fixed Sobol (low-discrepancy) 3D anchor positions for the latent tokens, used as positional encoding.
+ # The embedder is parameter-free and the anchors are fixed, precompute once.
+ sobol_seq = torch.quasirandom.SobolEngine(dimension=3, scramble=True, seed=123).draw(q_token_length)
+ pos_emb = PcdAbsolutePositionEmbedder(model_channels)(sobol_seq.unsqueeze(0))
+ self.register_buffer("pos_emb", pos_emb, persistent=False)
+
+ # RePo3DRotaryEmbedding layers for the refiner and main blocks
+ repo_kwargs = dict(num_heads=self.num_heads, head_dim=num_head_channels, **op_kwargs)
+ self.noise_repo_layers = nn.ModuleList(
+ [RePo3DRotaryEmbedding(model_channels, **repo_kwargs) for _ in range(num_refiner_blocks)])
+ self.context_repo_layers = nn.ModuleList(
+ [RePo3DRotaryEmbedding(model_channels, **repo_kwargs) for _ in range(num_refiner_blocks)])
+ self.repo_layers = nn.ModuleList(
+ [RePo3DRotaryEmbedding(model_channels, **repo_kwargs) for _ in range(num_blocks)])
+
+ # Refiner blocks
+ block_kwargs = dict(num_heads=self.num_heads, mlp_ratio=self.mlp_ratio, use_rope=True, qk_rms_norm=self.qk_rms_norm, **op_kwargs)
+ self.noise_refiner = nn.ModuleList(
+ [UnifiedTransformerBlock(model_channels, modulation=True, share_mod=self.share_mod, **block_kwargs) for _ in range(num_refiner_blocks)])
+ self.context_refiner = nn.ModuleList(
+ [UnifiedTransformerBlock(model_channels, modulation=False, **block_kwargs) for _ in range(num_refiner_blocks)])
+
+ self.cam_refiner = MLP(self.cam_channels, model_channels, model_channels, **op_kwargs)
+
+ self.blocks = nn.ModuleList(
+ [UnifiedTransformerBlock(model_channels, modulation=True, share_mod=self.share_mod, **block_kwargs) for _ in range(num_blocks)])
+
+ self.shift_table = nn.Parameter(torch.empty(1, 2, model_channels, **factory_kwargs))
+ self.out_layer = operations.Linear(model_channels, out_channels, **factory_kwargs)
+ self.cam_out_layer = operations.Linear(model_channels, cam_channels, **factory_kwargs)
+
+ def forward(self, x, t, context=None, ref_latents=None, transformer_options={}, **kwargs):
+ return comfy.patcher_extension.WrapperExecutor.new_class_executor(
+ self._forward,
+ self,
+ comfy.patcher_extension.get_all_wrappers(comfy.patcher_extension.WrappersMP.DIFFUSION_MODEL, transformer_options)
+ ).execute(x, t, context, ref_latents, transformer_options, **kwargs)
+
+ def _forward(self, x, t, context=None, ref_latents=None, transformer_options={}, **kwargs):
+ # x is the unpacked nested latent: [latent (B,8192,in_channels), camera (B,1,cam_channels)].
+ # context == feature1.
+ z, camera = x[0], x[1]
+ feat1 = context
+
+ h_x = self.input_layer(z)
+ h_cond = self.cond_embedder(feat1)
+ if ref_latents is not None and self.cond_embedder2 is not None:
+ # Flatten the Flux2 VAE latent (B,128,h,w) to a token sequence and front-pad to feat1's length
+ # (the pad count = feat1's prefix tokens: DINOv3 cls + registers), then add to the context.
+ feat2 = ref_latents[0].flatten(2).transpose(1, 2)
+ feat2 = F.pad(feat2, (0, 0, feat1.shape[1] - feat2.shape[1], 0))
+ h_cond = h_cond + self.cond_embedder2(feat2.to(h_cond.dtype))
+ t_emb = self.t_embedder(t)
+ t_mod = self.adaLN_modulation(t_emb) if self.share_mod else t_emb
+
+ h_x = h_x + self.pos_emb.to(z)
+
+ for i, block in enumerate(self.noise_refiner):
+ h_x = block(h_x, mod=t_mod, rotary_emb=self.noise_repo_layers[i](h_x), transformer_options=transformer_options)
+
+ for i, block in enumerate(self.context_refiner):
+ h_cond = block(h_cond, mod=None, rotary_emb=self.context_repo_layers[i](h_cond), transformer_options=transformer_options)
+
+ cam = camera.to(z)
+ h_cam = self.cam_refiner(cam)
+ h = torch.cat([h_x, h_cond, h_cam], dim=1)
+
+ for i, block in enumerate(self.blocks):
+ h = block(h, mod=t_mod, rotary_emb=self.repo_layers[i](h), transformer_options=transformer_options)
+
+ h_x = F.layer_norm(h[:, :z.shape[1]].float(), h.shape[-1:]).to(z)
+ h_cam = F.layer_norm(h[:, -cam.shape[1]:].float(), h.shape[-1:]).to(z)
+
+ shift, scale = (comfy.model_management.cast_to(self.shift_table, t_emb.dtype, t_emb.device) + t_emb.unsqueeze(1)).chunk(2, dim=1)
+ scale = 1 + scale
+ h_x = torch.addcmul(shift, h_x, scale)
+ h_cam = torch.addcmul(shift, h_cam, scale)
+
+ return self.out_layer(h_x), self.cam_out_layer(h_cam)
diff --git a/ComfyUI/comfy/ldm/triposplat/preview.py b/ComfyUI/comfy/ldm/triposplat/preview.py
new file mode 100644
index 0000000000000000000000000000000000000000..6a942bb53b09312131644bd3ddbf4f05a29993ca
--- /dev/null
+++ b/ComfyUI/comfy/ldm/triposplat/preview.py
@@ -0,0 +1,91 @@
+# Live preview for TripoSplat: decode an x0 estimate into a coarse gaussian splat and render it with a perspective orbit camera.
+import numpy as np
+from PIL import Image
+
+_C0 = 0.28209479177387814
+_LATENT_TOKENS = 8192 # q_token_length
+_LATENT_CH = 16 # in_channels
+_OBJECT_TO_VIEWER = np.array([[1, 0, 0], [0, 0, -1], [0, 1, 0]], np.float32) # object frame -> viewer Y-up frame
+
+
+def _view_matrix(yaw_deg, pitch_deg):
+ y, p = np.radians(yaw_deg), np.radians(pitch_deg)
+ Ry = np.array([[np.cos(y), 0, np.sin(y)], [0, 1, 0], [-np.sin(y), 0, np.cos(y)]], np.float32)
+ Rx = np.array([[1, 0, 0], [0, np.cos(p), -np.sin(p)], [0, np.sin(p), np.cos(p)]], np.float32)
+ return Rx @ Ry
+
+
+def render_splat(xyz, rgb, scale, opacity=None, yaw=35.0, pitch=30.0, size=320, min_px=2, gain=1.0,
+ max_px=9, min_opacity=0.0, fov=35.0, dist=2.2):
+ # Project gaussian centers with a perspective camera and paint each as a filled disk whose screen
+ # radius follows the gaussian's world-space scale, composited with a nearest-wins z-buffer.
+ # gain scales the footprint (≈ std spanned), `min_px`/`max_px` clamp the on-screen radius.
+
+ pts = xyz.astype(np.float32) @ _OBJECT_TO_VIEWER.T
+ v = pts @ _view_matrix(yaw, pitch).T
+ zc = v[:, 2] + dist
+ keep = zc > 1e-2
+ if opacity is not None and min_opacity > 0.0: # culls gaussians with very low opacity
+ keep = keep & (opacity > min_opacity)
+ v, zc, scale = v[keep], zc[keep], scale[keep]
+ col = (np.clip(rgb, 0, 1)[:, :3] * 255).astype(np.uint8)[keep]
+ if v.shape[0] == 0:
+ return Image.fromarray(np.zeros((size, size, 3), np.uint8))
+ f = (size / 2) / np.tan(np.radians(fov) / 2)
+ cx = size / 2 + f * v[:, 0] / zc
+ cy = size / 2 + f * v[:, 1] / zc
+ radius = np.clip(np.round(f * scale / zc * gain), min_px, max_px).astype(np.int32)
+
+ # Expand each splat to its disk pixels, bucketed by integer radius so it stays vectorized.
+ px, py, pz, pc = [], [], [], []
+ for r in range(int(radius.min()), int(radius.max()) + 1):
+ m = radius == r
+ if not m.any():
+ continue
+ dy, dx = np.mgrid[-r:r + 1, -r:r + 1]
+ disk = (dx * dx + dy * dy) <= r * r
+ ox, oy = dx[disk], dy[disk]
+ px.append((cx[m, None] + ox).ravel())
+ py.append((cy[m, None] + oy).ravel())
+ pz.append(np.repeat(zc[m], ox.size))
+ pc.append(np.repeat(col[m], ox.size, axis=0))
+ px, py = np.concatenate(px), np.concatenate(py)
+ pz, pc = np.concatenate(pz), np.concatenate(pc)
+ xi = np.clip(px, 0, size - 1).astype(np.int64)
+ yi = np.clip(py, 0, size - 1).astype(np.int64)
+
+ # Nearest-wins z-buffer: pack (quantized depth, source index), per-pixel min picks the closest
+ # splat, then decode the winning index back to its color.
+ pid = yi * size + xi
+ q = np.clip((pz * 1024.0).astype(np.int64), 0, (1 << 20) - 1) # near = small
+ key = (q << 32) | np.arange(pid.size, dtype=np.int64)
+ buf = np.full(size * size, 1 << 62, np.int64)
+ np.minimum.at(buf, pid, key)
+ img = np.zeros((size * size, 3), np.uint8)
+ hit = buf < (1 << 62)
+ img[hit] = pc[buf[hit] & 0xFFFFFFFF]
+ return Image.fromarray(img.reshape(size, size, 3))
+
+
+def _extract_latent(x0):
+ # x0 from the sampler callback is the nested latent packed to (B, 1, TOKENS*CH + 1*5);
+ # the plain single-latent case is (B, TOKENS, CH). Return the (B, TOKENS, CH) latent stream.
+ if x0.ndim == 3 and x0.shape[1] == _LATENT_TOKENS and x0.shape[2] == _LATENT_CH:
+ return x0
+ flat = x0.reshape(x0.shape[0], -1)
+ return flat[:, :_LATENT_TOKENS * _LATENT_CH].reshape(x0.shape[0], _LATENT_TOKENS, _LATENT_CH)
+
+
+def decode_x0_to_image(decoder, x0, cfg):
+ # Decode x0 at a coarse octree level / few gaussians and render a preview image.
+ latent = _extract_latent(x0)
+ fsm = decoder.first_stage_model
+ gaussian = fsm.decode(latent.to(decoder.device, decoder.vae_dtype),
+ num_gaussians=cfg.get("gaussians", 16384), level=cfg.get("level", 5))[0]
+ xyz = gaussian.get_xyz.float().cpu().numpy()
+ rgb = gaussian._features_dc.float().cpu().numpy()[:, 0, :] * _C0 + 0.5
+ scale = gaussian.get_scaling.float().cpu().numpy().max(axis=1) # per-splat world radius (largest axis)
+ opacity = gaussian.get_opacity.float().cpu().numpy()[:, 0]
+ return render_splat(xyz, rgb, scale, opacity=opacity, yaw=cfg.get("yaw", 35.0), pitch=cfg.get("pitch", 30.0),
+ size=cfg.get("size", 320), min_px=1, gain=1.0, max_px=cfg.get("point_size", 3),
+ min_opacity=0.01)
diff --git a/ComfyUI/comfy/ldm/triposplat/vae.py b/ComfyUI/comfy/ldm/triposplat/vae.py
new file mode 100644
index 0000000000000000000000000000000000000000..e5ed9fd36f11dcc083af9e41c507fcb976682905
--- /dev/null
+++ b/ComfyUI/comfy/ldm/triposplat/vae.py
@@ -0,0 +1,382 @@
+# TripoSplat gaussian decoder ("VAE"): an octree probability decoder picks point coords, then an
+# elastic-gaussian decoder predicts per-point gaussian params. OctreeGaussianDecoder.decode() returns
+# a Gaussian. The octree sampler uses the global torch RNG (no generator) like upstream, so seed it for repeatable decodes.
+import numpy as np
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+
+import comfy.model_management
+import comfy.ops
+from .gaussian import build_gaussian_models
+from .model import MultiHeadRMSNorm, MLP, PcdAbsolutePositionEmbedder, attention
+
+
+# Quasi-random sampling utilities (pure functions, dtype/device-agnostic)
+
+PRIMES = [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53]
+
+
+def radical_inverse(base, n):
+ val = 0
+ inv_base = 1.0 / base
+ inv_base_n = inv_base
+ while n > 0:
+ digit = n % base
+ val += digit * inv_base_n
+ n //= base
+ inv_base_n *= inv_base
+ return val
+
+
+def halton_sequence(dim, n):
+ return [radical_inverse(PRIMES[i], n) for i in range(dim)]
+
+
+def hammersley_sequence(dim, n, num_samples):
+ return [n / num_samples] + halton_sequence(dim - 1, n)
+
+
+def sample_probs(probs, counts, generator=None):
+ # Systematic resampling: distribute counts[r] draws across the P bins of row r
+ batch_shape = counts.shape
+ R = counts.numel()
+ P = probs.size(-1)
+ device = probs.device
+ probs = probs.reshape(R, P).to(torch.float32).clamp_min(0)
+ counts = counts.reshape(R).to(device=device, dtype=torch.long)
+
+ row_sums = probs.sum(1, keepdim=True)
+ probs = torch.where(row_sums == 0, probs.new_tensor(1.0 / P), probs / row_sums.clamp_min(1))
+ cdf = probs.cumsum(dim=1).clamp(max=1.0 - 1e-12)
+
+ Nmax = int(counts.max())
+ if Nmax == 0:
+ return counts.new_zeros(*batch_shape, P)
+ cnt = counts.clamp_min(1).float().unsqueeze(1) # (R, 1)
+ grid = torch.arange(Nmax, device=device, dtype=torch.float32).unsqueeze(0) # (1, Nmax)
+ u = (torch.rand(R, 1, generator=generator).to(device) + grid) / cnt # (R, Nmax) systematic samples (CPU-seeded)
+ idx = torch.searchsorted(cdf, u.clamp(max=1.0 - 1e-12)).clamp_max(P - 1)
+ weight = (grid < counts.unsqueeze(1)).to(cdf.dtype) # mask out j >= counts[r]
+ out = torch.zeros(R, P, dtype=torch.float32, device=device)
+ out.scatter_add_(1, idx, weight)
+ return out.to(torch.long).view(*batch_shape, P)
+
+
+class MultiHeadAttention(nn.Module):
+ def __init__(self, channels, num_heads, ctx_channels=None, type="self", qkv_bias=True, qk_rms_norm=False,
+ dtype=None, device=None, operations=None):
+ super().__init__()
+ assert channels % num_heads == 0
+ self.channels = channels
+ self.head_dim = channels // num_heads
+ self.ctx_channels = ctx_channels if ctx_channels is not None else channels
+ self.num_heads = num_heads
+ self._type = type
+ self.qk_rms_norm = qk_rms_norm
+ if self._type == "self":
+ self.to_qkv = operations.Linear(channels, channels * 3, bias=qkv_bias, dtype=dtype, device=device)
+ else:
+ self.to_q = operations.Linear(channels, channels, bias=qkv_bias, dtype=dtype, device=device)
+ self.to_kv = operations.Linear(self.ctx_channels, channels * 2, bias=qkv_bias, dtype=dtype, device=device)
+ if self.qk_rms_norm:
+ self.q_rms_norm = MultiHeadRMSNorm(self.head_dim, num_heads, dtype=dtype, device=device)
+ self.k_rms_norm = MultiHeadRMSNorm(self.head_dim, num_heads, dtype=dtype, device=device)
+ self.to_out = operations.Linear(channels, channels, dtype=dtype, device=device)
+
+ def forward(self, x, context=None):
+ B, L, C = x.shape
+ if self._type == "self":
+ q, k, v = self.to_qkv(x).reshape(B, L, 3, self.num_heads, -1).unbind(dim=2)
+ else:
+ Lkv = context.shape[1]
+ q = self.to_q(x).reshape(B, L, self.num_heads, -1)
+ k, v = self.to_kv(context).reshape(B, Lkv, 2, self.num_heads, -1).unbind(dim=2)
+ if self.qk_rms_norm:
+ q = self.q_rms_norm(q)
+ k = self.k_rms_norm(k)
+ h = attention(q, k, v)
+ return self.to_out(h.reshape(B, L, -1))
+
+
+# Octree probability decoder
+
+class LevelEmbedder(nn.Module):
+ def __init__(self, hidden_size, frequency_embedding_size=256, max_period=1024,
+ dtype=None, device=None, operations=None):
+ super().__init__()
+ self.mlp = nn.Sequential(
+ operations.Linear(frequency_embedding_size, hidden_size, bias=True, dtype=dtype, device=device),
+ nn.SiLU(),
+ operations.Linear(hidden_size, hidden_size, bias=True, dtype=dtype, device=device),
+ )
+ self.frequency_embedding_size = frequency_embedding_size
+ self.max_period = max_period
+
+ @staticmethod
+ def level_embedding(t, dim, max_period=1024):
+ half = dim // 2
+ freqs = torch.exp(-np.log(max_period) * torch.arange(start=0, end=half, dtype=torch.float32) / half).to(device=t.device)
+ args = t[:, None].float() * freqs[None] * 2 * torch.pi
+ embedding = torch.cat([torch.cos(args), torch.sin(args)], dim=-1)
+ if dim % 2:
+ embedding = torch.cat([embedding, torch.zeros_like(embedding[:, :1])], dim=-1)
+ return embedding
+
+ def forward(self, t):
+ emb = self.level_embedding(t, self.frequency_embedding_size, self.max_period)
+ return self.mlp(emb.to(self.mlp[0].weight.dtype))
+
+
+class ModulatedTransformerCrossOnlyBlock(nn.Module):
+ def __init__(self, channels, ctx_channels, num_heads, mlp_ratio=4.0, share_mod=False,
+ qk_rms_norm_cross=True, qkv_bias=True, dtype=None, device=None, operations=None):
+ super().__init__()
+ self.share_mod = share_mod
+ self.norm1 = operations.LayerNorm(channels, elementwise_affine=False, eps=1e-6, dtype=dtype, device=device)
+ self.norm2 = operations.LayerNorm(channels, elementwise_affine=False, eps=1e-6, dtype=dtype, device=device)
+ self.cross_attn = MultiHeadAttention(channels, ctx_channels=ctx_channels, num_heads=num_heads,
+ type="cross", qkv_bias=qkv_bias,
+ qk_rms_norm=qk_rms_norm_cross, dtype=dtype, device=device, operations=operations)
+ self.mlp = MLP(channels, int(channels * mlp_ratio), channels, dtype=dtype, device=device, operations=operations)
+ if not share_mod:
+ self.adaLN_modulation = nn.Sequential(
+ nn.SiLU(), operations.Linear(channels, 6 * channels, bias=True, dtype=dtype, device=device))
+
+ def forward(self, x, mod, context):
+ if self.share_mod:
+ shift_msa, scale_msa, gate_msa, shift_mlp, scale_mlp, gate_mlp = mod.chunk(6, dim=1)
+ else:
+ shift_msa, scale_msa, gate_msa, shift_mlp, scale_mlp, gate_mlp = self.adaLN_modulation(mod).chunk(6, dim=1)
+ h = torch.addcmul(shift_msa.unsqueeze(1), self.norm1(x), 1 + scale_msa.unsqueeze(1))
+ x = torch.addcmul(x, self.cross_attn(h, context), gate_msa.unsqueeze(1))
+ h = torch.addcmul(shift_mlp.unsqueeze(1), self.norm2(x), 1 + scale_mlp.unsqueeze(1))
+ x = torch.addcmul(x, self.mlp(h), gate_mlp.unsqueeze(1))
+ return x
+
+
+class OctreeProbabilityFixedlenDecoder(nn.Module):
+ # Cross-attention transformer over octree coords -> per-node 8-way child occupancy logits.
+ def __init__(self, model_channels=1024, cond_channels=16, num_blocks=4, num_heads=16,
+ num_head_channels=64, mlp_ratio=4.0, share_mod=True,
+ qk_rms_norm_cross=True, dtype=None, device=None, operations=None):
+ super().__init__()
+ self.model_channels = model_channels
+ self.cond_channels = cond_channels
+ self.num_blocks = num_blocks
+ self.num_heads = num_heads or model_channels // num_head_channels
+ self.mlp_ratio = mlp_ratio
+ self.share_mod = share_mod
+ self.qk_rms_norm_cross = qk_rms_norm_cross
+ self.input_layer = operations.Linear(model_channels, model_channels, dtype=dtype, device=device)
+ self.l_embedder = LevelEmbedder(model_channels, dtype=dtype, device=device, operations=operations)
+ if share_mod:
+ self.adaLN_modulation = nn.Sequential(
+ nn.SiLU(), operations.Linear(model_channels, 6 * model_channels, bias=True, dtype=dtype, device=device))
+ if cond_channels is not None:
+ self.blocks = nn.ModuleList([
+ ModulatedTransformerCrossOnlyBlock(
+ model_channels, ctx_channels=cond_channels, num_heads=self.num_heads,
+ mlp_ratio=self.mlp_ratio, qk_rms_norm_cross=self.qk_rms_norm_cross,
+ share_mod=self.share_mod, dtype=dtype, device=device, operations=operations)
+ for _ in range(num_blocks)
+ ])
+ self.out_proj = operations.Linear(model_channels, 8, dtype=dtype, device=device)
+ self.in_proj = operations.Linear(3, model_channels, dtype=dtype, device=device)
+ self.pos_embedder = PcdAbsolutePositionEmbedder(channels=model_channels, in_channels=3, max_res=10, schedule="log2")
+
+ def forward(self, x, l, cond):
+ d = next(self.parameters()).dtype
+ B, L, _ = x.shape
+ h = self.in_proj(x.to(d)) + self.pos_embedder(x.reshape(-1, 3)).reshape(B, L, -1).to(d)
+ h = self.input_layer(h)
+ l_emb = self.l_embedder(l)
+ if self.share_mod:
+ l_emb = self.adaLN_modulation(l_emb)
+ cond = cond.to(d)
+ for block in self.blocks:
+ h = block(h, l_emb, cond)
+ h = F.layer_norm(h.float(), h.shape[-1:]).to(d)
+ logits = self.out_proj(h)
+ return {"logits": logits, "probs": torch.softmax(logits, dim=-1)}
+
+ @staticmethod
+ def sample(model, cond, num_points, level, temperature=1.0, generator=None):
+ B = cond.shape[0]
+ device = cond.device
+ child_offset = torch.tensor([[i, j, k] for k in [0, 1] for j in [0, 1] for i in [0, 1]],
+ dtype=torch.long, device=device)
+ prev_coords_int = torch.zeros(B, 1, 3, dtype=torch.long, device=device)
+ prev_counts = torch.full((B, 1), num_points, dtype=torch.long, device=device)
+ prev_log_probs = torch.zeros(B, 1, dtype=torch.float32, device=device)
+ batch_indices_range = torch.arange(B, device=device).unsqueeze(1)
+
+ for lv in range(1, level + 1):
+ res_p = 1 << (lv - 1)
+ res = 1 << lv
+ parent_coords_norm = (prev_coords_int.to(torch.float32) + 0.5) / res_p
+ res_tensor = torch.full((B,), res, dtype=torch.long, device=device)
+ pred_logits = model(parent_coords_norm, res_tensor, cond)["logits"] / temperature
+ pred_probs = torch.softmax(pred_logits, dim=-1)
+ pred_log_probs = torch.log_softmax(pred_logits, dim=-1)
+ sampled = sample_probs(pred_probs, prev_counts, generator=generator).flatten(1, 2)
+ pred_log_probs = pred_log_probs.flatten(1, 2)
+ prev_log_probs_expanded = prev_log_probs.repeat_interleave(8, dim=1)
+ child_coords_int = (prev_coords_int[:, :, None, :] * 2 + child_offset[None, None, :, :]).flatten(1, 2)
+ mask = sampled > 0
+ max_valid = mask.sum(dim=1).max().item()
+ scatter_indices = mask.cumsum(dim=1) - 1
+ valid_scatter_indices = scatter_indices[mask]
+ valid_batch_indices = batch_indices_range.expand_as(mask)[mask]
+ next_prev_coords_int = torch.zeros(B, max_valid, 3, dtype=child_coords_int.dtype, device=device)
+ next_prev_coords_int[valid_batch_indices, valid_scatter_indices] = child_coords_int[mask]
+ next_prev_counts = torch.zeros(B, max_valid, dtype=sampled.dtype, device=device)
+ next_prev_counts[valid_batch_indices, valid_scatter_indices] = sampled[mask]
+ next_prev_log_probs = torch.zeros(B, max_valid, dtype=prev_log_probs.dtype, device=device)
+ next_prev_log_probs[valid_batch_indices, valid_scatter_indices] = (prev_log_probs_expanded + pred_log_probs)[mask]
+ prev_coords_int = next_prev_coords_int
+ prev_counts = next_prev_counts
+ prev_log_probs = next_prev_log_probs
+
+ res = 1 << level
+ prev_log_probs = torch.repeat_interleave(prev_log_probs.flatten(0, 1), prev_counts.flatten(0, 1), dim=0).reshape(B, num_points)
+ coords_int = torch.repeat_interleave(prev_coords_int.flatten(0, 1), prev_counts.flatten(0, 1), dim=0).reshape(B, num_points, -1)
+ rand = torch.rand(coords_int.shape, dtype=torch.float32, generator=generator).to(device)
+ coords_norm = (coords_int.to(torch.float32) + rand) / res
+ return {"points": coords_norm, "log_probs": prev_log_probs}
+
+
+# Elastic gaussian decoder
+
+class TransformerCrossBlock(nn.Module):
+ def __init__(self, channels, ctx_channels, num_heads, mlp_ratio=4.0,
+ qk_rms_norm=True, qk_rms_norm_cross=True, qkv_bias=True,
+ dtype=None, device=None, operations=None):
+ super().__init__()
+ self.norm1 = operations.LayerNorm(channels, elementwise_affine=False, eps=1e-6, dtype=dtype, device=device)
+ self.norm2 = operations.LayerNorm(channels, elementwise_affine=True, eps=1e-6, dtype=dtype, device=device)
+ self.norm3 = operations.LayerNorm(channels, elementwise_affine=False, eps=1e-6, dtype=dtype, device=device)
+ self.self_attn = MultiHeadAttention(channels, num_heads=num_heads, type="self", qkv_bias=qkv_bias,
+ qk_rms_norm=qk_rms_norm, dtype=dtype, device=device, operations=operations)
+ self.cross_attn = MultiHeadAttention(channels, ctx_channels=ctx_channels, num_heads=num_heads, type="cross",
+ qkv_bias=qkv_bias, qk_rms_norm=qk_rms_norm_cross, dtype=dtype, device=device, operations=operations)
+ self.mlp = MLP(channels, int(channels * mlp_ratio), channels, dtype=dtype, device=device, operations=operations)
+
+ def forward(self, x, context):
+ x = x + self.self_attn(self.norm1(x))
+ x = x + self.cross_attn(self.norm2(x), context)
+ x = x + self.mlp(self.norm3(x))
+ return x
+
+
+class ElasticGaussianFixedlenDecoder(nn.Module):
+ # Cross-attention transformer over sampled octree points -> per-point gaussian params.
+ def __init__(self, in_channels=3, model_channels=1024, cond_channels=16, num_blocks=16, num_heads=16,
+ num_head_channels=64, mlp_ratio=4.0, *, representation_config=None,
+ qk_rms_norm=True, qk_rms_norm_cross=True, dtype=None, device=None, operations=None):
+ super().__init__()
+ self.rep_config = representation_config or dict(
+ lr=dict(_xyz=1.0, _features_dc=1.0, _opacity=1.0, _scaling=1.0, _rotation=0.1),
+ perturb_offset=True, perturbe_size=1.5, offset_scale=0.05, num_gaussians=32,
+ filter_kernel_size_3d=0.0009, scaling_bias=0.004, opacity_bias=0.1,
+ scaling_activation="softplus",
+ )
+ self.out_channels = self._calc_layout()
+ self.model_channels = model_channels
+ self.cond_channels = cond_channels
+ self.num_blocks = num_blocks
+ self.num_heads = num_heads or model_channels // num_head_channels
+ self.mlp_ratio = mlp_ratio
+ self.input_layer = operations.Linear(model_channels, model_channels, dtype=dtype, device=device)
+ if cond_channels is not None:
+ self.blocks = nn.ModuleList([
+ TransformerCrossBlock(model_channels, ctx_channels=cond_channels,
+ num_heads=self.num_heads, mlp_ratio=self.mlp_ratio,
+ qk_rms_norm=qk_rms_norm, qk_rms_norm_cross=qk_rms_norm_cross,
+ dtype=dtype, device=device, operations=operations)
+ for _ in range(num_blocks)
+ ])
+ self.in_proj = operations.Linear(in_channels, model_channels, dtype=dtype, device=device)
+ self.pos_embedder = PcdAbsolutePositionEmbedder(channels=model_channels, in_channels=3, max_res=10, schedule="log2")
+ self.out_proj = operations.Linear(model_channels, self.out_channels, dtype=dtype, device=device)
+ self._build_perturbation()
+
+ def _calc_layout(self):
+ ng = self.rep_config['num_gaussians']
+ self.layout = {
+ '_xyz': {'shape': (ng, 3), 'size': ng * 3},
+ '_features_dc': {'shape': (ng, 1, 3), 'size': ng * 3},
+ '_scaling': {'shape': (ng, 3), 'size': ng * 3},
+ '_rotation': {'shape': (ng, 4), 'size': ng * 4},
+ '_opacity': {'shape': (ng, 1), 'size': ng},
+ }
+ self.layout['_offset_scale'] = {'shape': (ng, 1), 'size': ng}
+ start = 0
+ for k, v in self.layout.items():
+ v['range'] = (start, start + v['size'])
+ start += v['size']
+ return start
+
+ def _build_perturbation(self):
+ ng = self.rep_config['num_gaussians']
+ perturbation = torch.tensor([hammersley_sequence(3, i, ng) for i in range(ng)]).float()
+ perturbation = torch.atanh((perturbation * 2 - 1) / self.rep_config['perturbe_size'])
+ self.register_buffer('points_offset_perturbation', perturbation)
+ base = torch.tensor(self.rep_config['offset_scale'])
+ self.register_buffer('base_offset_scale', torch.log(torch.exp(base) - 1.0))
+
+ def _get_offset(self, h):
+ B = h.shape[0]
+ r = self.layout['_offset_scale']['range']
+ _offset_scale = F.softplus(
+ h[:, :, r[0]:r[1]].reshape(B, -1, *self.layout['_offset_scale']['shape'])
+ + comfy.model_management.cast_to(self.base_offset_scale, h.dtype, h.device))
+
+ r = self.layout['_xyz']['range']
+ offset = h[:, :, r[0]:r[1]].reshape(B, -1, *self.layout['_xyz']['shape'])
+ offset = offset * self.rep_config['lr']['_xyz']
+ if self.rep_config['perturb_offset']:
+ offset = offset + comfy.model_management.cast_to(self.points_offset_perturbation, offset.dtype, offset.device)
+ offset = torch.tanh(offset) * 0.5 * self.rep_config['perturbe_size']
+ offset = offset * _offset_scale
+ return offset
+
+ def forward(self, x=None, cond=None):
+ pcd = x["points"]
+ d = next(self.parameters()).dtype
+ B, L, _ = pcd.shape
+ h = self.in_proj(pcd.to(d)) + self.pos_embedder(pcd.reshape(-1, 3)).reshape(B, L, -1).to(d)
+ h = self.input_layer(h)
+ cond = cond.to(d)
+ for block in self.blocks:
+ h = block(h, cond)
+ h = F.layer_norm(h.float(), h.shape[-1:]).to(h.dtype)
+ return {"features": self.out_proj(h)}
+
+
+# Combined octree gaussian decoder (comfy first-stage model)
+
+class OctreeGaussianDecoder(nn.Module):
+ _MAX_VOXEL_LEVEL = 8
+
+ def __init__(self, dtype=None, device=None, operations=None):
+ super().__init__()
+ if operations is None:
+ operations = comfy.ops.disable_weight_init
+ self.octree = OctreeProbabilityFixedlenDecoder(dtype=dtype, device=device, operations=operations)
+ self.gs = ElasticGaussianFixedlenDecoder(dtype=dtype, device=device, operations=operations)
+
+ @property
+ def gaussians_per_point(self) -> int:
+ return self.gs.rep_config['num_gaussians']
+
+ def decode(self, latent: torch.Tensor, num_gaussians: int, level: int = None, generator=None):
+ # level defaults to the full octree depth, a lower level is cheaper (coarser) for live previews.
+ # generator (a CPU torch.Generator) makes the octree sampling reproducible without touching global RNG.
+ level = self._MAX_VOXEL_LEVEL if level is None else level
+ num_decoder_tokens = max(1, num_gaussians // self.gaussians_per_point)
+ points_pred = OctreeProbabilityFixedlenDecoder.sample(
+ self.octree, latent, num_points=num_decoder_tokens, level=level, temperature=1.0, generator=generator,
+ )
+ pred = self.gs(x=points_pred, cond=latent)
+ return build_gaussian_models(self.gs, points_pred, pred) # one GaussianModel per batch item
diff --git a/ComfyUI/comfy/ldm/util.py b/ComfyUI/comfy/ldm/util.py
new file mode 100644
index 0000000000000000000000000000000000000000..304936ff4414529c130ea4bc8b6b0fd86b452302
--- /dev/null
+++ b/ComfyUI/comfy/ldm/util.py
@@ -0,0 +1,197 @@
+import importlib
+import logging
+
+import torch
+from torch import optim
+import numpy as np
+
+from inspect import isfunction
+from PIL import Image, ImageDraw, ImageFont
+
+
+def log_txt_as_img(wh, xc, size=10):
+ # wh a tuple of (width, height)
+ # xc a list of captions to plot
+ b = len(xc)
+ txts = list()
+ for bi in range(b):
+ txt = Image.new("RGB", wh, color="white")
+ draw = ImageDraw.Draw(txt)
+ font = ImageFont.truetype('data/DejaVuSans.ttf', size=size)
+ nc = int(40 * (wh[0] / 256))
+ lines = "\n".join(xc[bi][start:start + nc] for start in range(0, len(xc[bi]), nc))
+
+ try:
+ draw.text((0, 0), lines, fill="black", font=font)
+ except UnicodeEncodeError:
+ logging.warning("Cant encode string for logging. Skipping.")
+
+ txt = np.array(txt).transpose(2, 0, 1) / 127.5 - 1.0
+ txts.append(txt)
+ txts = np.stack(txts)
+ txts = torch.tensor(txts)
+ return txts
+
+
+def ismap(x):
+ if not isinstance(x, torch.Tensor):
+ return False
+ return (len(x.shape) == 4) and (x.shape[1] > 3)
+
+
+def isimage(x):
+ if not isinstance(x,torch.Tensor):
+ return False
+ return (len(x.shape) == 4) and (x.shape[1] == 3 or x.shape[1] == 1)
+
+
+def exists(x):
+ return x is not None
+
+
+def default(val, d):
+ if exists(val):
+ return val
+ return d() if isfunction(d) else d
+
+
+def mean_flat(tensor):
+ """
+ https://github.com/openai/guided-diffusion/blob/27c20a8fab9cb472df5d6bdd6c8d11c8f430b924/guided_diffusion/nn.py#L86
+ Take the mean over all non-batch dimensions.
+ """
+ return tensor.mean(dim=list(range(1, len(tensor.shape))))
+
+
+def count_params(model, verbose=False):
+ total_params = sum(p.numel() for p in model.parameters())
+ if verbose:
+ logging.info(f"{model.__class__.__name__} has {total_params*1.e-6:.2f} M params.")
+ return total_params
+
+
+def instantiate_from_config(config):
+ if "target" not in config:
+ if config == '__is_first_stage__':
+ return None
+ elif config == "__is_unconditional__":
+ return None
+ raise KeyError("Expected key `target` to instantiate.")
+ return get_obj_from_str(config["target"])(**config.get("params", dict()))
+
+
+def get_obj_from_str(string, reload=False):
+ module, cls = string.rsplit(".", 1)
+ if reload:
+ module_imp = importlib.import_module(module)
+ importlib.reload(module_imp)
+ return getattr(importlib.import_module(module, package=None), cls)
+
+
+class AdamWwithEMAandWings(optim.Optimizer):
+ # credit to https://gist.github.com/crowsonkb/65f7265353f403714fce3b2595e0b298
+ def __init__(self, params, lr=1.e-3, betas=(0.9, 0.999), eps=1.e-8, # TODO: check hyperparameters before using
+ weight_decay=1.e-2, amsgrad=False, ema_decay=0.9999, # ema decay to match previous code
+ ema_power=1., param_names=()):
+ """AdamW that saves EMA versions of the parameters."""
+ if not 0.0 <= lr:
+ raise ValueError("Invalid learning rate: {}".format(lr))
+ if not 0.0 <= eps:
+ raise ValueError("Invalid epsilon value: {}".format(eps))
+ if not 0.0 <= betas[0] < 1.0:
+ raise ValueError("Invalid beta parameter at index 0: {}".format(betas[0]))
+ if not 0.0 <= betas[1] < 1.0:
+ raise ValueError("Invalid beta parameter at index 1: {}".format(betas[1]))
+ if not 0.0 <= weight_decay:
+ raise ValueError("Invalid weight_decay value: {}".format(weight_decay))
+ if not 0.0 <= ema_decay <= 1.0:
+ raise ValueError("Invalid ema_decay value: {}".format(ema_decay))
+ defaults = dict(lr=lr, betas=betas, eps=eps,
+ weight_decay=weight_decay, amsgrad=amsgrad, ema_decay=ema_decay,
+ ema_power=ema_power, param_names=param_names)
+ super().__init__(params, defaults)
+
+ def __setstate__(self, state):
+ super().__setstate__(state)
+ for group in self.param_groups:
+ group.setdefault('amsgrad', False)
+
+ @torch.no_grad()
+ def step(self, closure=None):
+ """Performs a single optimization step.
+ Args:
+ closure (callable, optional): A closure that reevaluates the model
+ and returns the loss.
+ """
+ loss = None
+ if closure is not None:
+ with torch.enable_grad():
+ loss = closure()
+
+ for group in self.param_groups:
+ params_with_grad = []
+ grads = []
+ exp_avgs = []
+ exp_avg_sqs = []
+ ema_params_with_grad = []
+ max_exp_avg_sqs = []
+ state_steps = []
+ amsgrad = group['amsgrad']
+ beta1, beta2 = group['betas']
+ ema_decay = group['ema_decay']
+ ema_power = group['ema_power']
+
+ for p in group['params']:
+ if p.grad is None:
+ continue
+ params_with_grad.append(p)
+ if p.grad.is_sparse:
+ raise RuntimeError('AdamW does not support sparse gradients')
+ grads.append(p.grad)
+
+ state = self.state[p]
+
+ # State initialization
+ if len(state) == 0:
+ state['step'] = 0
+ # Exponential moving average of gradient values
+ state['exp_avg'] = torch.zeros_like(p, memory_format=torch.preserve_format)
+ # Exponential moving average of squared gradient values
+ state['exp_avg_sq'] = torch.zeros_like(p, memory_format=torch.preserve_format)
+ if amsgrad:
+ # Maintains max of all exp. moving avg. of sq. grad. values
+ state['max_exp_avg_sq'] = torch.zeros_like(p, memory_format=torch.preserve_format)
+ # Exponential moving average of parameter values
+ state['param_exp_avg'] = p.detach().float().clone()
+
+ exp_avgs.append(state['exp_avg'])
+ exp_avg_sqs.append(state['exp_avg_sq'])
+ ema_params_with_grad.append(state['param_exp_avg'])
+
+ if amsgrad:
+ max_exp_avg_sqs.append(state['max_exp_avg_sq'])
+
+ # update the steps for each param group update
+ state['step'] += 1
+ # record the step after step update
+ state_steps.append(state['step'])
+
+ optim._functional.adamw(params_with_grad,
+ grads,
+ exp_avgs,
+ exp_avg_sqs,
+ max_exp_avg_sqs,
+ state_steps,
+ amsgrad=amsgrad,
+ beta1=beta1,
+ beta2=beta2,
+ lr=group['lr'],
+ weight_decay=group['weight_decay'],
+ eps=group['eps'],
+ maximize=False)
+
+ cur_ema_decay = min(ema_decay, 1 - state['step'] ** -ema_power)
+ for param, ema_param in zip(params_with_grad, ema_params_with_grad):
+ ema_param.mul_(cur_ema_decay).add_(param.float(), alpha=1 - cur_ema_decay)
+
+ return loss
diff --git a/ComfyUI/comfy/ldm/wan/__pycache__/ar_model.cpython-312.pyc b/ComfyUI/comfy/ldm/wan/__pycache__/ar_model.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..4c65cdd2e53a77cc39b0042bc29bed2fb85a6136
Binary files /dev/null and b/ComfyUI/comfy/ldm/wan/__pycache__/ar_model.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/wan/__pycache__/model.cpython-312.pyc b/ComfyUI/comfy/ldm/wan/__pycache__/model.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..aa497e0c59582431a7ab7d3a6eb1534addb6f0b0
Binary files /dev/null and b/ComfyUI/comfy/ldm/wan/__pycache__/model.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/wan/__pycache__/model_animate.cpython-312.pyc b/ComfyUI/comfy/ldm/wan/__pycache__/model_animate.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..b5fb9fa4d92a2a8471a8a1992ebdab1fbcbce12b
Binary files /dev/null and b/ComfyUI/comfy/ldm/wan/__pycache__/model_animate.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/wan/__pycache__/model_multitalk.cpython-312.pyc b/ComfyUI/comfy/ldm/wan/__pycache__/model_multitalk.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..d5ea06025b13414f7fec8c15d67983273059e790
Binary files /dev/null and b/ComfyUI/comfy/ldm/wan/__pycache__/model_multitalk.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/wan/__pycache__/model_wandancer.cpython-312.pyc b/ComfyUI/comfy/ldm/wan/__pycache__/model_wandancer.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..888ff9bd0585d7c7697b807b33e63452145a4619
Binary files /dev/null and b/ComfyUI/comfy/ldm/wan/__pycache__/model_wandancer.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/wan/__pycache__/uni3c.cpython-312.pyc b/ComfyUI/comfy/ldm/wan/__pycache__/uni3c.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..155348b15f8228e7433e722770d89d08cf3e2c05
Binary files /dev/null and b/ComfyUI/comfy/ldm/wan/__pycache__/uni3c.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/wan/__pycache__/vae.cpython-312.pyc b/ComfyUI/comfy/ldm/wan/__pycache__/vae.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..5796cc0be1bebd14181c3809188e7d804a0c55a6
Binary files /dev/null and b/ComfyUI/comfy/ldm/wan/__pycache__/vae.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/wan/__pycache__/vae2_2.cpython-312.pyc b/ComfyUI/comfy/ldm/wan/__pycache__/vae2_2.cpython-312.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..a5d81264a717611cc90080097176433283899443
Binary files /dev/null and b/ComfyUI/comfy/ldm/wan/__pycache__/vae2_2.cpython-312.pyc differ
diff --git a/ComfyUI/comfy/ldm/wan/ar_model.py b/ComfyUI/comfy/ldm/wan/ar_model.py
new file mode 100644
index 0000000000000000000000000000000000000000..d72f53602b0862b8f733263a58a018dc275a9bc4
--- /dev/null
+++ b/ComfyUI/comfy/ldm/wan/ar_model.py
@@ -0,0 +1,276 @@
+"""
+CausalWanModel: Wan 2.1 backbone with KV-cached causal self-attention for
+autoregressive (frame-by-frame) video generation via Causal Forcing.
+
+Weight-compatible with the standard WanModel -- same layer names, same shapes.
+The difference is purely in the forward pass: this model processes one temporal
+block at a time and maintains a KV cache across blocks.
+
+Reference: https://github.com/thu-ml/Causal-Forcing
+"""
+
+import torch
+import torch.nn as nn
+
+from comfy.ldm.modules.attention import optimized_attention
+from comfy.ldm.flux.math import apply_rope1
+from comfy.ldm.wan.model import (
+ sinusoidal_embedding_1d,
+ repeat_e,
+ WanModel,
+ WanAttentionBlock,
+)
+import comfy.ldm.common_dit
+import comfy.model_management
+
+
+class CausalWanSelfAttention(nn.Module):
+ """Self-attention with KV cache support for autoregressive inference."""
+
+ def __init__(self, dim, num_heads, window_size=(-1, -1), qk_norm=True,
+ eps=1e-6, operation_settings={}):
+ assert dim % num_heads == 0
+ super().__init__()
+ self.dim = dim
+ self.num_heads = num_heads
+ self.head_dim = dim // num_heads
+ self.qk_norm = qk_norm
+ self.eps = eps
+
+ ops = operation_settings.get("operations")
+ device = operation_settings.get("device")
+ dtype = operation_settings.get("dtype")
+
+ self.q = ops.Linear(dim, dim, device=device, dtype=dtype)
+ self.k = ops.Linear(dim, dim, device=device, dtype=dtype)
+ self.v = ops.Linear(dim, dim, device=device, dtype=dtype)
+ self.o = ops.Linear(dim, dim, device=device, dtype=dtype)
+ self.norm_q = ops.RMSNorm(dim, eps=eps, elementwise_affine=True, device=device, dtype=dtype) if qk_norm else nn.Identity()
+ self.norm_k = ops.RMSNorm(dim, eps=eps, elementwise_affine=True, device=device, dtype=dtype) if qk_norm else nn.Identity()
+
+ def forward(self, x, freqs, kv_cache=None, transformer_options={}):
+ b, s, n, d = *x.shape[:2], self.num_heads, self.head_dim
+
+ q = apply_rope1(self.norm_q(self.q(x)).view(b, s, n, d), freqs)
+ k = apply_rope1(self.norm_k(self.k(x)).view(b, s, n, d), freqs)
+ v = self.v(x).view(b, s, n, d)
+
+ if kv_cache is None:
+ x = optimized_attention(
+ q.view(b, s, n * d),
+ k.view(b, s, n * d),
+ v.view(b, s, n * d),
+ heads=self.num_heads,
+ transformer_options=transformer_options,
+ )
+ else:
+ end = kv_cache["end"]
+ new_end = end + s
+
+ # Roped K and plain V go into cache
+ kv_cache["k"][:, end:new_end] = k
+ kv_cache["v"][:, end:new_end] = v
+ kv_cache["end"] = new_end
+
+ x = optimized_attention(
+ q.view(b, s, n * d),
+ kv_cache["k"][:, :new_end].view(b, new_end, n * d),
+ kv_cache["v"][:, :new_end].view(b, new_end, n * d),
+ heads=self.num_heads,
+ transformer_options=transformer_options,
+ )
+
+ x = self.o(x)
+ return x
+
+
+class CausalWanAttentionBlock(WanAttentionBlock):
+ """Transformer block with KV-cached self-attention and cross-attention caching."""
+
+ def __init__(self, cross_attn_type, dim, ffn_dim, num_heads,
+ window_size=(-1, -1), qk_norm=True, cross_attn_norm=False,
+ eps=1e-6, operation_settings={}):
+ super().__init__(cross_attn_type, dim, ffn_dim, num_heads,
+ window_size, qk_norm, cross_attn_norm, eps,
+ operation_settings=operation_settings)
+ self.self_attn = CausalWanSelfAttention(
+ dim, num_heads, window_size, qk_norm, eps,
+ operation_settings=operation_settings)
+
+ def forward(self, x, e, freqs, context, context_img_len=257,
+ kv_cache=None, crossattn_cache=None, transformer_options={}):
+ if e.ndim < 4:
+ e = (comfy.model_management.cast_to(self.modulation, dtype=x.dtype, device=x.device) + e).chunk(6, dim=1)
+ else:
+ e = (comfy.model_management.cast_to(self.modulation, dtype=x.dtype, device=x.device).unsqueeze(0) + e).unbind(2)
+
+ # Self-attention with optional KV cache
+ x = x.contiguous()
+ y = self.self_attn(
+ torch.addcmul(repeat_e(e[0], x), self.norm1(x), 1 + repeat_e(e[1], x)),
+ freqs, kv_cache=kv_cache, transformer_options=transformer_options)
+ x = torch.addcmul(x, y, repeat_e(e[2], x))
+ del y
+
+ # Cross-attention with optional caching
+ if crossattn_cache is not None and crossattn_cache.get("is_init"):
+ q = self.cross_attn.norm_q(self.cross_attn.q(self.norm3(x)))
+ x_ca = optimized_attention(
+ q, crossattn_cache["k"], crossattn_cache["v"],
+ heads=self.num_heads, transformer_options=transformer_options)
+ x = x + self.cross_attn.o(x_ca)
+ else:
+ x = x + self.cross_attn(self.norm3(x), context, context_img_len=context_img_len, transformer_options=transformer_options)
+ if crossattn_cache is not None:
+ crossattn_cache["k"] = self.cross_attn.norm_k(self.cross_attn.k(context))
+ crossattn_cache["v"] = self.cross_attn.v(context)
+ crossattn_cache["is_init"] = True
+
+ # FFN
+ y = self.ffn(torch.addcmul(repeat_e(e[3], x), self.norm2(x), 1 + repeat_e(e[4], x)))
+ x = torch.addcmul(x, y, repeat_e(e[5], x))
+ return x
+
+
+class CausalWanModel(WanModel):
+ """
+ Wan 2.1 diffusion backbone with causal KV-cache support.
+
+ Same weight structure as WanModel -- loads identical state dicts.
+ Adds forward_block() for frame-by-frame autoregressive inference.
+ """
+
+ def __init__(self,
+ model_type='t2v',
+ patch_size=(1, 2, 2),
+ text_len=512,
+ in_dim=16,
+ dim=2048,
+ ffn_dim=8192,
+ freq_dim=256,
+ text_dim=4096,
+ out_dim=16,
+ num_heads=16,
+ num_layers=32,
+ window_size=(-1, -1),
+ qk_norm=True,
+ cross_attn_norm=True,
+ eps=1e-6,
+ image_model=None,
+ device=None,
+ dtype=None,
+ operations=None):
+ super().__init__(
+ model_type=model_type, patch_size=patch_size, text_len=text_len,
+ in_dim=in_dim, dim=dim, ffn_dim=ffn_dim, freq_dim=freq_dim,
+ text_dim=text_dim, out_dim=out_dim, num_heads=num_heads,
+ num_layers=num_layers, window_size=window_size, qk_norm=qk_norm,
+ cross_attn_norm=cross_attn_norm, eps=eps, image_model=image_model,
+ wan_attn_block_class=CausalWanAttentionBlock,
+ device=device, dtype=dtype, operations=operations)
+
+ def forward_block(self, x, timestep, context, start_frame,
+ kv_caches, crossattn_caches, clip_fea=None):
+ """
+ Forward one temporal block for autoregressive inference.
+
+ Args:
+ x: [B, C, block_frames, H, W] input latent for the current block
+ timestep: [B, block_frames] per-frame timesteps
+ context: [B, L, text_dim] raw text embeddings (pre-text_embedding)
+ start_frame: temporal frame index for RoPE offset
+ kv_caches: list of per-layer KV cache dicts
+ crossattn_caches: list of per-layer cross-attention cache dicts
+ clip_fea: optional CLIP features for I2V
+
+ Returns:
+ flow_pred: [B, C_out, block_frames, H, W] flow prediction
+ """
+ x = comfy.ldm.common_dit.pad_to_patch_size(x, self.patch_size)
+ bs, c, t, h, w = x.shape
+
+ x = self.patch_embedding(x.float()).to(x.dtype)
+ grid_sizes = x.shape[2:]
+ x = x.flatten(2).transpose(1, 2)
+
+ # Per-frame time embedding
+ e = self.time_embedding(
+ sinusoidal_embedding_1d(self.freq_dim, timestep.flatten()).to(dtype=x.dtype))
+ e = e.reshape(timestep.shape[0], -1, e.shape[-1])
+ e0 = self.time_projection(e).unflatten(2, (6, self.dim))
+
+ # Text embedding (reuses crossattn_cache after first block)
+ context = self.text_embedding(context)
+
+ context_img_len = None
+ if clip_fea is not None and self.img_emb is not None:
+ context_clip = self.img_emb(clip_fea)
+ context = torch.concat([context_clip, context], dim=1)
+ context_img_len = clip_fea.shape[-2]
+
+ # RoPE for current block's temporal position
+ freqs = self.rope_encode(t, h, w, t_start=start_frame, device=x.device, dtype=x.dtype)
+
+ # Transformer blocks
+ for i, block in enumerate(self.blocks):
+ x = block(x, e=e0, freqs=freqs, context=context,
+ context_img_len=context_img_len,
+ kv_cache=kv_caches[i],
+ crossattn_cache=crossattn_caches[i])
+
+ # Head
+ x = self.head(x, e)
+
+ # Unpatchify
+ x = self.unpatchify(x, grid_sizes)
+ return x[:, :, :t, :h, :w]
+
+ def init_kv_caches(self, batch_size, max_seq_len, device, dtype):
+ """Create fresh KV caches for all layers."""
+ caches = []
+ for _ in range(self.num_layers):
+ caches.append({
+ "k": torch.zeros(batch_size, max_seq_len, self.num_heads, self.head_dim, device=device, dtype=dtype),
+ "v": torch.zeros(batch_size, max_seq_len, self.num_heads, self.head_dim, device=device, dtype=dtype),
+ "end": 0,
+ })
+ return caches
+
+ def init_crossattn_caches(self, batch_size, device, dtype):
+ """Create fresh cross-attention caches for all layers."""
+ caches = []
+ for _ in range(self.num_layers):
+ caches.append({"is_init": False})
+ return caches
+
+ def reset_kv_caches(self, kv_caches):
+ """Reset KV caches to empty (reuse allocated memory)."""
+ for cache in kv_caches:
+ cache["end"] = 0
+
+ def reset_crossattn_caches(self, crossattn_caches):
+ """Reset cross-attention caches."""
+ for cache in crossattn_caches:
+ cache["is_init"] = False
+
+ @property
+ def head_dim(self):
+ return self.dim // self.num_heads
+
+ def forward(self, x, timestep, context, clip_fea=None, time_dim_concat=None, transformer_options={}, **kwargs):
+ ar_state = transformer_options.get("ar_state")
+ if ar_state is not None:
+ bs = x.shape[0]
+ block_frames = x.shape[2]
+ t_per_frame = timestep.unsqueeze(1).expand(bs, block_frames)
+ return self.forward_block(
+ x=x, timestep=t_per_frame, context=context,
+ start_frame=ar_state["start_frame"],
+ kv_caches=ar_state["kv_caches"],
+ crossattn_caches=ar_state["crossattn_caches"],
+ clip_fea=clip_fea,
+ )
+
+ return super().forward(x, timestep, context, clip_fea=clip_fea,
+ time_dim_concat=time_dim_concat,
+ transformer_options=transformer_options, **kwargs)
diff --git a/ComfyUI/comfy/ldm/wan/model.py b/ComfyUI/comfy/ldm/wan/model.py
new file mode 100644
index 0000000000000000000000000000000000000000..c042e93c4c9b81614c7f06b45d49524a3f82b865
--- /dev/null
+++ b/ComfyUI/comfy/ldm/wan/model.py
@@ -0,0 +1,1864 @@
+# original version: https://github.com/Wan-Video/Wan2.1/blob/main/wan/modules/model.py
+# Copyright 2024-2025 The Alibaba Wan Team Authors. All rights reserved.
+import math
+
+import torch
+import torch.nn as nn
+from einops import rearrange
+
+from comfy.ldm.modules.attention import optimized_attention
+from comfy.ldm.flux.layers import EmbedND
+from comfy.ldm.flux.math import apply_rope1, rope
+import comfy.ldm.common_dit
+import comfy.model_management
+import comfy.patcher_extension
+
+
+def sinusoidal_embedding_1d(dim, position):
+ # preprocess
+ assert dim % 2 == 0
+ half = dim // 2
+ position = position.type(torch.float32)
+
+ # calculation
+ sinusoid = torch.outer(
+ position, torch.pow(10000, -torch.arange(half).to(position).div(half)))
+ x = torch.cat([torch.cos(sinusoid), torch.sin(sinusoid)], dim=1)
+ return x
+
+
+class WanSelfAttention(nn.Module):
+
+ def __init__(self,
+ dim,
+ num_heads,
+ window_size=(-1, -1),
+ qk_norm=True,
+ eps=1e-6,
+ kv_dim=None,
+ operation_settings={}):
+ assert dim % num_heads == 0
+ super().__init__()
+ self.dim = dim
+ self.num_heads = num_heads
+ self.head_dim = dim // num_heads
+ self.window_size = window_size
+ self.qk_norm = qk_norm
+ self.eps = eps
+ if kv_dim is None:
+ kv_dim = dim
+
+ # layers
+ self.q = operation_settings.get("operations").Linear(dim, dim, device=operation_settings.get("device"), dtype=operation_settings.get("dtype"))
+ self.k = operation_settings.get("operations").Linear(kv_dim, dim, device=operation_settings.get("device"), dtype=operation_settings.get("dtype"))
+ self.v = operation_settings.get("operations").Linear(kv_dim, dim, device=operation_settings.get("device"), dtype=operation_settings.get("dtype"))
+ self.o = operation_settings.get("operations").Linear(dim, dim, device=operation_settings.get("device"), dtype=operation_settings.get("dtype"))
+ self.norm_q = operation_settings.get("operations").RMSNorm(dim, eps=eps, elementwise_affine=True, device=operation_settings.get("device"), dtype=operation_settings.get("dtype")) if qk_norm else nn.Identity()
+ self.norm_k = operation_settings.get("operations").RMSNorm(dim, eps=eps, elementwise_affine=True, device=operation_settings.get("device"), dtype=operation_settings.get("dtype")) if qk_norm else nn.Identity()
+
+ def forward(self, x, freqs, transformer_options={}):
+ r"""
+ Args:
+ x(Tensor): Shape [B, L, num_heads, C / num_heads]
+ freqs(Tensor): Rope freqs, shape [1024, C / num_heads / 2]
+ """
+ patches = transformer_options.get("patches", {})
+
+ b, s, n, d = *x.shape[:2], self.num_heads, self.head_dim
+
+ def qkv_fn_q(x):
+ q = self.norm_q(self.q(x)).view(b, s, n, d)
+ return apply_rope1(q, freqs)
+
+ def qkv_fn_k(x):
+ k = self.norm_k(self.k(x)).view(b, s, n, d)
+ return apply_rope1(k, freqs)
+
+ #These two are VRAM hogs, so we want to do all of q computation and
+ #have pytorch garbage collect the intermediates on the sub function
+ #return before we touch k
+ q = qkv_fn_q(x)
+ k = qkv_fn_k(x)
+
+ x = optimized_attention(
+ q.view(b, s, n * d),
+ k.view(b, s, n * d),
+ self.v(x).view(b, s, n * d),
+ heads=self.num_heads,
+ transformer_options=transformer_options,
+ )
+
+ if "attn1_patch" in patches:
+ for p in patches["attn1_patch"]:
+ x = p({"x": x, "q": q, "k": k, "transformer_options": transformer_options})
+
+ x = self.o(x)
+ return x
+
+
+class WanT2VCrossAttention(WanSelfAttention):
+
+ def forward(self, x, context, transformer_options={}, **kwargs):
+ r"""
+ Args:
+ x(Tensor): Shape [B, L1, C]
+ context(Tensor): Shape [B, L2, C]
+ """
+ # compute query, key, value
+ q = self.norm_q(self.q(x))
+ k = self.norm_k(self.k(context))
+ v = self.v(context)
+
+ # compute attention
+ x = optimized_attention(q, k, v, heads=self.num_heads, transformer_options=transformer_options)
+
+ x = self.o(x)
+ return x
+
+
+class WanI2VCrossAttention(WanSelfAttention):
+
+ def __init__(self,
+ dim,
+ num_heads,
+ window_size=(-1, -1),
+ qk_norm=True,
+ eps=1e-6, operation_settings={}):
+ super().__init__(dim, num_heads, window_size, qk_norm, eps, operation_settings=operation_settings)
+
+ self.k_img = operation_settings.get("operations").Linear(dim, dim, device=operation_settings.get("device"), dtype=operation_settings.get("dtype"))
+ self.v_img = operation_settings.get("operations").Linear(dim, dim, device=operation_settings.get("device"), dtype=operation_settings.get("dtype"))
+ # self.alpha = nn.Parameter(torch.zeros((1, )))
+ self.norm_k_img = operation_settings.get("operations").RMSNorm(dim, eps=eps, elementwise_affine=True, device=operation_settings.get("device"), dtype=operation_settings.get("dtype")) if qk_norm else nn.Identity()
+
+ def forward(self, x, context, context_img_len, transformer_options={}):
+ r"""
+ Args:
+ x(Tensor): Shape [B, L1, C]
+ context(Tensor): Shape [B, L2, C]
+ """
+ context_img = context[:, :context_img_len]
+ context = context[:, context_img_len:]
+
+ # compute query, key, value
+ q = self.norm_q(self.q(x))
+ k = self.norm_k(self.k(context))
+ v = self.v(context)
+ k_img = self.norm_k_img(self.k_img(context_img))
+ v_img = self.v_img(context_img)
+ img_x = optimized_attention(q, k_img, v_img, heads=self.num_heads, transformer_options=transformer_options)
+ # compute attention
+ x = optimized_attention(q, k, v, heads=self.num_heads, transformer_options=transformer_options)
+
+ # output
+ x = x + img_x
+ x = self.o(x)
+ return x
+
+
+WAN_CROSSATTENTION_CLASSES = {
+ 't2v_cross_attn': WanT2VCrossAttention,
+ 'i2v_cross_attn': WanI2VCrossAttention,
+}
+
+
+def repeat_e(e, x):
+ repeats = 1
+ if e.size(1) > 1:
+ repeats = x.size(1) // e.size(1)
+ if repeats == 1:
+ return e
+ if repeats * e.size(1) == x.size(1):
+ return torch.repeat_interleave(e, repeats, dim=1)
+ else:
+ return torch.repeat_interleave(e, repeats + 1, dim=1)[:, :x.size(1)]
+
+
+class WanAttentionBlock(nn.Module):
+
+ def __init__(self,
+ cross_attn_type,
+ dim,
+ ffn_dim,
+ num_heads,
+ window_size=(-1, -1),
+ qk_norm=True,
+ cross_attn_norm=False,
+ eps=1e-6, operation_settings={}):
+ super().__init__()
+ self.dim = dim
+ self.ffn_dim = ffn_dim
+ self.num_heads = num_heads
+ self.window_size = window_size
+ self.qk_norm = qk_norm
+ self.cross_attn_norm = cross_attn_norm
+ self.eps = eps
+
+ # layers
+ self.norm1 = operation_settings.get("operations").LayerNorm(dim, eps, elementwise_affine=False, device=operation_settings.get("device"), dtype=operation_settings.get("dtype"))
+ self.self_attn = WanSelfAttention(dim, num_heads, window_size, qk_norm,
+ eps, operation_settings=operation_settings)
+ self.norm3 = operation_settings.get("operations").LayerNorm(
+ dim, eps,
+ elementwise_affine=True, device=operation_settings.get("device"), dtype=operation_settings.get("dtype")) if cross_attn_norm else nn.Identity()
+ self.cross_attn = WAN_CROSSATTENTION_CLASSES[cross_attn_type](dim,
+ num_heads,
+ (-1, -1),
+ qk_norm,
+ eps, operation_settings=operation_settings)
+ self.norm2 = operation_settings.get("operations").LayerNorm(dim, eps, elementwise_affine=False, device=operation_settings.get("device"), dtype=operation_settings.get("dtype"))
+ self.ffn = nn.Sequential(
+ operation_settings.get("operations").Linear(dim, ffn_dim, device=operation_settings.get("device"), dtype=operation_settings.get("dtype")), nn.GELU(approximate='tanh'),
+ operation_settings.get("operations").Linear(ffn_dim, dim, device=operation_settings.get("device"), dtype=operation_settings.get("dtype")))
+
+ # modulation
+ self.modulation = nn.Parameter(torch.empty(1, 6, dim, device=operation_settings.get("device"), dtype=operation_settings.get("dtype")))
+
+ def forward(
+ self,
+ x,
+ e,
+ freqs,
+ context,
+ context_img_len=257,
+ transformer_options={},
+ ):
+ r"""
+ Args:
+ x(Tensor): Shape [B, L, C]
+ e(Tensor): Shape [B, 6, C]
+ freqs(Tensor): Rope freqs, shape [1024, C / num_heads / 2]
+ """
+ # assert e.dtype == torch.float32
+
+ patches = transformer_options.get("patches", {})
+
+ if e.ndim < 4:
+ e = (comfy.model_management.cast_to(self.modulation, dtype=x.dtype, device=x.device) + e).chunk(6, dim=1)
+ else:
+ e = (comfy.model_management.cast_to(self.modulation, dtype=x.dtype, device=x.device).unsqueeze(0) + e).unbind(2)
+ # assert e[0].dtype == torch.float32
+
+ # self-attention
+ x = x.contiguous() # otherwise implicit in LayerNorm
+ y = self.self_attn(
+ torch.addcmul(repeat_e(e[0], x), self.norm1(x), 1 + repeat_e(e[1], x)),
+ freqs, transformer_options=transformer_options)
+
+ x = torch.addcmul(x, y, repeat_e(e[2], x))
+ del y
+
+ # cross-attention & ffn
+ x = x + self.cross_attn(self.norm3(x), context, context_img_len=context_img_len, transformer_options=transformer_options)
+
+ if "attn2_patch" in patches:
+ for p in patches["attn2_patch"]:
+ x = p({"x": x, "transformer_options": transformer_options})
+
+ y = self.ffn(torch.addcmul(repeat_e(e[3], x), self.norm2(x), 1 + repeat_e(e[4], x)))
+ x = torch.addcmul(x, y, repeat_e(e[5], x))
+ return x
+
+
+class VaceWanAttentionBlock(WanAttentionBlock):
+ def __init__(
+ self,
+ cross_attn_type,
+ dim,
+ ffn_dim,
+ num_heads,
+ window_size=(-1, -1),
+ qk_norm=True,
+ cross_attn_norm=False,
+ eps=1e-6,
+ block_id=0,
+ operation_settings={}
+ ):
+ super().__init__(cross_attn_type, dim, ffn_dim, num_heads, window_size, qk_norm, cross_attn_norm, eps, operation_settings=operation_settings)
+ self.block_id = block_id
+ if block_id == 0:
+ self.before_proj = operation_settings.get("operations").Linear(self.dim, self.dim, device=operation_settings.get("device"), dtype=operation_settings.get("dtype"))
+ self.after_proj = operation_settings.get("operations").Linear(self.dim, self.dim, device=operation_settings.get("device"), dtype=operation_settings.get("dtype"))
+
+ def forward(self, c, x, **kwargs):
+ if self.block_id == 0:
+ c = self.before_proj(c) + x
+ c = super().forward(c, **kwargs)
+ c_skip = self.after_proj(c)
+ return c_skip, c
+
+
+class WanCamAdapter(nn.Module):
+ def __init__(self, in_dim, out_dim, kernel_size, stride, num_residual_blocks=1, operation_settings={}):
+ super(WanCamAdapter, self).__init__()
+
+ # Pixel Unshuffle: reduce spatial dimensions by a factor of 8
+ self.pixel_unshuffle = nn.PixelUnshuffle(downscale_factor=8)
+
+ # Convolution: reduce spatial dimensions by a factor
+ # of 2 (without overlap)
+ self.conv = operation_settings.get("operations").Conv2d(in_dim * 64, out_dim, kernel_size=kernel_size, stride=stride, padding=0, device=operation_settings.get("device"), dtype=operation_settings.get("dtype"))
+
+ # Residual blocks for feature extraction
+ self.residual_blocks = nn.Sequential(
+ *[WanCamResidualBlock(out_dim, operation_settings = operation_settings) for _ in range(num_residual_blocks)]
+ )
+
+ def forward(self, x):
+ # Reshape to merge the frame dimension into batch
+ bs, c, f, h, w = x.size()
+ x = x.permute(0, 2, 1, 3, 4).contiguous().view(bs * f, c, h, w)
+
+ # Pixel Unshuffle operation
+ x_unshuffled = self.pixel_unshuffle(x)
+
+ # Convolution operation
+ x_conv = self.conv(x_unshuffled)
+
+ # Feature extraction with residual blocks
+ out = self.residual_blocks(x_conv)
+
+ # Reshape to restore original bf dimension
+ out = out.view(bs, f, out.size(1), out.size(2), out.size(3))
+
+ # Permute dimensions to reorder (if needed), e.g., swap channels and feature frames
+ out = out.permute(0, 2, 1, 3, 4)
+
+ return out
+
+
+class WanCamResidualBlock(nn.Module):
+ def __init__(self, dim, operation_settings={}):
+ super(WanCamResidualBlock, self).__init__()
+ self.conv1 = operation_settings.get("operations").Conv2d(dim, dim, kernel_size=3, padding=1, device=operation_settings.get("device"), dtype=operation_settings.get("dtype"))
+ self.relu = nn.ReLU(inplace=True)
+ self.conv2 = operation_settings.get("operations").Conv2d(dim, dim, kernel_size=3, padding=1, device=operation_settings.get("device"), dtype=operation_settings.get("dtype"))
+
+ def forward(self, x):
+ residual = x
+ out = self.relu(self.conv1(x))
+ out = self.conv2(out)
+ out += residual
+ return out
+
+
+class Head(nn.Module):
+
+ def __init__(self, dim, out_dim, patch_size, eps=1e-6, operation_settings={}):
+ super().__init__()
+ self.dim = dim
+ self.out_dim = out_dim
+ self.patch_size = patch_size
+ self.eps = eps
+
+ # layers
+ out_dim = math.prod(patch_size) * out_dim
+ self.norm = operation_settings.get("operations").LayerNorm(dim, eps, elementwise_affine=False, device=operation_settings.get("device"), dtype=operation_settings.get("dtype"))
+ self.head = operation_settings.get("operations").Linear(dim, out_dim, device=operation_settings.get("device"), dtype=operation_settings.get("dtype"))
+
+ # modulation
+ self.modulation = nn.Parameter(torch.empty(1, 2, dim, device=operation_settings.get("device"), dtype=operation_settings.get("dtype")))
+
+ def forward(self, x, e):
+ r"""
+ Args:
+ x(Tensor): Shape [B, L1, C]
+ e(Tensor): Shape [B, C]
+ """
+ # assert e.dtype == torch.float32
+ if e.ndim < 3:
+ e = (comfy.model_management.cast_to(self.modulation, dtype=x.dtype, device=x.device) + e.unsqueeze(1)).chunk(2, dim=1)
+ else:
+ e = (comfy.model_management.cast_to(self.modulation, dtype=x.dtype, device=x.device).unsqueeze(0) + e.unsqueeze(2)).unbind(2)
+
+ x = (self.head(torch.addcmul(repeat_e(e[0], x), self.norm(x), 1 + repeat_e(e[1], x))))
+ return x
+
+
+class MLPProj(torch.nn.Module):
+
+ def __init__(self, in_dim, out_dim, flf_pos_embed_token_number=None, operation_settings={}):
+ super().__init__()
+
+ self.proj = torch.nn.Sequential(
+ operation_settings.get("operations").LayerNorm(in_dim, device=operation_settings.get("device"), dtype=operation_settings.get("dtype")), operation_settings.get("operations").Linear(in_dim, in_dim, device=operation_settings.get("device"), dtype=operation_settings.get("dtype")),
+ torch.nn.GELU(), operation_settings.get("operations").Linear(in_dim, out_dim, device=operation_settings.get("device"), dtype=operation_settings.get("dtype")),
+ operation_settings.get("operations").LayerNorm(out_dim, device=operation_settings.get("device"), dtype=operation_settings.get("dtype")))
+
+ if flf_pos_embed_token_number is not None:
+ self.emb_pos = nn.Parameter(torch.empty((1, flf_pos_embed_token_number, in_dim), device=operation_settings.get("device"), dtype=operation_settings.get("dtype")))
+ else:
+ self.emb_pos = None
+
+ def forward(self, image_embeds):
+ if self.emb_pos is not None:
+ image_embeds = image_embeds[:, :self.emb_pos.shape[1]] + comfy.model_management.cast_to(self.emb_pos[:, :image_embeds.shape[1]], dtype=image_embeds.dtype, device=image_embeds.device)
+
+ clip_extra_context_tokens = self.proj(image_embeds)
+ return clip_extra_context_tokens
+
+
+class WanModel(torch.nn.Module):
+ r"""
+ Wan diffusion backbone supporting both text-to-video and image-to-video.
+ """
+
+ def __init__(self,
+ model_type='t2v',
+ patch_size=(1, 2, 2),
+ text_len=512,
+ in_dim=16,
+ dim=2048,
+ ffn_dim=8192,
+ freq_dim=256,
+ text_dim=4096,
+ out_dim=16,
+ num_heads=16,
+ num_layers=32,
+ window_size=(-1, -1),
+ qk_norm=True,
+ cross_attn_norm=True,
+ eps=1e-6,
+ flf_pos_embed_token_number=None,
+ in_dim_ref_conv=None,
+ wan_attn_block_class=WanAttentionBlock,
+ image_model=None,
+ device=None,
+ dtype=None,
+ operations=None,
+ ):
+ r"""
+ Initialize the diffusion model backbone.
+
+ Args:
+ model_type (`str`, *optional*, defaults to 't2v'):
+ Model variant - 't2v' (text-to-video) or 'i2v' (image-to-video)
+ patch_size (`tuple`, *optional*, defaults to (1, 2, 2)):
+ 3D patch dimensions for video embedding (t_patch, h_patch, w_patch)
+ text_len (`int`, *optional*, defaults to 512):
+ Fixed length for text embeddings
+ in_dim (`int`, *optional*, defaults to 16):
+ Input video channels (C_in)
+ dim (`int`, *optional*, defaults to 2048):
+ Hidden dimension of the transformer
+ ffn_dim (`int`, *optional*, defaults to 8192):
+ Intermediate dimension in feed-forward network
+ freq_dim (`int`, *optional*, defaults to 256):
+ Dimension for sinusoidal time embeddings
+ text_dim (`int`, *optional*, defaults to 4096):
+ Input dimension for text embeddings
+ out_dim (`int`, *optional*, defaults to 16):
+ Output video channels (C_out)
+ num_heads (`int`, *optional*, defaults to 16):
+ Number of attention heads
+ num_layers (`int`, *optional*, defaults to 32):
+ Number of transformer blocks
+ window_size (`tuple`, *optional*, defaults to (-1, -1)):
+ Window size for local attention (-1 indicates global attention)
+ qk_norm (`bool`, *optional*, defaults to True):
+ Enable query/key normalization
+ cross_attn_norm (`bool`, *optional*, defaults to False):
+ Enable cross-attention normalization
+ eps (`float`, *optional*, defaults to 1e-6):
+ Epsilon value for normalization layers
+ """
+
+ super().__init__()
+ self.dtype = dtype
+ operation_settings = {"operations": operations, "device": device, "dtype": dtype}
+
+ assert model_type in ['t2v', 'i2v']
+ self.model_type = model_type
+
+ self.patch_size = patch_size
+ self.text_len = text_len
+ self.in_dim = in_dim
+ self.dim = dim
+ self.ffn_dim = ffn_dim
+ self.freq_dim = freq_dim
+ self.text_dim = text_dim
+ self.out_dim = out_dim
+ self.num_heads = num_heads
+ self.num_layers = num_layers
+ self.window_size = window_size
+ self.qk_norm = qk_norm
+ self.cross_attn_norm = cross_attn_norm
+ self.eps = eps
+
+ # embeddings
+ self.patch_embedding = operations.Conv3d(
+ in_dim, dim, kernel_size=patch_size, stride=patch_size, device=operation_settings.get("device"), dtype=torch.float32)
+ self.text_embedding = nn.Sequential(
+ operations.Linear(text_dim, dim, device=operation_settings.get("device"), dtype=operation_settings.get("dtype")), nn.GELU(approximate='tanh'),
+ operations.Linear(dim, dim, device=operation_settings.get("device"), dtype=operation_settings.get("dtype")))
+
+ self.time_embedding = nn.Sequential(
+ operations.Linear(freq_dim, dim, device=operation_settings.get("device"), dtype=operation_settings.get("dtype")), nn.SiLU(), operations.Linear(dim, dim, device=operation_settings.get("device"), dtype=operation_settings.get("dtype")))
+ self.time_projection = nn.Sequential(nn.SiLU(), operations.Linear(dim, dim * 6, device=operation_settings.get("device"), dtype=operation_settings.get("dtype")))
+
+ # blocks
+ cross_attn_type = 't2v_cross_attn' if model_type == 't2v' else 'i2v_cross_attn'
+ self.blocks = nn.ModuleList([
+ wan_attn_block_class(cross_attn_type, dim, ffn_dim, num_heads,
+ window_size, qk_norm, cross_attn_norm, eps, operation_settings=operation_settings)
+ for i in range(num_layers)
+ ])
+
+ # head
+ self.head = Head(dim, out_dim, patch_size, eps, operation_settings=operation_settings)
+
+ d = dim // num_heads
+ self.rope_embedder = EmbedND(dim=d, theta=10000.0, axes_dim=[d - 4 * (d // 6), 2 * (d // 6), 2 * (d // 6)])
+
+ if model_type == 'i2v':
+ self.img_emb = MLPProj(1280, dim, flf_pos_embed_token_number=flf_pos_embed_token_number, operation_settings=operation_settings)
+ else:
+ self.img_emb = None
+
+ if in_dim_ref_conv is not None:
+ self.ref_conv = operations.Conv2d(in_dim_ref_conv, dim, kernel_size=patch_size[1:], stride=patch_size[1:], device=operation_settings.get("device"), dtype=operation_settings.get("dtype"))
+ else:
+ self.ref_conv = None
+
+ def forward_orig(
+ self,
+ x,
+ t,
+ context,
+ clip_fea=None,
+ freqs=None,
+ transformer_options={},
+ **kwargs,
+ ):
+ r"""
+ Forward pass through the diffusion model
+
+ Args:
+ x (Tensor):
+ List of input video tensors with shape [B, C_in, F, H, W]
+ t (Tensor):
+ Diffusion timesteps tensor of shape [B]
+ context (List[Tensor]):
+ List of text embeddings each with shape [B, L, C]
+ seq_len (`int`):
+ Maximum sequence length for positional encoding
+ clip_fea (Tensor, *optional*):
+ CLIP image features for image-to-video mode
+ y (List[Tensor], *optional*):
+ Conditional video inputs for image-to-video mode, same shape as x
+
+ Returns:
+ List[Tensor]:
+ List of denoised video tensors with original input shapes [C_out, F, H / 8, W / 8]
+ """
+ # embeddings
+ x_input = x
+ x = self.patch_embedding(x.float()).to(x.dtype)
+ grid_sizes = x.shape[2:]
+ transformer_options["grid_sizes"] = grid_sizes
+ x = x.flatten(2).transpose(1, 2)
+
+ # time embeddings
+ e = self.time_embedding(
+ sinusoidal_embedding_1d(self.freq_dim, t.flatten()).to(dtype=x[0].dtype))
+ e = e.reshape(t.shape[0], -1, e.shape[-1])
+ e0 = self.time_projection(e).unflatten(2, (6, self.dim))
+
+ full_ref = None
+ img_offset = 0
+ if self.ref_conv is not None:
+ full_ref = kwargs.get("reference_latent", None)
+ if full_ref is not None:
+ full_ref = self.ref_conv(full_ref).flatten(2).transpose(1, 2)
+ x = torch.concat((full_ref, x), dim=1)
+ img_offset = full_ref.shape[1]
+
+ # In-context reference (Bernini)
+ context_latents = kwargs.get("context_latents", None)
+ main_len = x.shape[1]
+ if context_latents is not None:
+ for lat in context_latents:
+ cl = self.patch_embedding(lat.float().to(x.device)).to(x.dtype).flatten(2).transpose(1, 2)
+ x = torch.cat([x, cl], dim=1)
+
+ # context
+ context = self.text_embedding(context)
+
+ context_img_len = None
+ if clip_fea is not None:
+ if self.img_emb is not None:
+ context_clip = self.img_emb(clip_fea) # bs x 257 x dim
+ context = torch.concat([context_clip, context], dim=1)
+ context_img_len = clip_fea.shape[-2]
+
+ patches_replace = transformer_options.get("patches_replace", {})
+ patches = transformer_options.get("patches", {})
+ blocks_replace = patches_replace.get("dit", {})
+ transformer_options["total_blocks"] = len(self.blocks)
+ transformer_options["block_type"] = "double"
+ for i, block in enumerate(self.blocks):
+ transformer_options["block_index"] = i
+ if ("double_block", i) in blocks_replace:
+ def block_wrap(args):
+ out = {}
+ out["img"] = block(args["img"], context=args["txt"], e=args["vec"], freqs=args["pe"], context_img_len=context_img_len, transformer_options=args["transformer_options"])
+ return out
+ out = blocks_replace[("double_block", i)]({"img": x, "txt": context, "vec": e0, "pe": freqs, "transformer_options": transformer_options}, {"original_block": block_wrap})
+ x = out["img"]
+ else:
+ x = block(x, e=e0, freqs=freqs, context=context, context_img_len=context_img_len, transformer_options=transformer_options)
+
+ if "double_block" in patches:
+ for p in patches["double_block"]:
+ out = p({"img": x, "x": x_input, "vec": e, "block_index": i, "img_offset": img_offset, "transformer_options": transformer_options})
+ x = out["img"]
+
+ # head
+ x = self.head(x, e)
+
+ if context_latents is not None:
+ x = x[:, :main_len]
+
+ if full_ref is not None:
+ x = x[:, full_ref.shape[1]:]
+
+ # unpatchify
+ x = self.unpatchify(x, grid_sizes)
+ return x
+
+ def rope_encode(self, t, h, w, t_start=0, steps_t=None, steps_h=None, steps_w=None, device=None, dtype=None, transformer_options={}, source_id=0):
+ patch_size = self.patch_size
+ t_len = ((t + (patch_size[0] // 2)) // patch_size[0])
+ h_len = ((h + (patch_size[1] // 2)) // patch_size[1])
+ w_len = ((w + (patch_size[2] // 2)) // patch_size[2])
+
+ if steps_t is None:
+ steps_t = t_len
+ if steps_h is None:
+ steps_h = h_len
+ if steps_w is None:
+ steps_w = w_len
+
+ h_start = 0
+ w_start = 0
+ rope_options = transformer_options.get("rope_options", None)
+ if rope_options is not None:
+ t_len = (t_len - 1.0) * rope_options.get("scale_t", 1.0) + 1.0
+ h_len = (h_len - 1.0) * rope_options.get("scale_y", 1.0) + 1.0
+ w_len = (w_len - 1.0) * rope_options.get("scale_x", 1.0) + 1.0
+
+ t_start += rope_options.get("shift_t", 0.0)
+ h_start += rope_options.get("shift_y", 0.0)
+ w_start += rope_options.get("shift_x", 0.0)
+
+ img_ids = torch.zeros((steps_t, steps_h, steps_w, 3), device=device, dtype=dtype)
+ img_ids[:, :, :, 0] = img_ids[:, :, :, 0] + torch.linspace(t_start, t_start + (t_len - 1), steps=steps_t, device=device, dtype=dtype).reshape(-1, 1, 1)
+ img_ids[:, :, :, 1] = img_ids[:, :, :, 1] + torch.linspace(h_start, h_start + (h_len - 1), steps=steps_h, device=device, dtype=dtype).reshape(1, -1, 1)
+ img_ids[:, :, :, 2] = img_ids[:, :, :, 2] + torch.linspace(w_start, w_start + (w_len - 1), steps=steps_w, device=device, dtype=dtype).reshape(1, 1, -1)
+ img_ids = img_ids.reshape(1, -1, img_ids.shape[-1])
+
+ freqs = self.rope_embedder(img_ids).movedim(1, 2)
+
+ # In-context reference: a non-zero source_id composes an extra rotation into the spatial rope
+ if source_id:
+ d = self.dim // self.num_heads
+ pos = torch.tensor([[float(source_id)]], device=freqs.device, dtype=torch.float32)
+ id_rot = rope(pos, d, self.rope_embedder.theta).reshape(1, 1, 1, d // 2, 2, 2).to(freqs.dtype)
+ freqs = torch.einsum('...ij,...jk->...ik', freqs, id_rot)
+ return freqs
+
+ def forward(self, x, timestep, context, clip_fea=None, time_dim_concat=None, transformer_options={}, **kwargs):
+ return comfy.patcher_extension.WrapperExecutor.new_class_executor(
+ self._forward,
+ self,
+ comfy.patcher_extension.get_all_wrappers(comfy.patcher_extension.WrappersMP.DIFFUSION_MODEL, transformer_options)
+ ).execute(x, timestep, context, clip_fea, time_dim_concat, transformer_options, **kwargs)
+
+ def _forward(self, x, timestep, context, clip_fea=None, time_dim_concat=None, transformer_options={}, **kwargs):
+ bs, c, t, h, w = x.shape
+ x = comfy.ldm.common_dit.pad_to_patch_size(x, self.patch_size)
+
+ t_len = t
+ if time_dim_concat is not None:
+ time_dim_concat = comfy.ldm.common_dit.pad_to_patch_size(time_dim_concat, self.patch_size)
+ x = torch.cat([x, time_dim_concat], dim=2)
+ t_len = x.shape[2]
+
+ if self.ref_conv is not None and "reference_latent" in kwargs:
+ t_len += 1
+
+ freqs = self.rope_encode(t_len, h, w, device=x.device, dtype=x.dtype, transformer_options=transformer_options)
+
+ # In-context reference: one rope block per stream, each with it's own source_id (1, 2, ...) to distinguish from the target (id 0).
+ context_latents = kwargs.get("context_latents", None)
+ if context_latents is not None:
+ context_latents = [comfy.ldm.common_dit.pad_to_patch_size(lat, self.patch_size) for lat in context_latents]
+ for i, lat in enumerate(context_latents):
+ freqs = torch.cat([freqs, self.rope_encode(lat.shape[-3], lat.shape[-2], lat.shape[-1], device=x.device, dtype=x.dtype, transformer_options=transformer_options, source_id=i + 1)], dim=1)
+ kwargs = {**kwargs, "context_latents": context_latents}
+
+ return self.forward_orig(x, timestep, context, clip_fea=clip_fea, freqs=freqs, transformer_options=transformer_options, **kwargs)[:, :, :t, :h, :w]
+
+ def unpatchify(self, x, grid_sizes):
+ r"""
+ Reconstruct video tensors from patch embeddings.
+
+ Args:
+ x (List[Tensor]):
+ List of patchified features, each with shape [L, C_out * prod(patch_size)]
+ grid_sizes (Tensor):
+ Original spatial-temporal grid dimensions before patching,
+ shape [B, 3] (3 dimensions correspond to F_patches, H_patches, W_patches)
+
+ Returns:
+ List[Tensor]:
+ Reconstructed video tensors with shape [L, C_out, F, H / 8, W / 8]
+ """
+
+ c = self.out_dim
+ u = x
+ b = u.shape[0]
+ u = u[:, :math.prod(grid_sizes)].view(b, *grid_sizes, *self.patch_size, c)
+ u = torch.einsum('bfhwpqrc->bcfphqwr', u)
+ u = u.reshape(b, c, *[i * j for i, j in zip(grid_sizes, self.patch_size)])
+ return u
+
+
+class VaceWanModel(WanModel):
+ r"""
+ Wan diffusion backbone supporting both text-to-video and image-to-video.
+ """
+
+ def __init__(self,
+ model_type='vace',
+ patch_size=(1, 2, 2),
+ text_len=512,
+ in_dim=16,
+ dim=2048,
+ ffn_dim=8192,
+ freq_dim=256,
+ text_dim=4096,
+ out_dim=16,
+ num_heads=16,
+ num_layers=32,
+ window_size=(-1, -1),
+ qk_norm=True,
+ cross_attn_norm=True,
+ eps=1e-6,
+ flf_pos_embed_token_number=None,
+ image_model=None,
+ vace_layers=None,
+ vace_in_dim=None,
+ device=None,
+ dtype=None,
+ operations=None,
+ ):
+
+ super().__init__(model_type='t2v', patch_size=patch_size, text_len=text_len, in_dim=in_dim, dim=dim, ffn_dim=ffn_dim, freq_dim=freq_dim, text_dim=text_dim, out_dim=out_dim, num_heads=num_heads, num_layers=num_layers, window_size=window_size, qk_norm=qk_norm, cross_attn_norm=cross_attn_norm, eps=eps, flf_pos_embed_token_number=flf_pos_embed_token_number, image_model=image_model, device=device, dtype=dtype, operations=operations)
+ operation_settings = {"operations": operations, "device": device, "dtype": dtype}
+
+ # Vace
+ if vace_layers is not None:
+ self.vace_layers = vace_layers
+ self.vace_in_dim = vace_in_dim
+ # vace blocks
+ self.vace_blocks = nn.ModuleList([
+ VaceWanAttentionBlock('t2v_cross_attn', self.dim, self.ffn_dim, self.num_heads, self.window_size, self.qk_norm, self.cross_attn_norm, self.eps, block_id=i, operation_settings=operation_settings)
+ for i in range(self.vace_layers)
+ ])
+
+ self.vace_layers_mapping = {i: n for n, i in enumerate(range(0, self.num_layers, self.num_layers // self.vace_layers))}
+ # vace patch embeddings
+ self.vace_patch_embedding = operations.Conv3d(
+ self.vace_in_dim, self.dim, kernel_size=self.patch_size, stride=self.patch_size, device=device, dtype=torch.float32
+ )
+
+ def forward_orig(
+ self,
+ x,
+ t,
+ context,
+ vace_context,
+ vace_strength,
+ clip_fea=None,
+ freqs=None,
+ transformer_options={},
+ **kwargs,
+ ):
+ # embeddings
+ x_input = x
+ x = self.patch_embedding(x.float()).to(x.dtype)
+ grid_sizes = x.shape[2:]
+ transformer_options["grid_sizes"] = grid_sizes
+ x = x.flatten(2).transpose(1, 2)
+
+ # time embeddings
+ e = self.time_embedding(
+ sinusoidal_embedding_1d(self.freq_dim, t).to(dtype=x[0].dtype))
+ e0 = self.time_projection(e).unflatten(1, (6, self.dim))
+
+ # context
+ context = self.text_embedding(context)
+
+ context_img_len = None
+ if clip_fea is not None:
+ if self.img_emb is not None:
+ context_clip = self.img_emb(clip_fea) # bs x 257 x dim
+ context = torch.concat([context_clip, context], dim=1)
+ context_img_len = clip_fea.shape[-2]
+
+ orig_shape = list(vace_context.shape)
+ vace_context = vace_context.movedim(0, 1).reshape([-1] + orig_shape[2:])
+ c = self.vace_patch_embedding(vace_context.float()).to(vace_context.dtype)
+ c = c.flatten(2).transpose(1, 2)
+ c = list(c.split(orig_shape[0], dim=0))
+
+ # arguments
+ x_orig = x
+
+ patches_replace = transformer_options.get("patches_replace", {})
+ patches = transformer_options.get("patches", {})
+ blocks_replace = patches_replace.get("dit", {})
+ transformer_options["total_blocks"] = len(self.blocks)
+ transformer_options["block_type"] = "double"
+ for i, block in enumerate(self.blocks):
+ transformer_options["block_index"] = i
+ if ("double_block", i) in blocks_replace:
+ def block_wrap(args):
+ out = {}
+ out["img"] = block(args["img"], context=args["txt"], e=args["vec"], freqs=args["pe"], context_img_len=context_img_len, transformer_options=args["transformer_options"])
+ return out
+ out = blocks_replace[("double_block", i)]({"img": x, "txt": context, "vec": e0, "pe": freqs, "transformer_options": transformer_options}, {"original_block": block_wrap})
+ x = out["img"]
+ else:
+ x = block(x, e=e0, freqs=freqs, context=context, context_img_len=context_img_len, transformer_options=transformer_options)
+
+ if "double_block" in patches:
+ for p in patches["double_block"]:
+ out = p({"img": x, "x": x_input, "vec": e, "block_index": i, "img_offset": 0, "transformer_options": transformer_options})
+ x = out["img"]
+
+ ii = self.vace_layers_mapping.get(i, None)
+ if ii is not None:
+ for iii in range(len(c)):
+ c_skip, c[iii] = self.vace_blocks[ii](c[iii], x=x_orig, e=e0, freqs=freqs, context=context, context_img_len=context_img_len, transformer_options=transformer_options)
+ x += c_skip * vace_strength[iii]
+ del c_skip
+ # head
+ x = self.head(x, e)
+
+ # unpatchify
+ x = self.unpatchify(x, grid_sizes)
+ return x
+
+class CameraWanModel(WanModel):
+ r"""
+ Wan diffusion backbone supporting both text-to-video and image-to-video.
+ """
+
+ def __init__(self,
+ model_type='camera',
+ patch_size=(1, 2, 2),
+ text_len=512,
+ in_dim=16,
+ dim=2048,
+ ffn_dim=8192,
+ freq_dim=256,
+ text_dim=4096,
+ out_dim=16,
+ num_heads=16,
+ num_layers=32,
+ window_size=(-1, -1),
+ qk_norm=True,
+ cross_attn_norm=True,
+ eps=1e-6,
+ flf_pos_embed_token_number=None,
+ image_model=None,
+ in_dim_control_adapter=24,
+ device=None,
+ dtype=None,
+ operations=None,
+ ):
+
+ if model_type == 'camera':
+ model_type = 'i2v'
+ else:
+ model_type = 't2v'
+
+ super().__init__(model_type=model_type, patch_size=patch_size, text_len=text_len, in_dim=in_dim, dim=dim, ffn_dim=ffn_dim, freq_dim=freq_dim, text_dim=text_dim, out_dim=out_dim, num_heads=num_heads, num_layers=num_layers, window_size=window_size, qk_norm=qk_norm, cross_attn_norm=cross_attn_norm, eps=eps, flf_pos_embed_token_number=flf_pos_embed_token_number, image_model=image_model, device=device, dtype=dtype, operations=operations)
+ operation_settings = {"operations": operations, "device": device, "dtype": dtype}
+
+ self.control_adapter = WanCamAdapter(in_dim_control_adapter, dim, kernel_size=patch_size[1:], stride=patch_size[1:], operation_settings=operation_settings)
+
+
+ def forward_orig(
+ self,
+ x,
+ t,
+ context,
+ clip_fea=None,
+ freqs=None,
+ camera_conditions = None,
+ transformer_options={},
+ **kwargs,
+ ):
+ # embeddings
+ x_input = x
+ x = self.patch_embedding(x.float()).to(x.dtype)
+ if self.control_adapter is not None and camera_conditions is not None:
+ x = x + self.control_adapter(camera_conditions).to(x.dtype)
+ grid_sizes = x.shape[2:]
+ x = x.flatten(2).transpose(1, 2)
+
+ # time embeddings
+ e = self.time_embedding(
+ sinusoidal_embedding_1d(self.freq_dim, t).to(dtype=x[0].dtype))
+ e0 = self.time_projection(e).unflatten(1, (6, self.dim))
+
+ # context
+ context = self.text_embedding(context)
+
+ context_img_len = None
+ if clip_fea is not None:
+ if self.img_emb is not None:
+ context_clip = self.img_emb(clip_fea) # bs x 257 x dim
+ context = torch.concat([context_clip, context], dim=1)
+ context_img_len = clip_fea.shape[-2]
+
+ patches_replace = transformer_options.get("patches_replace", {})
+ patches = transformer_options.get("patches", {})
+ blocks_replace = patches_replace.get("dit", {})
+ transformer_options["total_blocks"] = len(self.blocks)
+ transformer_options["block_type"] = "double"
+ for i, block in enumerate(self.blocks):
+ transformer_options["block_index"] = i
+ if ("double_block", i) in blocks_replace:
+ def block_wrap(args):
+ out = {}
+ out["img"] = block(args["img"], context=args["txt"], e=args["vec"], freqs=args["pe"], context_img_len=context_img_len, transformer_options=args["transformer_options"])
+ return out
+ out = blocks_replace[("double_block", i)]({"img": x, "txt": context, "vec": e0, "pe": freqs, "transformer_options": transformer_options}, {"original_block": block_wrap})
+ x = out["img"]
+ else:
+ x = block(x, e=e0, freqs=freqs, context=context, context_img_len=context_img_len, transformer_options=transformer_options)
+
+ if "double_block" in patches:
+ for p in patches["double_block"]:
+ out = p({"img": x, "x": x_input, "vec": e, "block_index": i, "img_offset": 0, "transformer_options": transformer_options})
+ x = out["img"]
+
+ # head
+ x = self.head(x, e)
+
+ # unpatchify
+ x = self.unpatchify(x, grid_sizes)
+ return x
+
+
+class CausalConv1d(nn.Module):
+
+ def __init__(self,
+ chan_in,
+ chan_out,
+ kernel_size=3,
+ stride=1,
+ dilation=1,
+ pad_mode='replicate',
+ operations=None,
+ **kwargs):
+ super().__init__()
+
+ self.pad_mode = pad_mode
+ padding = (kernel_size - 1, 0) # T
+ self.time_causal_padding = padding
+
+ self.conv = operations.Conv1d(
+ chan_in,
+ chan_out,
+ kernel_size,
+ stride=stride,
+ dilation=dilation,
+ **kwargs)
+
+ def forward(self, x):
+ x = torch.nn.functional.pad(x, self.time_causal_padding, mode=self.pad_mode)
+ return self.conv(x)
+
+
+class MotionEncoder_tc(nn.Module):
+
+ def __init__(self,
+ in_dim: int,
+ hidden_dim: int,
+ num_heads: int,
+ need_global=True,
+ dtype=None,
+ device=None,
+ operations=None,):
+ factory_kwargs = {"dtype": dtype, "device": device}
+ super().__init__()
+
+ self.num_heads = num_heads
+ self.need_global = need_global
+ self.conv1_local = CausalConv1d(in_dim, hidden_dim // 4 * num_heads, 3, stride=1, operations=operations, **factory_kwargs)
+ if need_global:
+ self.conv1_global = CausalConv1d(
+ in_dim, hidden_dim // 4, 3, stride=1, operations=operations, **factory_kwargs)
+ self.norm1 = operations.LayerNorm(
+ hidden_dim // 4,
+ elementwise_affine=False,
+ eps=1e-6,
+ **factory_kwargs)
+ self.act = nn.SiLU()
+ self.conv2 = CausalConv1d(hidden_dim // 4, hidden_dim // 2, 3, stride=2, operations=operations, **factory_kwargs)
+ self.conv3 = CausalConv1d(hidden_dim // 2, hidden_dim, 3, stride=2, operations=operations, **factory_kwargs)
+
+ if need_global:
+ self.final_linear = operations.Linear(hidden_dim, hidden_dim, **factory_kwargs)
+
+ self.norm1 = operations.LayerNorm(
+ hidden_dim // 4,
+ elementwise_affine=False,
+ eps=1e-6,
+ **factory_kwargs)
+
+ self.norm2 = operations.LayerNorm(
+ hidden_dim // 2,
+ elementwise_affine=False,
+ eps=1e-6,
+ **factory_kwargs)
+
+ self.norm3 = operations.LayerNorm(
+ hidden_dim, elementwise_affine=False, eps=1e-6, **factory_kwargs)
+
+ self.padding_tokens = nn.Parameter(torch.empty(1, 1, 1, hidden_dim, **factory_kwargs))
+
+ def forward(self, x):
+ x = rearrange(x, 'b t c -> b c t')
+ x_ori = x.clone()
+ b, c, t = x.shape
+ x = self.conv1_local(x)
+ x = rearrange(x, 'b (n c) t -> (b n) t c', n=self.num_heads)
+ x = self.norm1(x)
+ x = self.act(x)
+ x = rearrange(x, 'b t c -> b c t')
+ x = self.conv2(x)
+ x = rearrange(x, 'b c t -> b t c')
+ x = self.norm2(x)
+ x = self.act(x)
+ x = rearrange(x, 'b t c -> b c t')
+ x = self.conv3(x)
+ x = rearrange(x, 'b c t -> b t c')
+ x = self.norm3(x)
+ x = self.act(x)
+ x = rearrange(x, '(b n) t c -> b t n c', b=b)
+ padding = comfy.model_management.cast_to(self.padding_tokens, dtype=x.dtype, device=x.device).repeat(b, x.shape[1], 1, 1)
+ x = torch.cat([x, padding], dim=-2)
+ x_local = x.clone()
+
+ if not self.need_global:
+ return x_local
+
+ x = self.conv1_global(x_ori)
+ x = rearrange(x, 'b c t -> b t c')
+ x = self.norm1(x)
+ x = self.act(x)
+ x = rearrange(x, 'b t c -> b c t')
+ x = self.conv2(x)
+ x = rearrange(x, 'b c t -> b t c')
+ x = self.norm2(x)
+ x = self.act(x)
+ x = rearrange(x, 'b t c -> b c t')
+ x = self.conv3(x)
+ x = rearrange(x, 'b c t -> b t c')
+ x = self.norm3(x)
+ x = self.act(x)
+ x = self.final_linear(x)
+ x = rearrange(x, '(b n) t c -> b t n c', b=b)
+
+ return x, x_local
+
+
+class CausalAudioEncoder(nn.Module):
+
+ def __init__(self,
+ dim=5120,
+ num_layers=25,
+ out_dim=2048,
+ video_rate=8,
+ num_token=4,
+ need_global=False,
+ dtype=None,
+ device=None,
+ operations=None):
+ super().__init__()
+ self.encoder = MotionEncoder_tc(
+ in_dim=dim,
+ hidden_dim=out_dim,
+ num_heads=num_token,
+ need_global=need_global, dtype=dtype, device=device, operations=operations)
+ weight = torch.empty((1, num_layers, 1, 1), dtype=dtype, device=device)
+
+ self.weights = torch.nn.Parameter(weight)
+ self.act = torch.nn.SiLU()
+
+ def forward(self, features):
+ # features B * num_layers * dim * video_length
+ weights = self.act(comfy.model_management.cast_to(self.weights, dtype=features.dtype, device=features.device))
+ weights_sum = weights.sum(dim=1, keepdims=True)
+ weighted_feat = ((features * weights) / weights_sum).sum(
+ dim=1) # b dim f
+ weighted_feat = weighted_feat.permute(0, 2, 1) # b f dim
+ res = self.encoder(weighted_feat) # b f n dim
+ return res # b f n dim
+
+
+class AdaLayerNorm(nn.Module):
+ def __init__(self, embedding_dim, output_dim=None, norm_elementwise_affine=False, norm_eps=1e-5, dtype=None, device=None, operations=None):
+ super().__init__()
+
+ output_dim = output_dim or embedding_dim * 2
+
+ self.silu = nn.SiLU()
+ self.linear = operations.Linear(embedding_dim, output_dim, dtype=dtype, device=device)
+ self.norm = operations.LayerNorm(output_dim // 2, norm_eps, norm_elementwise_affine, dtype=dtype, device=device)
+
+ def forward(self, x, temb):
+ temb = self.linear(self.silu(temb))
+ shift, scale = temb.chunk(2, dim=1)
+ shift = shift[:, None, :]
+ scale = scale[:, None, :]
+ x = self.norm(x) * (1 + scale) + shift
+ return x
+
+
+class AudioInjector_WAN(nn.Module):
+
+ def __init__(self,
+ dim=2048,
+ num_heads=32,
+ inject_layer=[0, 27],
+ root_net=None,
+ enable_adain=False,
+ adain_dim=2048,
+ adain_mode=None,
+ dtype=None,
+ device=None,
+ operations=None):
+ super().__init__()
+ self.enable_adain = enable_adain
+ self.adain_mode = adain_mode
+ self.injected_block_id = {}
+ audio_injector_id = 0
+ for inject_id in inject_layer:
+ self.injected_block_id[inject_id] = audio_injector_id
+ audio_injector_id += 1
+
+ self.injector = nn.ModuleList([
+ WanT2VCrossAttention(
+ dim=dim,
+ num_heads=num_heads,
+ qk_norm=True, operation_settings={"operations": operations, "device": device, "dtype": dtype}
+ ) for _ in range(audio_injector_id)
+ ])
+ self.injector_pre_norm_feat = nn.ModuleList([
+ operations.LayerNorm(
+ dim,
+ elementwise_affine=False,
+ eps=1e-6, dtype=dtype, device=device
+ ) for _ in range(audio_injector_id)
+ ])
+ self.injector_pre_norm_vec = nn.ModuleList([
+ operations.LayerNorm(
+ dim,
+ elementwise_affine=False,
+ eps=1e-6, dtype=dtype, device=device
+ ) for _ in range(audio_injector_id)
+ ])
+ if enable_adain:
+ self.injector_adain_layers = nn.ModuleList([
+ AdaLayerNorm(
+ output_dim=dim * 2, embedding_dim=adain_dim, dtype=dtype, device=device, operations=operations)
+ for _ in range(audio_injector_id)
+ ])
+ if adain_mode != "attn_norm":
+ self.injector_adain_output_layers = nn.ModuleList(
+ [operations.Linear(dim, dim, dtype=dtype, device=device) for _ in range(audio_injector_id)])
+
+ def forward(self, x, block_id, audio_emb, audio_emb_global, seq_len, scale=1.0):
+ audio_attn_id = self.injected_block_id.get(block_id, None)
+ if audio_attn_id is None:
+ return x
+
+ num_frames = audio_emb.shape[1]
+ input_hidden_states = rearrange(x[:, :seq_len], "b (t n) c -> (b t) n c", t=num_frames)
+ if self.enable_adain and self.adain_mode == "attn_norm":
+ audio_emb_global = rearrange(audio_emb_global, "b t n c -> (b t) n c")
+ adain_hidden_states = self.injector_adain_layers[audio_attn_id](input_hidden_states, temb=audio_emb_global[:, 0])
+ attn_hidden_states = adain_hidden_states
+ else:
+ attn_hidden_states = self.injector_pre_norm_feat[audio_attn_id](input_hidden_states)
+
+ if audio_emb.dim() == 3: # WanDancer case
+ attn_audio_emb = rearrange(audio_emb, "b t c -> (b t) 1 c", t=num_frames)
+ else: # S2V case
+ attn_audio_emb = rearrange(audio_emb, "b t n c -> (b t) n c", t=num_frames)
+
+ residual_out = self.injector[audio_attn_id](x=attn_hidden_states, context=attn_audio_emb)
+ residual_out = rearrange(residual_out, "(b t) n c -> b (t n) c", t=num_frames)
+ x[:, :seq_len] = x[:, :seq_len] + residual_out * scale
+ return x
+
+
+class FramePackMotioner(nn.Module):
+ def __init__(
+ self,
+ inner_dim=1024,
+ num_heads=16, # Used to indicate the number of heads in the backbone network; unrelated to this module's design
+ zip_frame_buckets=[
+ 1, 2, 16
+ ], # Three numbers representing the number of frames sampled for patch operations from the nearest to the farthest frames
+ drop_mode="drop", # If not "drop", it will use "padd", meaning padding instead of deletion
+ dtype=None,
+ device=None,
+ operations=None):
+ super().__init__()
+ self.proj = operations.Conv3d(16, inner_dim, kernel_size=(1, 2, 2), stride=(1, 2, 2), dtype=dtype, device=device)
+ self.proj_2x = operations.Conv3d(16, inner_dim, kernel_size=(2, 4, 4), stride=(2, 4, 4), dtype=dtype, device=device)
+ self.proj_4x = operations.Conv3d(16, inner_dim, kernel_size=(4, 8, 8), stride=(4, 8, 8), dtype=dtype, device=device)
+ self.zip_frame_buckets = zip_frame_buckets
+
+ self.inner_dim = inner_dim
+ self.num_heads = num_heads
+
+ self.drop_mode = drop_mode
+
+ def forward(self, motion_latents, rope_embedder, add_last_motion=2):
+ lat_height, lat_width = motion_latents.shape[3], motion_latents.shape[4]
+ padd_lat = torch.zeros(motion_latents.shape[0], 16, sum(self.zip_frame_buckets), lat_height, lat_width).to(device=motion_latents.device, dtype=motion_latents.dtype)
+ overlap_frame = min(padd_lat.shape[2], motion_latents.shape[2])
+ if overlap_frame > 0:
+ padd_lat[:, :, -overlap_frame:] = motion_latents[:, :, -overlap_frame:]
+
+ if add_last_motion < 2 and self.drop_mode != "drop":
+ zero_end_frame = sum(self.zip_frame_buckets[:len(self.zip_frame_buckets) - add_last_motion - 1])
+ padd_lat[:, :, -zero_end_frame:] = 0
+
+ clean_latents_4x, clean_latents_2x, clean_latents_post = padd_lat[:, :, -sum(self.zip_frame_buckets):, :, :].split(self.zip_frame_buckets[::-1], dim=2) # 16, 2 ,1
+
+ # patchfy
+ clean_latents_post = self.proj(clean_latents_post).flatten(2).transpose(1, 2)
+ clean_latents_2x = self.proj_2x(clean_latents_2x)
+ l_2x_shape = clean_latents_2x.shape
+ clean_latents_2x = clean_latents_2x.flatten(2).transpose(1, 2)
+ clean_latents_4x = self.proj_4x(clean_latents_4x)
+ l_4x_shape = clean_latents_4x.shape
+ clean_latents_4x = clean_latents_4x.flatten(2).transpose(1, 2)
+
+ if add_last_motion < 2 and self.drop_mode == "drop":
+ clean_latents_post = clean_latents_post[:, :
+ 0] if add_last_motion < 2 else clean_latents_post
+ clean_latents_2x = clean_latents_2x[:, :
+ 0] if add_last_motion < 1 else clean_latents_2x
+
+ motion_lat = torch.cat([clean_latents_post, clean_latents_2x, clean_latents_4x], dim=1)
+
+ rope_post = rope_embedder.rope_encode(1, lat_height, lat_width, t_start=-1, device=motion_latents.device, dtype=motion_latents.dtype)
+ rope_2x = rope_embedder.rope_encode(1, lat_height, lat_width, t_start=-3, steps_h=l_2x_shape[-2], steps_w=l_2x_shape[-1], device=motion_latents.device, dtype=motion_latents.dtype)
+ rope_4x = rope_embedder.rope_encode(4, lat_height, lat_width, t_start=-19, steps_h=l_4x_shape[-2], steps_w=l_4x_shape[-1], device=motion_latents.device, dtype=motion_latents.dtype)
+
+ rope = torch.cat([rope_post, rope_2x, rope_4x], dim=1)
+ return motion_lat, rope
+
+
+class WanModel_S2V(WanModel):
+ def __init__(self,
+ model_type='s2v',
+ patch_size=(1, 2, 2),
+ text_len=512,
+ in_dim=16,
+ dim=2048,
+ ffn_dim=8192,
+ freq_dim=256,
+ text_dim=4096,
+ out_dim=16,
+ num_heads=16,
+ num_layers=32,
+ window_size=(-1, -1),
+ qk_norm=True,
+ cross_attn_norm=True,
+ eps=1e-6,
+ audio_dim=1024,
+ num_audio_token=4,
+ enable_adain=True,
+ cond_dim=16,
+ audio_inject_layers=[0, 4, 8, 12, 16, 20, 24, 27, 30, 33, 36, 39],
+ adain_mode="attn_norm",
+ framepack_drop_mode="padd",
+ image_model=None,
+ device=None,
+ dtype=None,
+ operations=None,
+ ):
+
+ super().__init__(model_type='t2v', patch_size=patch_size, text_len=text_len, in_dim=in_dim, dim=dim, ffn_dim=ffn_dim, freq_dim=freq_dim, text_dim=text_dim, out_dim=out_dim, num_heads=num_heads, num_layers=num_layers, window_size=window_size, qk_norm=qk_norm, cross_attn_norm=cross_attn_norm, eps=eps, image_model=image_model, device=device, dtype=dtype, operations=operations)
+
+ self.trainable_cond_mask = operations.Embedding(3, self.dim, device=device, dtype=dtype)
+
+ self.casual_audio_encoder = CausalAudioEncoder(
+ dim=audio_dim,
+ out_dim=self.dim,
+ num_token=num_audio_token,
+ need_global=enable_adain, dtype=dtype, device=device, operations=operations)
+
+ if cond_dim > 0:
+ self.cond_encoder = operations.Conv3d(
+ cond_dim,
+ self.dim,
+ kernel_size=self.patch_size,
+ stride=self.patch_size, device=device, dtype=dtype)
+
+ self.audio_injector = AudioInjector_WAN(
+ dim=self.dim,
+ num_heads=self.num_heads,
+ inject_layer=audio_inject_layers,
+ root_net=self,
+ enable_adain=enable_adain,
+ adain_dim=self.dim,
+ adain_mode=adain_mode,
+ dtype=dtype, device=device, operations=operations
+ )
+
+ self.frame_packer = FramePackMotioner(
+ inner_dim=self.dim,
+ num_heads=self.num_heads,
+ zip_frame_buckets=[1, 2, 16],
+ drop_mode=framepack_drop_mode,
+ dtype=dtype, device=device, operations=operations)
+
+ def forward_orig(
+ self,
+ x,
+ t,
+ context,
+ audio_embed=None,
+ reference_latent=None,
+ control_video=None,
+ reference_motion=None,
+ clip_fea=None,
+ freqs=None,
+ transformer_options={},
+ **kwargs,
+ ):
+ if audio_embed is not None:
+ num_embeds = x.shape[-3] * 4
+ audio_emb_global, audio_emb = self.casual_audio_encoder(audio_embed[:, :, :, :num_embeds])
+ else:
+ audio_emb = None
+
+ # embeddings
+ bs, _, time, height, width = x.shape
+ x_input = x
+ x = self.patch_embedding(x.float()).to(x.dtype)
+ if control_video is not None:
+ x = x + self.cond_encoder(control_video)
+
+ if t.ndim == 1:
+ t = t.unsqueeze(1).repeat(1, x.shape[2])
+
+ grid_sizes = x.shape[2:]
+ x = x.flatten(2).transpose(1, 2)
+ seq_len = x.size(1)
+
+ cond_mask_weight = comfy.model_management.cast_to(self.trainable_cond_mask.weight, dtype=x.dtype, device=x.device).unsqueeze(1).unsqueeze(1)
+ x = x + cond_mask_weight[0]
+
+ if reference_latent is not None:
+ ref = self.patch_embedding(reference_latent.float()).to(x.dtype)
+ ref = ref.flatten(2).transpose(1, 2)
+ freqs_ref = self.rope_encode(reference_latent.shape[-3], reference_latent.shape[-2], reference_latent.shape[-1], t_start=max(30, time + 9), device=x.device, dtype=x.dtype)
+ ref = ref + cond_mask_weight[1]
+ x = torch.cat([x, ref], dim=1)
+ freqs = torch.cat([freqs, freqs_ref], dim=1)
+ t = torch.cat([t, torch.zeros((t.shape[0], reference_latent.shape[-3]), device=t.device, dtype=t.dtype)], dim=1)
+ del ref, freqs_ref
+
+ if reference_motion is not None:
+ motion_encoded, freqs_motion = self.frame_packer(reference_motion, self)
+ motion_encoded = motion_encoded + cond_mask_weight[2]
+ x = torch.cat([x, motion_encoded], dim=1)
+ freqs = torch.cat([freqs, freqs_motion], dim=1)
+
+ t = torch.repeat_interleave(t, 2, dim=1)
+ t = torch.cat([t, torch.zeros((t.shape[0], 3), device=t.device, dtype=t.dtype)], dim=1)
+ del motion_encoded, freqs_motion
+
+ # time embeddings
+ e = self.time_embedding(
+ sinusoidal_embedding_1d(self.freq_dim, t.flatten()).to(dtype=x[0].dtype))
+ e = e.reshape(t.shape[0], -1, e.shape[-1])
+ e0 = self.time_projection(e).unflatten(2, (6, self.dim))
+
+ # context
+ context = self.text_embedding(context)
+
+ patches_replace = transformer_options.get("patches_replace", {})
+ patches = transformer_options.get("patches", {})
+ blocks_replace = patches_replace.get("dit", {})
+ transformer_options["total_blocks"] = len(self.blocks)
+ transformer_options["block_type"] = "double"
+ for i, block in enumerate(self.blocks):
+ transformer_options["block_index"] = i
+ if ("double_block", i) in blocks_replace:
+ def block_wrap(args):
+ out = {}
+ out["img"] = block(args["img"], context=args["txt"], e=args["vec"], freqs=args["pe"], transformer_options=args["transformer_options"])
+ return out
+ out = blocks_replace[("double_block", i)]({"img": x, "txt": context, "vec": e0, "pe": freqs, "transformer_options": transformer_options}, {"original_block": block_wrap})
+ x = out["img"]
+ else:
+ x = block(x, e=e0, freqs=freqs, context=context, transformer_options=transformer_options)
+
+ if "double_block" in patches:
+ for p in patches["double_block"]:
+ out = p({"img": x, "x": x_input, "vec": e, "block_index": i, "img_offset": 0, "transformer_options": transformer_options})
+ x = out["img"]
+
+ if audio_emb is not None:
+ x = self.audio_injector(x, i, audio_emb, audio_emb_global, seq_len)
+ # head
+ x = self.head(x, e)
+
+ # unpatchify
+ x = self.unpatchify(x, grid_sizes)
+ return x
+
+
+class WanT2VCrossAttentionGather(WanSelfAttention):
+
+ def forward(self, x, context, transformer_options={}, **kwargs):
+ r"""
+ Args:
+ x(Tensor): Shape [B, L1, C] - video tokens
+ context(Tensor): Shape [B, L2, C] - audio tokens with shape [B, frames*16, 1536]
+ """
+ b, n, d = x.size(0), self.num_heads, self.head_dim
+
+ q = self.norm_q(self.q(x))
+ k = self.norm_k(self.k(context))
+ v = self.v(context)
+
+ # Handle audio temporal structure (16 tokens per frame)
+ k = k.reshape(-1, 16, n, d).transpose(1, 2)
+ v = v.reshape(-1, 16, n, d).transpose(1, 2)
+
+ # Handle video spatial structure
+ q = q.reshape(k.shape[0], -1, n, d).transpose(1, 2)
+
+ x = optimized_attention(q, k, v, heads=self.num_heads, skip_reshape=True, skip_output_reshape=True, transformer_options=transformer_options)
+
+ x = x.transpose(1, 2).reshape(b, -1, n * d)
+ x = self.o(x)
+ return x
+
+
+class AudioCrossAttentionWrapper(nn.Module):
+ def __init__(self, dim, kv_dim, num_heads, qk_norm=True, eps=1e-6, operation_settings={}):
+ super().__init__()
+
+ self.audio_cross_attn = WanT2VCrossAttentionGather(dim, num_heads, qk_norm=qk_norm, kv_dim=kv_dim, eps=eps, operation_settings=operation_settings)
+ self.norm1_audio = operation_settings.get("operations").LayerNorm(dim, eps, elementwise_affine=True, device=operation_settings.get("device"), dtype=operation_settings.get("dtype"))
+
+ def forward(self, x, audio, transformer_options={}):
+ x = x + self.audio_cross_attn(self.norm1_audio(x), audio, transformer_options=transformer_options)
+ return x
+
+
+class WanAttentionBlockAudio(WanAttentionBlock):
+
+ def __init__(self,
+ cross_attn_type,
+ dim,
+ ffn_dim,
+ num_heads,
+ window_size=(-1, -1),
+ qk_norm=True,
+ cross_attn_norm=False,
+ eps=1e-6, operation_settings={}):
+ super().__init__(cross_attn_type, dim, ffn_dim, num_heads, window_size, qk_norm, cross_attn_norm, eps, operation_settings)
+ self.audio_cross_attn_wrapper = AudioCrossAttentionWrapper(dim, 1536, num_heads, qk_norm, eps, operation_settings=operation_settings)
+
+ def forward(
+ self,
+ x,
+ e,
+ freqs,
+ context,
+ context_img_len=257,
+ audio=None,
+ transformer_options={},
+ ):
+ r"""
+ Args:
+ x(Tensor): Shape [B, L, C]
+ e(Tensor): Shape [B, 6, C]
+ freqs(Tensor): Rope freqs, shape [1024, C / num_heads / 2]
+ """
+ # assert e.dtype == torch.float32
+
+ if e.ndim < 4:
+ e = (comfy.model_management.cast_to(self.modulation, dtype=x.dtype, device=x.device) + e).chunk(6, dim=1)
+ else:
+ e = (comfy.model_management.cast_to(self.modulation, dtype=x.dtype, device=x.device).unsqueeze(0) + e).unbind(2)
+ # assert e[0].dtype == torch.float32
+
+ # self-attention
+ y = self.self_attn(
+ torch.addcmul(repeat_e(e[0], x), self.norm1(x), 1 + repeat_e(e[1], x)),
+ freqs, transformer_options=transformer_options)
+
+ x = torch.addcmul(x, y, repeat_e(e[2], x))
+
+ # cross-attention & ffn
+ x = x + self.cross_attn(self.norm3(x), context, context_img_len=context_img_len, transformer_options=transformer_options)
+ if audio is not None:
+ x = self.audio_cross_attn_wrapper(x, audio, transformer_options=transformer_options)
+ y = self.ffn(torch.addcmul(repeat_e(e[3], x), self.norm2(x), 1 + repeat_e(e[4], x)))
+ x = torch.addcmul(x, y, repeat_e(e[5], x))
+ return x
+
+class DummyAdapterLayer(nn.Module):
+ def __init__(self, layer):
+ super().__init__()
+ self.layer = layer
+
+ def forward(self, *args, **kwargs):
+ return self.layer(*args, **kwargs)
+
+
+class AudioProjModel(nn.Module):
+ def __init__(
+ self,
+ seq_len=5,
+ blocks=13, # add a new parameter blocks
+ channels=768, # add a new parameter channels
+ intermediate_dim=512,
+ output_dim=1536,
+ context_tokens=16,
+ device=None,
+ dtype=None,
+ operations=None,
+ ):
+ super().__init__()
+
+ self.seq_len = seq_len
+ self.blocks = blocks
+ self.channels = channels
+ self.input_dim = seq_len * blocks * channels # update input_dim to be the product of blocks and channels.
+ self.intermediate_dim = intermediate_dim
+ self.context_tokens = context_tokens
+ self.output_dim = output_dim
+
+ # define multiple linear layers
+ self.audio_proj_glob_1 = DummyAdapterLayer(operations.Linear(self.input_dim, intermediate_dim, dtype=dtype, device=device))
+ self.audio_proj_glob_2 = DummyAdapterLayer(operations.Linear(intermediate_dim, intermediate_dim, dtype=dtype, device=device))
+ self.audio_proj_glob_3 = DummyAdapterLayer(operations.Linear(intermediate_dim, context_tokens * output_dim, dtype=dtype, device=device))
+
+ self.audio_proj_glob_norm = DummyAdapterLayer(operations.LayerNorm(output_dim, dtype=dtype, device=device))
+
+ def forward(self, audio_embeds):
+ video_length = audio_embeds.shape[1]
+ audio_embeds = rearrange(audio_embeds, "bz f w b c -> (bz f) w b c")
+ batch_size, window_size, blocks, channels = audio_embeds.shape
+ audio_embeds = audio_embeds.view(batch_size, window_size * blocks * channels)
+
+ audio_embeds = torch.relu(self.audio_proj_glob_1(audio_embeds))
+ audio_embeds = torch.relu(self.audio_proj_glob_2(audio_embeds))
+
+ context_tokens = self.audio_proj_glob_3(audio_embeds).reshape(batch_size, self.context_tokens, self.output_dim)
+
+ context_tokens = self.audio_proj_glob_norm(context_tokens)
+ context_tokens = rearrange(context_tokens, "(bz f) m c -> bz f m c", f=video_length)
+
+ return context_tokens
+
+
+class HumoWanModel(WanModel):
+ r"""
+ Wan diffusion backbone supporting both text-to-video and image-to-video.
+ """
+
+ def __init__(self,
+ model_type='humo',
+ patch_size=(1, 2, 2),
+ text_len=512,
+ in_dim=16,
+ dim=2048,
+ ffn_dim=8192,
+ freq_dim=256,
+ text_dim=4096,
+ out_dim=16,
+ num_heads=16,
+ num_layers=32,
+ window_size=(-1, -1),
+ qk_norm=True,
+ cross_attn_norm=True,
+ eps=1e-6,
+ flf_pos_embed_token_number=None,
+ image_model=None,
+ audio_token_num=16,
+ device=None,
+ dtype=None,
+ operations=None,
+ ):
+
+ super().__init__(model_type='t2v', patch_size=patch_size, text_len=text_len, in_dim=in_dim, dim=dim, ffn_dim=ffn_dim, freq_dim=freq_dim, text_dim=text_dim, out_dim=out_dim, num_heads=num_heads, num_layers=num_layers, window_size=window_size, qk_norm=qk_norm, cross_attn_norm=cross_attn_norm, eps=eps, flf_pos_embed_token_number=flf_pos_embed_token_number, wan_attn_block_class=WanAttentionBlockAudio, image_model=image_model, device=device, dtype=dtype, operations=operations)
+
+ self.audio_proj = AudioProjModel(seq_len=8, blocks=5, channels=1280, intermediate_dim=512, output_dim=1536, context_tokens=audio_token_num, dtype=dtype, device=device, operations=operations)
+
+ def forward_orig(
+ self,
+ x,
+ t,
+ context,
+ freqs=None,
+ audio_embed=None,
+ reference_latent=None,
+ transformer_options={},
+ **kwargs,
+ ):
+ bs, _, time, height, width = x.shape
+
+ # embeddings
+ x_input = x
+ x = self.patch_embedding(x.float()).to(x.dtype)
+ grid_sizes = x.shape[2:]
+ x = x.flatten(2).transpose(1, 2)
+
+ # time embeddings
+ e = self.time_embedding(
+ sinusoidal_embedding_1d(self.freq_dim, t.flatten()).to(dtype=x[0].dtype))
+ e = e.reshape(t.shape[0], -1, e.shape[-1])
+ e0 = self.time_projection(e).unflatten(2, (6, self.dim))
+
+ if reference_latent is not None:
+ ref = self.patch_embedding(reference_latent.float()).to(x.dtype)
+ ref = ref.flatten(2).transpose(1, 2)
+ freqs_ref = self.rope_encode(reference_latent.shape[-3], reference_latent.shape[-2], reference_latent.shape[-1], t_start=time, device=x.device, dtype=x.dtype)
+ x = torch.cat([x, ref], dim=1)
+ freqs = torch.cat([freqs, freqs_ref], dim=1)
+ del ref, freqs_ref
+
+ # context
+ context = self.text_embedding(context)
+ context_img_len = None
+
+ if audio_embed is not None:
+ if reference_latent is not None:
+ zero_audio_pad = torch.zeros(audio_embed.shape[0], reference_latent.shape[-3], *audio_embed.shape[2:], device=audio_embed.device, dtype=audio_embed.dtype)
+ audio_embed = torch.cat([audio_embed, zero_audio_pad], dim=1)
+ audio = self.audio_proj(audio_embed).permute(0, 3, 1, 2).flatten(2).transpose(1, 2)
+ else:
+ audio = None
+
+ patches_replace = transformer_options.get("patches_replace", {})
+ patches = transformer_options.get("patches", {})
+ blocks_replace = patches_replace.get("dit", {})
+ transformer_options["total_blocks"] = len(self.blocks)
+ transformer_options["block_type"] = "double"
+ for i, block in enumerate(self.blocks):
+ transformer_options["block_index"] = i
+ if ("double_block", i) in blocks_replace:
+ def block_wrap(args):
+ out = {}
+ out["img"] = block(args["img"], context=args["txt"], e=args["vec"], freqs=args["pe"], context_img_len=context_img_len, audio=audio, transformer_options=args["transformer_options"])
+ return out
+ out = blocks_replace[("double_block", i)]({"img": x, "txt": context, "vec": e0, "pe": freqs, "transformer_options": transformer_options}, {"original_block": block_wrap})
+ x = out["img"]
+ else:
+ x = block(x, e=e0, freqs=freqs, context=context, context_img_len=context_img_len, audio=audio, transformer_options=transformer_options)
+
+ if "double_block" in patches:
+ for p in patches["double_block"]:
+ out = p({"img": x, "x": x_input, "vec": e, "block_index": i, "img_offset": 0, "transformer_options": transformer_options})
+ x = out["img"]
+
+ # head
+ x = self.head(x, e)
+
+ # unpatchify
+ x = self.unpatchify(x, grid_sizes)
+ return x
+
+class SCAILWanModel(WanModel):
+ def __init__(self, model_type="scail", patch_size=(1, 2, 2), in_dim=20, dim=5120, operations=None, device=None, dtype=None, **kwargs):
+ super().__init__(model_type='i2v', patch_size=patch_size, in_dim=in_dim, dim=dim, operations=operations, device=device, dtype=dtype, **kwargs)
+
+ self.patch_embedding_pose = operations.Conv3d(in_dim, dim, kernel_size=patch_size, stride=patch_size, device=device, dtype=torch.float32)
+
+ def forward_orig(self, x, t, context, clip_fea=None, freqs=None, transformer_options={}, pose_latents=None, reference_latent=None, ref_mask_latents=None, sam_latents=None, **kwargs):
+
+ x_input = x
+
+ img_offset = 0
+ if reference_latent is not None:
+ x = torch.cat((reference_latent, x), dim=2)
+ img_offset = (reference_latent.shape[2] // self.patch_size[0]) * \
+ (reference_latent.shape[3] // self.patch_size[1]) * \
+ (reference_latent.shape[4] // self.patch_size[2])
+
+ # embeddings
+ x = self.patch_embedding(x.float()).to(x.dtype)
+ if ref_mask_latents is not None: # SCAIL-2 additive mask stream (one identity mask frame per reference, then video)
+ x = x + self.patch_embedding_mask(ref_mask_latents.float()).to(x.dtype)
+ grid_sizes = x.shape[2:]
+ transformer_options["grid_sizes"] = grid_sizes
+ x = x.flatten(2).transpose(1, 2)
+
+ scail_pose_seq_len = 0
+ if pose_latents is not None:
+ scail_x = self.patch_embedding_pose(pose_latents.float()).to(x.dtype)
+ if sam_latents is not None: # SCAIL-2 additive mask stream
+ scail_x = scail_x + self.patch_embedding_mask(sam_latents.float()).to(x.dtype)
+ scail_x = scail_x.flatten(2).transpose(1, 2)
+ scail_pose_seq_len = scail_x.shape[1]
+ x = torch.cat([x, scail_x], dim=1)
+ del scail_x
+
+ # time embeddings
+ e = self.time_embedding(sinusoidal_embedding_1d(self.freq_dim, t.flatten()).to(dtype=x[0].dtype))
+ e = e.reshape(t.shape[0], -1, e.shape[-1])
+ e0 = self.time_projection(e).unflatten(2, (6, self.dim))
+
+ # context
+ context = self.text_embedding(context)
+
+ context_img_len = None
+ if clip_fea is not None:
+ if self.img_emb is not None:
+ context_clip = self.img_emb(clip_fea) # bs x 257 x dim
+ context = torch.cat([context_clip, context], dim=1)
+ context_img_len = clip_fea.shape[-2]
+
+ patches_replace = transformer_options.get("patches_replace", {})
+ patches = transformer_options.get("patches", {})
+ blocks_replace = patches_replace.get("dit", {})
+ transformer_options["total_blocks"] = len(self.blocks)
+ transformer_options["block_type"] = "double"
+ for i, block in enumerate(self.blocks):
+ transformer_options["block_index"] = i
+ if ("double_block", i) in blocks_replace:
+ def block_wrap(args):
+ out = {}
+ out["img"] = block(args["img"], context=args["txt"], e=args["vec"], freqs=args["pe"], context_img_len=context_img_len, transformer_options=args["transformer_options"])
+ return out
+ out = blocks_replace[("double_block", i)]({"img": x, "txt": context, "vec": e0, "pe": freqs, "transformer_options": transformer_options}, {"original_block": block_wrap})
+ x = out["img"]
+ else:
+ x = block(x, e=e0, freqs=freqs, context=context, context_img_len=context_img_len, transformer_options=transformer_options)
+
+ if "double_block" in patches:
+ for p in patches["double_block"]:
+ out = p({"img": x, "x": x_input, "vec": e, "block_index": i, "img_offset": img_offset, "transformer_options": transformer_options})
+ x = out["img"]
+
+ # head
+ x = self.head(x, e)
+
+ if scail_pose_seq_len > 0:
+ x = x[:, :-scail_pose_seq_len]
+
+ # unpatchify
+ x = self.unpatchify(x, grid_sizes)
+
+ if reference_latent is not None:
+ x = x[:, :, reference_latent.shape[2]:]
+
+ return x
+
+ # ref_mask_flag is a scalar bool (CONDConstant, SCAIL-2 only). False => replacement mode,
+ # which places ref/pose via H/W rope shifts instead of the animation-mode temporal offset.
+ # reference_latent may stack several frames: the last is the primary reference adjacent to the video, the earlier frames are additional references.
+ def rope_encode(self, t, h, w, t_start=0, steps_t=None, steps_h=None, steps_w=None, device=None, dtype=None, pose_latents=None, reference_latent=None, ref_mask_flag=None, transformer_options={}):
+ ref_t_patches = 0
+ if reference_latent is not None:
+ ref_t_patches = (reference_latent.shape[2] + (self.patch_size[0] // 2)) // self.patch_size[0]
+
+ if ref_mask_flag is not None and not bool(ref_mask_flag):
+ REF_ROPE_H = 120.0
+ POSE_ROPE_W = 120.0
+
+ main_t_patches = t - ref_t_patches
+ video_t_start = max(ref_t_patches - 1, 0)
+
+ parts = []
+ if ref_t_patches > 0:
+ ref_tf = {"rope_options": {"shift_y": REF_ROPE_H, "shift_x": 0.0, "scale_y": 1.0, "scale_x": 1.0}}
+ parts.append(super().rope_encode(ref_t_patches, h, w, t_start=0, device=device, dtype=dtype, transformer_options=ref_tf))
+ if main_t_patches > 0:
+ parts.append(super().rope_encode(main_t_patches, h, w, t_start=video_t_start, device=device, dtype=dtype, transformer_options=transformer_options))
+
+ if pose_latents is not None:
+ F_pose, H_pose, W_pose = pose_latents.shape[-3], pose_latents.shape[-2], pose_latents.shape[-1]
+ h_scale = h / H_pose
+ w_scale = w / W_pose
+ h_shift = (h_scale - 1) / 2
+ w_shift = (w_scale - 1) / 2
+ pose_tf = {"rope_options": {"shift_y": h_shift, "shift_x": POSE_ROPE_W + w_shift, "scale_y": h_scale, "scale_x": w_scale}}
+ parts.append(super().rope_encode(F_pose, H_pose, W_pose, t_start=video_t_start, device=device, dtype=dtype, transformer_options=pose_tf))
+
+ return torch.cat(parts, dim=1)
+
+ main_freqs = super().rope_encode(t, h, w, t_start=t_start, steps_t=steps_t, steps_h=steps_h, steps_w=steps_w, device=device, dtype=dtype, transformer_options=transformer_options)
+
+ if pose_latents is None:
+ return main_freqs
+
+ F_pose, H_pose, W_pose = pose_latents.shape[-3], pose_latents.shape[-2], pose_latents.shape[-1]
+
+ # if pose is at half resolution, scale_y/scale_x=2 stretches the position range to cover the same RoPE extent as the main frames
+ h_scale = h / H_pose
+ w_scale = w / W_pose
+
+ # 120 w-offset and shift 0.5 to place positions at midpoints (0.5, 2.5, ...) to match the original code
+ h_shift = (h_scale - 1) / 2
+ w_shift = (w_scale - 1) / 2
+ pose_transformer_options = {"rope_options": {"shift_y": h_shift, "shift_x": 120.0 + w_shift, "scale_y": h_scale, "scale_x": w_scale}}
+ pose_freqs = super().rope_encode(F_pose, H_pose, W_pose, t_start=t_start+ref_t_patches, device=device, dtype=dtype, transformer_options=pose_transformer_options)
+
+ return torch.cat([main_freqs, pose_freqs], dim=1)
+
+ def _forward(self, x, timestep, context, clip_fea=None, time_dim_concat=None, transformer_options={}, pose_latents=None, ref_mask_latents=None, sam_latents=None, **kwargs):
+ bs, c, t, h, w = x.shape
+ x = comfy.ldm.common_dit.pad_to_patch_size(x, self.patch_size)
+
+ if pose_latents is not None:
+ pose_latents = comfy.ldm.common_dit.pad_to_patch_size(pose_latents, self.patch_size)
+ if ref_mask_latents is not None: # SCAIL-2
+ ref_mask_latents = comfy.ldm.common_dit.pad_to_patch_size(ref_mask_latents, self.patch_size)
+ if sam_latents is not None: # SCAIL-2
+ sam_latents = comfy.ldm.common_dit.pad_to_patch_size(sam_latents, self.patch_size)
+
+ t_len = t
+ if time_dim_concat is not None:
+ time_dim_concat = comfy.ldm.common_dit.pad_to_patch_size(time_dim_concat, self.patch_size)
+ x = torch.cat([x, time_dim_concat], dim=2)
+ t_len = x.shape[2]
+
+ reference_latent = None
+ if "reference_latent" in kwargs:
+ reference_latent = comfy.ldm.common_dit.pad_to_patch_size(kwargs.pop("reference_latent"), self.patch_size)
+ t_len += reference_latent.shape[2]
+
+ ref_mask_flag = kwargs.pop("ref_mask_flag", None) # SCAIL-2
+
+ freqs = self.rope_encode(t_len, h, w, device=x.device, dtype=x.dtype, transformer_options=transformer_options, pose_latents=pose_latents, reference_latent=reference_latent, ref_mask_flag=ref_mask_flag)
+ return self.forward_orig(x, timestep, context, clip_fea=clip_fea, freqs=freqs, transformer_options=transformer_options, pose_latents=pose_latents, reference_latent=reference_latent, ref_mask_latents=ref_mask_latents, sam_latents=sam_latents, **kwargs)[:, :, :t, :h, :w]
+
+
+class SCAIL2WanModel(SCAILWanModel):
+ """SCAIL-2: SCAIL-Preview + an additive binary multi-identity mask stream."""
+
+ def __init__(self, model_type="scail2", patch_size=(1, 2, 2), in_dim=20, mask_in_dim=28, dim=5120, operations=None, device=None, dtype=None, **kwargs):
+ super().__init__(model_type=model_type, patch_size=patch_size, in_dim=in_dim, dim=dim, operations=operations, device=device, dtype=dtype, **kwargs)
+ self.patch_embedding_mask = operations.Conv3d(mask_in_dim, dim, kernel_size=patch_size, stride=patch_size, device=device, dtype=torch.float32)
diff --git a/ComfyUI/comfy/ldm/wan/model_animate.py b/ComfyUI/comfy/ldm/wan/model_animate.py
new file mode 100644
index 0000000000000000000000000000000000000000..9ebe5694bd3fb61acc11ef04e9281ce1d4871b29
--- /dev/null
+++ b/ComfyUI/comfy/ldm/wan/model_animate.py
@@ -0,0 +1,560 @@
+from torch import nn
+import torch
+from typing import Tuple, Optional
+from einops import rearrange
+import torch.nn.functional as F
+import math
+from .model import WanModel, sinusoidal_embedding_1d
+from comfy.ldm.modules.attention import optimized_attention
+import comfy.model_management
+
+class CausalConv1d(nn.Module):
+
+ def __init__(self, chan_in, chan_out, kernel_size=3, stride=1, dilation=1, pad_mode="replicate", operations=None, **kwargs):
+ super().__init__()
+
+ self.pad_mode = pad_mode
+ padding = (kernel_size - 1, 0) # T
+ self.time_causal_padding = padding
+
+ self.conv = operations.Conv1d(chan_in, chan_out, kernel_size, stride=stride, dilation=dilation, **kwargs)
+
+ def forward(self, x):
+ x = F.pad(x, self.time_causal_padding, mode=self.pad_mode)
+ return self.conv(x)
+
+
+class FaceEncoder(nn.Module):
+ def __init__(self, in_dim: int, hidden_dim: int, num_heads=int, dtype=None, device=None, operations=None):
+ factory_kwargs = {"dtype": dtype, "device": device}
+ super().__init__()
+
+ self.num_heads = num_heads
+ self.conv1_local = CausalConv1d(in_dim, 1024 * num_heads, 3, stride=1, operations=operations, **factory_kwargs)
+ self.norm1 = operations.LayerNorm(hidden_dim // 8, elementwise_affine=False, eps=1e-6, **factory_kwargs)
+ self.act = nn.SiLU()
+ self.conv2 = CausalConv1d(1024, 1024, 3, stride=2, operations=operations, **factory_kwargs)
+ self.conv3 = CausalConv1d(1024, 1024, 3, stride=2, operations=operations, **factory_kwargs)
+
+ self.out_proj = operations.Linear(1024, hidden_dim, **factory_kwargs)
+ self.norm1 = operations.LayerNorm(1024, elementwise_affine=False, eps=1e-6, **factory_kwargs)
+
+ self.norm2 = operations.LayerNorm(1024, elementwise_affine=False, eps=1e-6, **factory_kwargs)
+
+ self.norm3 = operations.LayerNorm(1024, elementwise_affine=False, eps=1e-6, **factory_kwargs)
+
+ self.padding_tokens = nn.Parameter(torch.empty(1, 1, 1, hidden_dim, **factory_kwargs))
+
+ def forward(self, x):
+
+ x = rearrange(x, "b t c -> b c t")
+ b, c, t = x.shape
+
+ x = self.conv1_local(x)
+ x = rearrange(x, "b (n c) t -> (b n) t c", n=self.num_heads)
+
+ x = self.norm1(x)
+ x = self.act(x)
+ x = rearrange(x, "b t c -> b c t")
+ x = self.conv2(x)
+ x = rearrange(x, "b c t -> b t c")
+ x = self.norm2(x)
+ x = self.act(x)
+ x = rearrange(x, "b t c -> b c t")
+ x = self.conv3(x)
+ x = rearrange(x, "b c t -> b t c")
+ x = self.norm3(x)
+ x = self.act(x)
+ x = self.out_proj(x)
+ x = rearrange(x, "(b n) t c -> b t n c", b=b)
+ padding = comfy.model_management.cast_to(self.padding_tokens, dtype=x.dtype, device=x.device).repeat(b, x.shape[1], 1, 1)
+ x = torch.cat([x, padding], dim=-2)
+ x_local = x.clone()
+
+ return x_local
+
+
+def get_norm_layer(norm_layer, operations=None):
+ """
+ Get the normalization layer.
+
+ Args:
+ norm_layer (str): The type of normalization layer.
+
+ Returns:
+ norm_layer (nn.Module): The normalization layer.
+ """
+ if norm_layer == "layer":
+ return operations.LayerNorm
+ elif norm_layer == "rms":
+ return operations.RMSNorm
+ else:
+ raise NotImplementedError(f"Norm layer {norm_layer} is not implemented")
+
+
+class FaceAdapter(nn.Module):
+ def __init__(
+ self,
+ hidden_dim: int,
+ heads_num: int,
+ qk_norm: bool = True,
+ qk_norm_type: str = "rms",
+ num_adapter_layers: int = 1,
+ dtype=None, device=None, operations=None
+ ):
+
+ factory_kwargs = {"dtype": dtype, "device": device}
+ super().__init__()
+ self.hidden_size = hidden_dim
+ self.heads_num = heads_num
+ self.fuser_blocks = nn.ModuleList(
+ [
+ FaceBlock(
+ self.hidden_size,
+ self.heads_num,
+ qk_norm=qk_norm,
+ qk_norm_type=qk_norm_type,
+ operations=operations,
+ **factory_kwargs,
+ )
+ for _ in range(num_adapter_layers)
+ ]
+ )
+
+ def forward(
+ self,
+ x: torch.Tensor,
+ motion_embed: torch.Tensor,
+ idx: int,
+ freqs_cis_q: Tuple[torch.Tensor, torch.Tensor] = None,
+ freqs_cis_k: Tuple[torch.Tensor, torch.Tensor] = None,
+ ) -> torch.Tensor:
+
+ return self.fuser_blocks[idx](x, motion_embed, freqs_cis_q, freqs_cis_k)
+
+
+
+class FaceBlock(nn.Module):
+ def __init__(
+ self,
+ hidden_size: int,
+ heads_num: int,
+ qk_norm: bool = True,
+ qk_norm_type: str = "rms",
+ qk_scale: float = None,
+ dtype: Optional[torch.dtype] = None,
+ device: Optional[torch.device] = None,
+ operations=None
+ ):
+ factory_kwargs = {"device": device, "dtype": dtype}
+ super().__init__()
+
+ self.deterministic = False
+ self.hidden_size = hidden_size
+ self.heads_num = heads_num
+ head_dim = hidden_size // heads_num
+ self.scale = qk_scale or head_dim**-0.5
+
+ self.linear1_kv = operations.Linear(hidden_size, hidden_size * 2, **factory_kwargs)
+ self.linear1_q = operations.Linear(hidden_size, hidden_size, **factory_kwargs)
+
+ self.linear2 = operations.Linear(hidden_size, hidden_size, **factory_kwargs)
+
+ qk_norm_layer = get_norm_layer(qk_norm_type, operations=operations)
+ self.q_norm = (
+ qk_norm_layer(head_dim, elementwise_affine=True, eps=1e-6, **factory_kwargs) if qk_norm else nn.Identity()
+ )
+ self.k_norm = (
+ qk_norm_layer(head_dim, elementwise_affine=True, eps=1e-6, **factory_kwargs) if qk_norm else nn.Identity()
+ )
+
+ self.pre_norm_feat = operations.LayerNorm(hidden_size, elementwise_affine=False, eps=1e-6, **factory_kwargs)
+
+ self.pre_norm_motion = operations.LayerNorm(hidden_size, elementwise_affine=False, eps=1e-6, **factory_kwargs)
+
+ def forward(
+ self,
+ x: torch.Tensor,
+ motion_vec: torch.Tensor,
+ motion_mask: Optional[torch.Tensor] = None,
+ # use_context_parallel=False,
+ ) -> torch.Tensor:
+
+ B, T, N, C = motion_vec.shape
+ T_comp = T
+
+ x_motion = self.pre_norm_motion(motion_vec)
+ x_feat = self.pre_norm_feat(x)
+
+ kv = self.linear1_kv(x_motion)
+ q = self.linear1_q(x_feat)
+
+ k, v = rearrange(kv, "B L N (K H D) -> K B L N H D", K=2, H=self.heads_num)
+ q = rearrange(q, "B S (H D) -> B S H D", H=self.heads_num)
+
+ # Apply QK-Norm if needed.
+ q = self.q_norm(q).to(v)
+ k = self.k_norm(k).to(v)
+
+ k = rearrange(k, "B L N H D -> (B L) N H D")
+ v = rearrange(v, "B L N H D -> (B L) N H D")
+
+ q = rearrange(q, "B (L S) H D -> (B L) S (H D)", L=T_comp)
+
+ attn = optimized_attention(q, k, v, heads=self.heads_num)
+
+ attn = rearrange(attn, "(B L) S C -> B (L S) C", L=T_comp)
+
+ output = self.linear2(attn)
+
+ if motion_mask is not None:
+ output = output * rearrange(motion_mask, "B T H W -> B (T H W)").unsqueeze(-1)
+
+ return output
+
+# https://github.com/XPixelGroup/BasicSR/blob/8d56e3a045f9fb3e1d8872f92ee4a4f07f886b0a/basicsr/ops/upfirdn2d/upfirdn2d.py#L162
+def upfirdn2d_native(input, kernel, up_x, up_y, down_x, down_y, pad_x0, pad_x1, pad_y0, pad_y1):
+ _, minor, in_h, in_w = input.shape
+ kernel_h, kernel_w = kernel.shape
+
+ out = input.view(-1, minor, in_h, 1, in_w, 1)
+ out = F.pad(out, [0, up_x - 1, 0, 0, 0, up_y - 1, 0, 0])
+ out = out.view(-1, minor, in_h * up_y, in_w * up_x)
+
+ out = F.pad(out, [max(pad_x0, 0), max(pad_x1, 0), max(pad_y0, 0), max(pad_y1, 0)])
+ out = out[:, :, max(-pad_y0, 0): out.shape[2] - max(-pad_y1, 0), max(-pad_x0, 0): out.shape[3] - max(-pad_x1, 0)]
+
+ out = out.reshape([-1, 1, in_h * up_y + pad_y0 + pad_y1, in_w * up_x + pad_x0 + pad_x1])
+ w = torch.flip(kernel, [0, 1]).view(1, 1, kernel_h, kernel_w)
+ out = F.conv2d(out, w)
+ out = out.reshape(-1, minor, in_h * up_y + pad_y0 + pad_y1 - kernel_h + 1, in_w * up_x + pad_x0 + pad_x1 - kernel_w + 1)
+ return out[:, :, ::down_y, ::down_x]
+
+def upfirdn2d(input, kernel, up=1, down=1, pad=(0, 0)):
+ return upfirdn2d_native(input, kernel, up, up, down, down, pad[0], pad[1], pad[0], pad[1])
+
+# https://github.com/XPixelGroup/BasicSR/blob/8d56e3a045f9fb3e1d8872f92ee4a4f07f886b0a/basicsr/ops/fused_act/fused_act.py#L81
+class FusedLeakyReLU(torch.nn.Module):
+ def __init__(self, channel, negative_slope=0.2, scale=2 ** 0.5, dtype=None, device=None):
+ super().__init__()
+ self.bias = torch.nn.Parameter(torch.empty(1, channel, 1, 1, dtype=dtype, device=device))
+ self.negative_slope = negative_slope
+ self.scale = scale
+
+ def forward(self, input):
+ return fused_leaky_relu(input, comfy.model_management.cast_to(self.bias, device=input.device, dtype=input.dtype), self.negative_slope, self.scale)
+
+def fused_leaky_relu(input, bias, negative_slope=0.2, scale=2 ** 0.5):
+ return F.leaky_relu(input + bias, negative_slope) * scale
+
+class Blur(torch.nn.Module):
+ def __init__(self, kernel, pad, dtype=None, device=None):
+ super().__init__()
+ kernel = torch.tensor(kernel, dtype=dtype, device=device)
+ kernel = kernel[None, :] * kernel[:, None]
+ kernel = kernel / kernel.sum()
+ self.register_buffer('kernel', kernel)
+ self.pad = pad
+
+ def forward(self, input):
+ return upfirdn2d(input, comfy.model_management.cast_to(self.kernel, dtype=input.dtype, device=input.device), pad=self.pad)
+
+#https://github.com/XPixelGroup/BasicSR/blob/8d56e3a045f9fb3e1d8872f92ee4a4f07f886b0a/basicsr/archs/stylegan2_arch.py#L590
+class ScaledLeakyReLU(torch.nn.Module):
+ def __init__(self, negative_slope=0.2):
+ super().__init__()
+ self.negative_slope = negative_slope
+
+ def forward(self, input):
+ return F.leaky_relu(input, negative_slope=self.negative_slope)
+
+# https://github.com/XPixelGroup/BasicSR/blob/8d56e3a045f9fb3e1d8872f92ee4a4f07f886b0a/basicsr/archs/stylegan2_arch.py#L605
+class EqualConv2d(torch.nn.Module):
+ def __init__(self, in_channel, out_channel, kernel_size, stride=1, padding=0, bias=True, dtype=None, device=None, operations=None):
+ super().__init__()
+ self.weight = torch.nn.Parameter(torch.empty(out_channel, in_channel, kernel_size, kernel_size, device=device, dtype=dtype))
+ self.scale = 1 / math.sqrt(in_channel * kernel_size ** 2)
+ self.stride = stride
+ self.padding = padding
+ self.bias = torch.nn.Parameter(torch.empty(out_channel, device=device, dtype=dtype)) if bias else None
+
+ def forward(self, input):
+ if self.bias is None:
+ bias = None
+ else:
+ bias = comfy.model_management.cast_to(self.bias, device=input.device, dtype=input.dtype)
+
+ return F.conv2d(input, comfy.model_management.cast_to(self.weight, device=input.device, dtype=input.dtype) * self.scale, bias=bias, stride=self.stride, padding=self.padding)
+
+# https://github.com/XPixelGroup/BasicSR/blob/8d56e3a045f9fb3e1d8872f92ee4a4f07f886b0a/basicsr/archs/stylegan2_arch.py#L134
+class EqualLinear(torch.nn.Module):
+ def __init__(self, in_dim, out_dim, bias=True, bias_init=0, lr_mul=1, activation=None, dtype=None, device=None, operations=None):
+ super().__init__()
+ self.weight = torch.nn.Parameter(torch.empty(out_dim, in_dim, device=device, dtype=dtype))
+ self.bias = torch.nn.Parameter(torch.empty(out_dim, device=device, dtype=dtype)) if bias else None
+ self.activation = activation
+ self.scale = (1 / math.sqrt(in_dim)) * lr_mul
+ self.lr_mul = lr_mul
+
+ def forward(self, input):
+ if self.bias is None:
+ bias = None
+ else:
+ bias = comfy.model_management.cast_to(self.bias, device=input.device, dtype=input.dtype) * self.lr_mul
+
+ if self.activation:
+ out = F.linear(input, comfy.model_management.cast_to(self.weight, device=input.device, dtype=input.dtype) * self.scale)
+ return fused_leaky_relu(out, bias)
+ return F.linear(input, comfy.model_management.cast_to(self.weight, device=input.device, dtype=input.dtype) * self.scale, bias=bias)
+
+# https://github.com/XPixelGroup/BasicSR/blob/8d56e3a045f9fb3e1d8872f92ee4a4f07f886b0a/basicsr/archs/stylegan2_arch.py#L654
+class ConvLayer(torch.nn.Sequential):
+ def __init__(self, in_channel, out_channel, kernel_size, downsample=False, blur_kernel=[1, 3, 3, 1], bias=True, activate=True, dtype=None, device=None, operations=None):
+ layers = []
+
+ if downsample:
+ factor = 2
+ p = (len(blur_kernel) - factor) + (kernel_size - 1)
+ layers.append(Blur(blur_kernel, pad=((p + 1) // 2, p // 2)))
+ stride, padding = 2, 0
+ else:
+ stride, padding = 1, kernel_size // 2
+
+ layers.append(EqualConv2d(in_channel, out_channel, kernel_size, padding=padding, stride=stride, bias=bias and not activate, dtype=dtype, device=device, operations=operations))
+
+ if activate:
+ layers.append(FusedLeakyReLU(out_channel) if bias else ScaledLeakyReLU(0.2))
+
+ super().__init__(*layers)
+
+# https://github.com/XPixelGroup/BasicSR/blob/8d56e3a045f9fb3e1d8872f92ee4a4f07f886b0a/basicsr/archs/stylegan2_arch.py#L704
+class ResBlock(torch.nn.Module):
+ def __init__(self, in_channel, out_channel, dtype=None, device=None, operations=None):
+ super().__init__()
+ self.conv1 = ConvLayer(in_channel, in_channel, 3, dtype=dtype, device=device, operations=operations)
+ self.conv2 = ConvLayer(in_channel, out_channel, 3, downsample=True, dtype=dtype, device=device, operations=operations)
+ self.skip = ConvLayer(in_channel, out_channel, 1, downsample=True, activate=False, bias=False, dtype=dtype, device=device, operations=operations)
+
+ def forward(self, input):
+ out = self.conv2(self.conv1(input))
+ skip = self.skip(input)
+ return (out + skip) / math.sqrt(2)
+
+
+class EncoderApp(torch.nn.Module):
+ def __init__(self, w_dim=512, dtype=None, device=None, operations=None):
+ super().__init__()
+ kwargs = {"device": device, "dtype": dtype, "operations": operations}
+
+ self.convs = torch.nn.ModuleList([
+ ConvLayer(3, 32, 1, **kwargs), ResBlock(32, 64, **kwargs),
+ ResBlock(64, 128, **kwargs), ResBlock(128, 256, **kwargs),
+ ResBlock(256, 512, **kwargs), ResBlock(512, 512, **kwargs),
+ ResBlock(512, 512, **kwargs), ResBlock(512, 512, **kwargs),
+ EqualConv2d(512, w_dim, 4, padding=0, bias=False, **kwargs)
+ ])
+
+ def forward(self, x):
+ h = x
+ for conv in self.convs:
+ h = conv(h)
+ return h.squeeze(-1).squeeze(-1)
+
+class Encoder(torch.nn.Module):
+ def __init__(self, dim=512, motion_dim=20, dtype=None, device=None, operations=None):
+ super().__init__()
+ self.net_app = EncoderApp(dim, dtype=dtype, device=device, operations=operations)
+ self.fc = torch.nn.Sequential(*[EqualLinear(dim, dim, dtype=dtype, device=device, operations=operations) for _ in range(4)] + [EqualLinear(dim, motion_dim, dtype=dtype, device=device, operations=operations)])
+
+ def encode_motion(self, x):
+ return self.fc(self.net_app(x))
+
+class Direction(torch.nn.Module):
+ def __init__(self, motion_dim, dtype=None, device=None, operations=None):
+ super().__init__()
+ self.weight = torch.nn.Parameter(torch.empty(512, motion_dim, device=device, dtype=dtype))
+ self.motion_dim = motion_dim
+
+ def forward(self, input):
+ stabilized_weight = comfy.model_management.cast_to(self.weight, device=input.device, dtype=input.dtype) + 1e-8 * torch.eye(512, self.motion_dim, device=input.device, dtype=input.dtype)
+ Q, _ = torch.linalg.qr(stabilized_weight.float())
+ if input is None:
+ return Q
+ return torch.sum(input.unsqueeze(-1) * Q.T.to(input.dtype), dim=1)
+
+class Synthesis(torch.nn.Module):
+ def __init__(self, motion_dim, dtype=None, device=None, operations=None):
+ super().__init__()
+ self.direction = Direction(motion_dim, dtype=dtype, device=device, operations=operations)
+
+class Generator(torch.nn.Module):
+ def __init__(self, style_dim=512, motion_dim=20, dtype=None, device=None, operations=None):
+ super().__init__()
+ self.enc = Encoder(style_dim, motion_dim, dtype=dtype, device=device, operations=operations)
+ self.dec = Synthesis(motion_dim, dtype=dtype, device=device, operations=operations)
+
+ def get_motion(self, img):
+ motion_feat = self.enc.encode_motion(img)
+ return self.dec.direction(motion_feat)
+
+class AnimateWanModel(WanModel):
+ r"""
+ Wan diffusion backbone supporting both text-to-video and image-to-video.
+ """
+
+ def __init__(self,
+ model_type='animate',
+ patch_size=(1, 2, 2),
+ text_len=512,
+ in_dim=16,
+ dim=2048,
+ ffn_dim=8192,
+ freq_dim=256,
+ text_dim=4096,
+ out_dim=16,
+ num_heads=16,
+ num_layers=32,
+ window_size=(-1, -1),
+ qk_norm=True,
+ cross_attn_norm=True,
+ eps=1e-6,
+ flf_pos_embed_token_number=None,
+ motion_encoder_dim=512,
+ image_model=None,
+ device=None,
+ dtype=None,
+ operations=None,
+ ):
+
+ super().__init__(model_type='i2v', patch_size=patch_size, text_len=text_len, in_dim=in_dim, dim=dim, ffn_dim=ffn_dim, freq_dim=freq_dim, text_dim=text_dim, out_dim=out_dim, num_heads=num_heads, num_layers=num_layers, window_size=window_size, qk_norm=qk_norm, cross_attn_norm=cross_attn_norm, eps=eps, flf_pos_embed_token_number=flf_pos_embed_token_number, image_model=image_model, device=device, dtype=dtype, operations=operations)
+
+ self.pose_patch_embedding = operations.Conv3d(
+ 16, dim, kernel_size=patch_size, stride=patch_size, device=device, dtype=dtype
+ )
+
+ self.motion_encoder = Generator(style_dim=512, motion_dim=20, device=device, dtype=dtype, operations=operations)
+
+ self.face_adapter = FaceAdapter(
+ heads_num=self.num_heads,
+ hidden_dim=self.dim,
+ num_adapter_layers=self.num_layers // 5,
+ device=device, dtype=dtype, operations=operations
+ )
+
+ self.face_encoder = FaceEncoder(
+ in_dim=motion_encoder_dim,
+ hidden_dim=self.dim,
+ num_heads=4,
+ device=device, dtype=dtype, operations=operations
+ )
+
+ def after_patch_embedding(self, x, pose_latents, face_pixel_values):
+ if pose_latents is not None:
+ pose_latents = self.pose_patch_embedding(pose_latents)
+ x[:, :, 1:pose_latents.shape[2] + 1] += pose_latents[:, :, :x.shape[2] - 1]
+
+ if face_pixel_values is None:
+ return x, None
+
+ b, c, T, h, w = face_pixel_values.shape
+ face_pixel_values = rearrange(face_pixel_values, "b c t h w -> (b t) c h w")
+ encode_bs = 8
+ face_pixel_values_tmp = []
+ for i in range(math.ceil(face_pixel_values.shape[0] / encode_bs)):
+ face_pixel_values_tmp.append(self.motion_encoder.get_motion(face_pixel_values[i * encode_bs: (i + 1) * encode_bs]))
+
+ motion_vec = torch.cat(face_pixel_values_tmp)
+
+ motion_vec = rearrange(motion_vec, "(b t) c -> b t c", t=T)
+ motion_vec = self.face_encoder(motion_vec)
+
+ B, L, H, C = motion_vec.shape
+ pad_face = torch.zeros(B, 1, H, C).type_as(motion_vec)
+ motion_vec = torch.cat([pad_face, motion_vec], dim=1)
+
+ if motion_vec.shape[1] < x.shape[2]:
+ B, L, H, C = motion_vec.shape
+ pad = torch.zeros(B, x.shape[2] - motion_vec.shape[1], H, C).type_as(motion_vec)
+ motion_vec = torch.cat([motion_vec, pad], dim=1)
+ else:
+ motion_vec = motion_vec[:, :x.shape[2]]
+ return x, motion_vec
+
+ def forward_orig(
+ self,
+ x,
+ t,
+ context,
+ clip_fea=None,
+ pose_latents=None,
+ face_pixel_values=None,
+ freqs=None,
+ transformer_options={},
+ **kwargs,
+ ):
+ # embeddings
+ x_input = x
+ x = self.patch_embedding(x.float()).to(x.dtype)
+ x, motion_vec = self.after_patch_embedding(x, pose_latents, face_pixel_values)
+ grid_sizes = x.shape[2:]
+ x = x.flatten(2).transpose(1, 2)
+
+ # time embeddings
+ e = self.time_embedding(
+ sinusoidal_embedding_1d(self.freq_dim, t.flatten()).to(dtype=x[0].dtype))
+ e = e.reshape(t.shape[0], -1, e.shape[-1])
+ e0 = self.time_projection(e).unflatten(2, (6, self.dim))
+
+ full_ref = None
+ img_offset = 0
+ if self.ref_conv is not None:
+ full_ref = kwargs.get("reference_latent", None)
+ if full_ref is not None:
+ full_ref = self.ref_conv(full_ref).flatten(2).transpose(1, 2)
+ x = torch.concat((full_ref, x), dim=1)
+ img_offset = full_ref.shape[1]
+
+ # context
+ context = self.text_embedding(context)
+
+ context_img_len = None
+ if clip_fea is not None:
+ if self.img_emb is not None:
+ context_clip = self.img_emb(clip_fea) # bs x 257 x dim
+ context = torch.concat([context_clip, context], dim=1)
+ context_img_len = clip_fea.shape[-2]
+
+ patches_replace = transformer_options.get("patches_replace", {})
+ patches = transformer_options.get("patches", {})
+ blocks_replace = patches_replace.get("dit", {})
+ transformer_options["total_blocks"] = len(self.blocks)
+ transformer_options["block_type"] = "double"
+ for i, block in enumerate(self.blocks):
+ transformer_options["block_index"] = i
+ if ("double_block", i) in blocks_replace:
+ def block_wrap(args):
+ out = {}
+ out["img"] = block(args["img"], context=args["txt"], e=args["vec"], freqs=args["pe"], context_img_len=context_img_len, transformer_options=args["transformer_options"])
+ return out
+ out = blocks_replace[("double_block", i)]({"img": x, "txt": context, "vec": e0, "pe": freqs, "transformer_options": transformer_options}, {"original_block": block_wrap})
+ x = out["img"]
+ else:
+ x = block(x, e=e0, freqs=freqs, context=context, context_img_len=context_img_len, transformer_options=transformer_options)
+
+ if "double_block" in patches:
+ for p in patches["double_block"]:
+ out = p({"img": x, "x": x_input, "vec": e, "block_index": i, "img_offset": img_offset, "transformer_options": transformer_options})
+ x = out["img"]
+
+ if i % 5 == 0 and motion_vec is not None:
+ x = x + self.face_adapter.fuser_blocks[i // 5](x, motion_vec)
+
+ # head
+ x = self.head(x, e)
+
+ if full_ref is not None:
+ x = x[:, full_ref.shape[1]:]
+
+ # unpatchify
+ x = self.unpatchify(x, grid_sizes)
+ return x
diff --git a/ComfyUI/comfy/ldm/wan/model_multitalk.py b/ComfyUI/comfy/ldm/wan/model_multitalk.py
new file mode 100644
index 0000000000000000000000000000000000000000..c9dd98c4ddc7f03f899c7627b980b5923205b3e5
--- /dev/null
+++ b/ComfyUI/comfy/ldm/wan/model_multitalk.py
@@ -0,0 +1,500 @@
+import torch
+from einops import rearrange, repeat
+import comfy
+from comfy.ldm.modules.attention import optimized_attention
+
+
+def calculate_x_ref_attn_map(visual_q, ref_k, ref_target_masks, split_num=8):
+ scale = 1.0 / visual_q.shape[-1] ** 0.5
+ visual_q = visual_q.transpose(1, 2) * scale
+
+ B, H, x_seqlens, K = visual_q.shape
+
+ x_ref_attn_maps = []
+ for class_idx, ref_target_mask in enumerate(ref_target_masks):
+ ref_target_mask = ref_target_mask.view(1, 1, 1, -1)
+
+ x_ref_attnmap = torch.zeros(B, H, x_seqlens, device=visual_q.device, dtype=visual_q.dtype)
+ chunk_size = min(max(x_seqlens // split_num, 1), x_seqlens)
+
+ for i in range(0, x_seqlens, chunk_size):
+ end_i = min(i + chunk_size, x_seqlens)
+
+ attn_chunk = visual_q[:, :, i:end_i] @ ref_k.permute(0, 2, 3, 1) # B, H, chunk, ref_seqlens
+
+ # Apply softmax
+ attn_max = attn_chunk.max(dim=-1, keepdim=True).values
+ attn_chunk = (attn_chunk - attn_max).exp()
+ attn_sum = attn_chunk.sum(dim=-1, keepdim=True)
+ attn_chunk = attn_chunk / (attn_sum + 1e-8)
+
+ # Apply mask and sum
+ masked_attn = attn_chunk * ref_target_mask
+ x_ref_attnmap[:, :, i:end_i] = masked_attn.sum(-1) / (ref_target_mask.sum() + 1e-8)
+
+ del attn_chunk, masked_attn
+
+ # Average across heads
+ x_ref_attnmap = x_ref_attnmap.mean(dim=1) # B, x_seqlens
+ x_ref_attn_maps.append(x_ref_attnmap)
+
+ del visual_q, ref_k
+
+ return torch.cat(x_ref_attn_maps, dim=0)
+
+def get_attn_map_with_target(visual_q, ref_k, shape, ref_target_masks=None, split_num=2):
+ """Args:
+ query (torch.tensor): B M H K
+ key (torch.tensor): B M H K
+ shape (tuple): (N_t, N_h, N_w)
+ ref_target_masks: [B, N_h * N_w]
+ """
+
+ N_t, N_h, N_w = shape
+
+ x_seqlens = N_h * N_w
+ ref_k = ref_k[:, :x_seqlens]
+ _, seq_lens, heads, _ = visual_q.shape
+ class_num, _ = ref_target_masks.shape
+ x_ref_attn_maps = torch.zeros(class_num, seq_lens).to(visual_q)
+
+ split_chunk = heads // split_num
+
+ for i in range(split_num):
+ x_ref_attn_maps_perhead = calculate_x_ref_attn_map(
+ visual_q[:, :, i*split_chunk:(i+1)*split_chunk, :],
+ ref_k[:, :, i*split_chunk:(i+1)*split_chunk, :],
+ ref_target_masks
+ )
+ x_ref_attn_maps += x_ref_attn_maps_perhead
+
+ return x_ref_attn_maps / split_num
+
+
+def normalize_and_scale(column, source_range, target_range, epsilon=1e-8):
+ source_min, source_max = source_range
+ new_min, new_max = target_range
+ normalized = (column - source_min) / (source_max - source_min + epsilon)
+ scaled = normalized * (new_max - new_min) + new_min
+ return scaled
+
+
+def rotate_half(x):
+ x = rearrange(x, "... (d r) -> ... d r", r=2)
+ x1, x2 = x.unbind(dim=-1)
+ x = torch.stack((-x2, x1), dim=-1)
+ return rearrange(x, "... d r -> ... (d r)")
+
+
+def get_audio_embeds(encoded_audio, audio_start, audio_end):
+ audio_embs = []
+ human_num = len(encoded_audio)
+ audio_frames = encoded_audio[0].shape[0]
+
+ indices = (torch.arange(4 + 1) - 2) * 1
+
+ for human_idx in range(human_num):
+ if audio_end > audio_frames: # in case of not enough audio for current window, pad with first audio frame as that's most likely silence
+ pad_len = audio_end - audio_frames
+ pad_shape = list(encoded_audio[human_idx].shape)
+ pad_shape[0] = pad_len
+ pad_tensor = encoded_audio[human_idx][:1].repeat(pad_len, *([1] * (encoded_audio[human_idx].dim() - 1)))
+ encoded_audio_in = torch.cat([encoded_audio[human_idx], pad_tensor], dim=0)
+ else:
+ encoded_audio_in = encoded_audio[human_idx]
+ center_indices = torch.arange(audio_start, audio_end, 1).unsqueeze(1) + indices.unsqueeze(0)
+ center_indices = torch.clamp(center_indices, min=0, max=encoded_audio_in.shape[0] - 1)
+ audio_emb = encoded_audio_in[center_indices].unsqueeze(0)
+ audio_embs.append(audio_emb)
+
+ return torch.cat(audio_embs, dim=0)
+
+
+def project_audio_features(audio_proj, encoded_audio, audio_start, audio_end):
+ audio_embs = get_audio_embeds(encoded_audio, audio_start, audio_end)
+
+ first_frame_audio_emb_s = audio_embs[:, :1, ...]
+ latter_frame_audio_emb = audio_embs[:, 1:, ...]
+ latter_frame_audio_emb = rearrange(latter_frame_audio_emb, "b (n_t n) w s c -> b n_t n w s c", n=4)
+
+ middle_index = audio_proj.seq_len // 2
+
+ latter_first_frame_audio_emb = latter_frame_audio_emb[:, :, :1, :middle_index+1, ...]
+ latter_first_frame_audio_emb = rearrange(latter_first_frame_audio_emb, "b n_t n w s c -> b n_t (n w) s c")
+ latter_last_frame_audio_emb = latter_frame_audio_emb[:, :, -1:, middle_index:, ...]
+ latter_last_frame_audio_emb = rearrange(latter_last_frame_audio_emb, "b n_t n w s c -> b n_t (n w) s c")
+ latter_middle_frame_audio_emb = latter_frame_audio_emb[:, :, 1:-1, middle_index:middle_index+1, ...]
+ latter_middle_frame_audio_emb = rearrange(latter_middle_frame_audio_emb, "b n_t n w s c -> b n_t (n w) s c")
+ latter_frame_audio_emb_s = torch.cat([latter_first_frame_audio_emb, latter_middle_frame_audio_emb, latter_last_frame_audio_emb], dim=2)
+
+ audio_emb = audio_proj(first_frame_audio_emb_s, latter_frame_audio_emb_s)
+ audio_emb = torch.cat(audio_emb.split(1), dim=2)
+
+ return audio_emb
+
+
+class RotaryPositionalEmbedding1D(torch.nn.Module):
+ def __init__(self,
+ head_dim,
+ ):
+ super().__init__()
+ self.head_dim = head_dim
+ self.base = 10000
+
+ def precompute_freqs_cis_1d(self, pos_indices):
+ freqs = 1.0 / (self.base ** (torch.arange(0, self.head_dim, 2)[: (self.head_dim // 2)].float() / self.head_dim))
+ freqs = freqs.to(pos_indices.device)
+ freqs = torch.einsum("..., f -> ... f", pos_indices.float(), freqs)
+ freqs = repeat(freqs, "... n -> ... (n r)", r=2)
+ return freqs
+
+ def forward(self, x, pos_indices):
+ freqs_cis = self.precompute_freqs_cis_1d(pos_indices)
+
+ x_ = x.float()
+
+ freqs_cis = freqs_cis.float().to(x.device)
+ cos, sin = freqs_cis.cos(), freqs_cis.sin()
+ cos, sin = rearrange(cos, 'n d -> 1 1 n d'), rearrange(sin, 'n d -> 1 1 n d')
+ x_ = (x_ * cos) + (rotate_half(x_) * sin)
+
+ return x_.type_as(x)
+
+class SingleStreamAttention(torch.nn.Module):
+ def __init__(
+ self,
+ dim: int,
+ encoder_hidden_states_dim: int,
+ num_heads: int,
+ qkv_bias: bool,
+ device=None, dtype=None, operations=None
+ ) -> None:
+ super().__init__()
+ self.dim = dim
+ self.encoder_hidden_states_dim = encoder_hidden_states_dim
+ self.num_heads = num_heads
+ self.head_dim = dim // num_heads
+
+ self.q_linear = operations.Linear(dim, dim, bias=qkv_bias, device=device, dtype=dtype)
+ self.proj = operations.Linear(dim, dim, device=device, dtype=dtype)
+ self.kv_linear = operations.Linear(encoder_hidden_states_dim, dim * 2, bias=qkv_bias, device=device, dtype=dtype)
+
+ def forward(self, x: torch.Tensor, encoder_hidden_states: torch.Tensor, shape=None) -> torch.Tensor:
+ N_t, N_h, N_w = shape
+
+ expected_tokens = N_t * N_h * N_w
+ actual_tokens = x.shape[1]
+ x_extra = None
+
+ if actual_tokens != expected_tokens:
+ x_extra = x[:, -N_h * N_w:, :]
+ x = x[:, :-N_h * N_w, :]
+ N_t = N_t - 1
+
+ B = x.shape[0]
+ S = N_h * N_w
+ x = x.view(B * N_t, S, self.dim)
+
+ # get q for hidden_state
+ q = self.q_linear(x).view(B * N_t, S, self.num_heads, self.head_dim)
+
+ # get kv from encoder_hidden_states # shape: (B, N, num_heads, head_dim)
+ kv = self.kv_linear(encoder_hidden_states)
+ encoder_k, encoder_v = kv.view(B * N_t, encoder_hidden_states.shape[1], 2, self.num_heads, self.head_dim).unbind(2)
+
+ #print("q.shape", q.shape) #torch.Size([21, 1024, 40, 128])
+ x = optimized_attention(
+ q.transpose(1, 2),
+ encoder_k.transpose(1, 2),
+ encoder_v.transpose(1, 2),
+ heads=self.num_heads, skip_reshape=True, skip_output_reshape=True).transpose(1, 2)
+
+ # linear transform
+ x = self.proj(x.reshape(B * N_t, S, self.dim))
+ x = x.view(B, N_t * S, self.dim)
+
+ if x_extra is not None:
+ x = torch.cat([x, torch.zeros_like(x_extra)], dim=1)
+
+ return x
+
+class SingleStreamMultiAttention(SingleStreamAttention):
+ def __init__(
+ self,
+ dim: int,
+ encoder_hidden_states_dim: int,
+ num_heads: int,
+ qkv_bias: bool,
+ class_range: int = 24,
+ class_interval: int = 4,
+ device=None, dtype=None, operations=None
+ ) -> None:
+ super().__init__(
+ dim=dim,
+ encoder_hidden_states_dim=encoder_hidden_states_dim,
+ num_heads=num_heads,
+ qkv_bias=qkv_bias,
+ device=device,
+ dtype=dtype,
+ operations=operations
+ )
+
+ # Rotary-embedding layout parameters
+ self.class_interval = class_interval
+ self.class_range = class_range
+ self.max_humans = self.class_range // self.class_interval
+
+ # Constant bucket used for background tokens
+ self.rope_bak = int(self.class_range // 2)
+
+ self.rope_1d = RotaryPositionalEmbedding1D(self.head_dim)
+
+ def forward(
+ self,
+ x: torch.Tensor,
+ encoder_hidden_states: torch.Tensor,
+ shape=None,
+ x_ref_attn_map=None
+ ) -> torch.Tensor:
+ encoder_hidden_states = encoder_hidden_states.squeeze(0).to(x.device)
+ human_num = x_ref_attn_map.shape[0] if x_ref_attn_map is not None else 1
+ # Single-speaker fall-through
+ if human_num <= 1:
+ return super().forward(x, encoder_hidden_states, shape)
+
+ N_t, N_h, N_w = shape
+
+ x_extra = None
+ if x.shape[0] * N_t != encoder_hidden_states.shape[0]:
+ x_extra = x[:, -N_h * N_w:, :]
+ x = x[:, :-N_h * N_w, :]
+ N_t = N_t - 1
+ x = rearrange(x, "B (N_t S) C -> (B N_t) S C", N_t=N_t)
+
+ # Query projection
+ B, N, C = x.shape
+ q = self.q_linear(x)
+ q = q.view(B, N, self.num_heads, self.head_dim).permute(0, 2, 1, 3)
+
+ # Use `class_range` logic for 2 speakers
+ rope_h1 = (0, self.class_interval)
+ rope_h2 = (self.class_range - self.class_interval, self.class_range)
+ rope_bak = int(self.class_range // 2)
+
+ # Normalize and scale attention maps for each speaker
+ max_values = x_ref_attn_map.max(1).values[:, None, None]
+ min_values = x_ref_attn_map.min(1).values[:, None, None]
+ max_min_values = torch.cat([max_values, min_values], dim=2)
+
+ human1_max_value, human1_min_value = max_min_values[0, :, 0].max(), max_min_values[0, :, 1].min()
+ human2_max_value, human2_min_value = max_min_values[1, :, 0].max(), max_min_values[1, :, 1].min()
+
+ human1 = normalize_and_scale(x_ref_attn_map[0], (human1_min_value, human1_max_value), rope_h1)
+ human2 = normalize_and_scale(x_ref_attn_map[1], (human2_min_value, human2_max_value), rope_h2)
+ back = torch.full((x_ref_attn_map.size(1),), rope_bak, dtype=human1.dtype, device=human1.device)
+
+ # Token-wise speaker dominance
+ max_indices = x_ref_attn_map.argmax(dim=0)
+ normalized_map = torch.stack([human1, human2, back], dim=1)
+ normalized_pos = normalized_map[torch.arange(x_ref_attn_map.size(1)), max_indices]
+
+ # Apply rotary to Q
+ q = rearrange(q, "(B N_t) H S C -> B H (N_t S) C", N_t=N_t)
+ q = self.rope_1d(q, normalized_pos)
+ q = rearrange(q, "B H (N_t S) C -> (B N_t) H S C", N_t=N_t)
+
+ # Keys / Values
+ _, N_a, _ = encoder_hidden_states.shape
+ encoder_kv = self.kv_linear(encoder_hidden_states)
+ encoder_kv = encoder_kv.view(B, N_a, 2, self.num_heads, self.head_dim).permute(2, 0, 3, 1, 4)
+ encoder_k, encoder_v = encoder_kv.unbind(0)
+
+ # Rotary for keys – assign centre of each speaker bucket to its context tokens
+ per_frame = torch.zeros(N_a, dtype=encoder_k.dtype, device=encoder_k.device)
+ per_frame[: per_frame.size(0) // 2] = (rope_h1[0] + rope_h1[1]) / 2
+ per_frame[per_frame.size(0) // 2 :] = (rope_h2[0] + rope_h2[1]) / 2
+ encoder_pos = torch.cat([per_frame] * N_t, dim=0)
+
+ encoder_k = rearrange(encoder_k, "(B N_t) H S C -> B H (N_t S) C", N_t=N_t)
+ encoder_k = self.rope_1d(encoder_k, encoder_pos)
+ encoder_k = rearrange(encoder_k, "B H (N_t S) C -> (B N_t) H S C", N_t=N_t)
+
+ # Final attention
+ q = rearrange(q, "B H M K -> B M H K")
+ encoder_k = rearrange(encoder_k, "B H M K -> B M H K")
+ encoder_v = rearrange(encoder_v, "B H M K -> B M H K")
+
+ x = optimized_attention(
+ q.transpose(1, 2),
+ encoder_k.transpose(1, 2),
+ encoder_v.transpose(1, 2),
+ heads=self.num_heads, skip_reshape=True, skip_output_reshape=True).transpose(1, 2)
+
+ # Linear projection
+ x = x.reshape(B, N, C)
+ x = self.proj(x)
+
+ # Restore original layout
+ x = rearrange(x, "(B N_t) S C -> B (N_t S) C", N_t=N_t)
+ if x_extra is not None:
+ x = torch.cat([x, torch.zeros_like(x_extra)], dim=1)
+
+ return x
+
+
+class MultiTalkAudioProjModel(torch.nn.Module):
+ def __init__(
+ self,
+ seq_len: int = 5,
+ seq_len_vf: int = 12,
+ blocks: int = 12,
+ channels: int = 768,
+ intermediate_dim: int = 512,
+ out_dim: int = 768,
+ context_tokens: int = 32,
+ device=None, dtype=None, operations=None
+ ):
+ super().__init__()
+
+ self.seq_len = seq_len
+ self.blocks = blocks
+ self.channels = channels
+ self.input_dim = seq_len * blocks * channels
+ self.input_dim_vf = seq_len_vf * blocks * channels
+ self.intermediate_dim = intermediate_dim
+ self.context_tokens = context_tokens
+ self.out_dim = out_dim
+
+ # define multiple linear layers
+ self.proj1 = operations.Linear(self.input_dim, intermediate_dim, device=device, dtype=dtype)
+ self.proj1_vf = operations.Linear(self.input_dim_vf, intermediate_dim, device=device, dtype=dtype)
+ self.proj2 = operations.Linear(intermediate_dim, intermediate_dim, device=device, dtype=dtype)
+ self.proj3 = operations.Linear(intermediate_dim, context_tokens * out_dim, device=device, dtype=dtype)
+ self.norm = operations.LayerNorm(out_dim, device=device, dtype=dtype)
+
+ def forward(self, audio_embeds, audio_embeds_vf):
+ video_length = audio_embeds.shape[1] + audio_embeds_vf.shape[1]
+ B, _, _, S, C = audio_embeds.shape
+
+ # process audio of first frame
+ audio_embeds = rearrange(audio_embeds, "bz f w b c -> (bz f) w b c")
+ batch_size, window_size, blocks, channels = audio_embeds.shape
+ audio_embeds = audio_embeds.view(batch_size, window_size * blocks * channels)
+
+ # process audio of latter frame
+ audio_embeds_vf = rearrange(audio_embeds_vf, "bz f w b c -> (bz f) w b c")
+ batch_size_vf, window_size_vf, blocks_vf, channels_vf = audio_embeds_vf.shape
+ audio_embeds_vf = audio_embeds_vf.view(batch_size_vf, window_size_vf * blocks_vf * channels_vf)
+
+ # first projection
+ audio_embeds = torch.relu(self.proj1(audio_embeds))
+ audio_embeds_vf = torch.relu(self.proj1_vf(audio_embeds_vf))
+ audio_embeds = rearrange(audio_embeds, "(bz f) c -> bz f c", bz=B)
+ audio_embeds_vf = rearrange(audio_embeds_vf, "(bz f) c -> bz f c", bz=B)
+ audio_embeds_c = torch.concat([audio_embeds, audio_embeds_vf], dim=1)
+ batch_size_c, N_t, C_a = audio_embeds_c.shape
+ audio_embeds_c = audio_embeds_c.view(batch_size_c*N_t, C_a)
+
+ # second projection
+ audio_embeds_c = torch.relu(self.proj2(audio_embeds_c))
+
+ context_tokens = self.proj3(audio_embeds_c).reshape(batch_size_c*N_t, self.context_tokens, self.out_dim)
+
+ # normalization and reshape
+ context_tokens = self.norm(context_tokens)
+ context_tokens = rearrange(context_tokens, "(bz f) m c -> bz f m c", f=video_length)
+
+ return context_tokens
+
+
+class WanMultiTalkAttentionBlock(torch.nn.Module):
+ def __init__(self, in_dim=5120, out_dim=768, device=None, dtype=None, operations=None):
+ super().__init__()
+ self.audio_cross_attn = SingleStreamMultiAttention(in_dim, out_dim, num_heads=40, qkv_bias=True, device=device, dtype=dtype, operations=operations)
+ self.norm_x = operations.LayerNorm(in_dim, device=device, dtype=dtype, elementwise_affine=True)
+
+
+class MultiTalkGetAttnMapPatch:
+ def __init__(self, ref_target_masks=None):
+ self.ref_target_masks = ref_target_masks
+
+ def __call__(self, kwargs):
+ transformer_options = kwargs.get("transformer_options", {})
+ x = kwargs["x"]
+
+ if self.ref_target_masks is not None:
+ x_ref_attn_map = get_attn_map_with_target(kwargs["q"], kwargs["k"], transformer_options["grid_sizes"], ref_target_masks=self.ref_target_masks.to(x.device))
+ transformer_options["x_ref_attn_map"] = x_ref_attn_map
+ return x
+
+
+class MultiTalkCrossAttnPatch:
+ def __init__(self, model_patch, audio_scale=1.0, ref_target_masks=None):
+ self.model_patch = model_patch
+ self.audio_scale = audio_scale
+ self.ref_target_masks = ref_target_masks
+
+ def __call__(self, kwargs):
+ transformer_options = kwargs.get("transformer_options", {})
+ block_idx = transformer_options.get("block_index", None)
+ x = kwargs["x"]
+ if block_idx is None:
+ return torch.zeros_like(x)
+
+ audio_embeds = transformer_options.get("audio_embeds")
+ x_ref_attn_map = transformer_options.pop("x_ref_attn_map", None)
+
+ norm_x = self.model_patch.model.blocks[block_idx].norm_x(x)
+ x_audio = self.model_patch.model.blocks[block_idx].audio_cross_attn(
+ norm_x, audio_embeds.to(x.dtype),
+ shape=transformer_options["grid_sizes"],
+ x_ref_attn_map=x_ref_attn_map
+ )
+ x = x + x_audio * self.audio_scale
+ return x
+
+ def models(self):
+ return [self.model_patch]
+
+class MultiTalkApplyModelWrapper:
+ def __init__(self, init_latents):
+ self.init_latents = init_latents
+
+ def __call__(self, executor, x, *args, **kwargs):
+ x[:, :, :self.init_latents.shape[2]] = self.init_latents.to(x)
+ samples = executor(x, *args, **kwargs)
+ return samples
+
+
+class InfiniteTalkOuterSampleWrapper:
+ def __init__(self, motion_frames_latent, model_patch, is_extend=False):
+ self.motion_frames_latent = motion_frames_latent
+ self.model_patch = model_patch
+ self.is_extend = is_extend
+
+ def __call__(self, executor, *args, **kwargs):
+ model_patcher = executor.class_obj.model_patcher
+ model_options = executor.class_obj.model_options
+ process_latent_in = model_patcher.model.process_latent_in
+
+ # for InfiniteTalk, model input first latent(s) need to always be replaced on every step
+ if self.motion_frames_latent is not None:
+ wrappers = model_options["transformer_options"]["wrappers"]
+ w = wrappers.setdefault(comfy.patcher_extension.WrappersMP.APPLY_MODEL, {})
+ w["MultiTalk_apply_model"] = [MultiTalkApplyModelWrapper(process_latent_in(self.motion_frames_latent))]
+
+ # run the sampling process
+ result = executor(*args, **kwargs)
+
+ # insert motion frames before decoding
+ if self.is_extend:
+ overlap = self.motion_frames_latent.shape[2]
+ result = torch.cat([self.motion_frames_latent.to(result), result[:, :, overlap:]], dim=2)
+
+ return result
+
+ def to(self, device_or_dtype):
+ if isinstance(device_or_dtype, torch.device):
+ if self.motion_frames_latent is not None:
+ self.motion_frames_latent = self.motion_frames_latent.to(device_or_dtype)
+ return self
diff --git a/ComfyUI/comfy/ldm/wan/model_wandancer.py b/ComfyUI/comfy/ldm/wan/model_wandancer.py
new file mode 100644
index 0000000000000000000000000000000000000000..aeec1d72521b95e3ad70c3c9e9892f07e863ce30
--- /dev/null
+++ b/ComfyUI/comfy/ldm/wan/model_wandancer.py
@@ -0,0 +1,261 @@
+import torch
+import torch.nn as nn
+import comfy
+from comfy.ldm.modules.attention import optimized_attention
+from comfy.ldm.flux.math import apply_rope1
+from comfy.ldm.flux.layers import EmbedND
+
+from .model import AudioInjector_WAN, WanModel, MLPProj, Head, sinusoidal_embedding_1d
+
+
+class MusicSelfAttention(nn.Module):
+ def __init__(self, dim, num_heads, device=None, dtype=None, operations=None):
+ assert dim % num_heads == 0
+ super().__init__()
+ self.embed_dim = dim
+ self.num_heads = num_heads
+ self.head_dim = dim // num_heads
+
+ self.q_proj = operations.Linear(dim, dim, device=device, dtype=dtype)
+ self.k_proj = operations.Linear(dim, dim, device=device, dtype=dtype)
+ self.v_proj = operations.Linear(dim, dim, device=device, dtype=dtype)
+ self.out_proj = operations.Linear(dim, dim, device=device, dtype=dtype)
+
+ def forward(self, x, freqs):
+ b, s, n, d = *x.shape[:2], self.num_heads, self.head_dim
+
+ q = self.q_proj(x).view(b, s, n, d)
+ q = apply_rope1(q, freqs)
+
+ k = self.k_proj(x).view(b, s, n, d)
+ k = apply_rope1(k, freqs)
+
+ x = optimized_attention(
+ q.view(b, s, n * d),
+ k.view(b, s, n * d),
+ self.v_proj(x).view(b, s, n * d),
+ heads=self.num_heads,
+ )
+
+ return self.out_proj(x)
+
+
+class MusicEncoderLayer(nn.Module):
+ def __init__(self, dim: int, num_heads: int, ffn_dim: int, device=None, dtype=None, operations=None):
+ super().__init__()
+ self.self_attn = MusicSelfAttention(dim, num_heads, device=device, dtype=dtype, operations=operations)
+
+ self.linear1 = operations.Linear(dim, ffn_dim, device=device, dtype=dtype)
+ self.linear2 = operations.Linear(ffn_dim, dim, device=device, dtype=dtype)
+
+ self.norm1 = operations.LayerNorm(dim, device=device, dtype=dtype)
+ self.norm2 = operations.LayerNorm(dim, device=device, dtype=dtype)
+
+ def forward(self, x: torch.Tensor, freqs: torch.Tensor) -> torch.Tensor:
+ x = x + self.self_attn(self.norm1(x), freqs=freqs)
+ x = x + self.linear2(torch.nn.functional.gelu(self.linear1(self.norm2(x)))) # ffn
+ return x
+
+
+class WanDancerModel(WanModel):
+ def __init__(self,
+ model_type='wandancer',
+ patch_size=(1, 2, 2),
+ text_len=512,
+ in_dim=16,
+ dim=5120,
+ ffn_dim=8192,
+ freq_dim=256,
+ text_dim=4096,
+ out_dim=16,
+ num_heads=16,
+ num_layers=40,
+ window_size=(-1, -1),
+ qk_norm=True,
+ cross_attn_norm=True,
+ eps=1e-6,
+ in_dim_ref_conv=None,
+ image_model=None,
+ device=None, dtype=None, operations=None,
+ audio_inject_layers=[0, 4, 8, 12, 16, 20, 24, 27],
+ music_dim = 256,
+ music_heads = 4,
+ music_feature_dim = 35,
+ music_latent_dim = 256
+ ):
+
+ super().__init__(model_type='i2v', patch_size=patch_size, text_len=text_len, in_dim=in_dim, dim=dim, ffn_dim=ffn_dim, freq_dim=freq_dim, text_dim=text_dim, out_dim=out_dim,
+ num_heads=num_heads, num_layers=num_layers, window_size=window_size, qk_norm=qk_norm, cross_attn_norm=cross_attn_norm, eps=eps, image_model=image_model, in_dim_ref_conv=in_dim_ref_conv,
+ device=device, dtype=dtype, operations=operations)
+
+ self.dtype = dtype
+ operation_settings = {"operations": operations, "device": device, "dtype": dtype}
+
+ self.patch_embedding_global = operations.Conv3d(in_dim, dim, kernel_size=patch_size, stride=patch_size, device=operation_settings.get("device"), dtype=torch.float32)
+ self.img_emb_refimage = MLPProj(1280, dim, operation_settings=operation_settings)
+ self.head_global = Head(dim, out_dim, patch_size, eps, operation_settings=operation_settings)
+
+ self.music_injector = AudioInjector_WAN(
+ dim=self.dim,
+ num_heads=self.num_heads,
+ inject_layer=audio_inject_layers,
+ root_net=self,
+ enable_adain=False,
+ dtype=dtype, device=device, operations=operations
+ )
+
+ self.music_projection = operations.Linear(music_feature_dim, music_latent_dim, device=device, dtype=dtype)
+ self.music_encoder = nn.ModuleList([MusicEncoderLayer(dim=music_dim, num_heads=music_heads, ffn_dim=1024, device=device, dtype=dtype, operations=operations) for _ in range(2)])
+ music_head_dim = music_dim // music_heads
+ self.music_rope_embedder = EmbedND(dim=music_head_dim, theta=10000.0, axes_dim=[music_head_dim])
+
+ def forward_orig(self, x, t, context, clip_fea=None, clip_fea_ref=None, freqs=None, audio_embed=None, fps=30, audio_inject_scale=1.0, transformer_options={}, **kwargs):
+ # embeddings
+ x_input = x
+ if int(fps + 0.5) != 30:
+ x = self.patch_embedding_global(x.float()).to(x.dtype)
+ else:
+ x = self.patch_embedding(x.float()).to(x.dtype)
+
+ grid_sizes = x.shape[2:]
+ latent_frames = grid_sizes[0]
+ transformer_options["grid_sizes"] = grid_sizes
+ x = x.flatten(2).transpose(1, 2)
+ seq_len = x.size(1)
+
+ # time embeddings
+ e = self.time_embedding(sinusoidal_embedding_1d(self.freq_dim, t.flatten()).to(dtype=x[0].dtype))
+ e = e.reshape(t.shape[0], -1, e.shape[-1])
+ e0 = self.time_projection(e).unflatten(2, (6, self.dim))
+
+ full_ref = None
+ img_offset = 0
+ if self.ref_conv is not None: # model has the weight, but this wasn't used in the original pipeline
+ full_ref = kwargs.get("reference_latent", None)
+ if full_ref is not None:
+ full_ref = self.ref_conv(full_ref).flatten(2).transpose(1, 2)
+ x = torch.concat((full_ref, x), dim=1)
+ img_offset = full_ref.shape[1]
+
+ # context
+ context = self.text_embedding(context)
+
+ audio_emb = None
+ if audio_embed is not None: # encode music feature,[1, frame_num, 35] -> [1, F*8, dim]
+ music_feature = self.music_projection(audio_embed)
+
+ music_seq_len = music_feature.shape[1]
+ music_ids = torch.arange(music_seq_len, device=music_feature.device, dtype=music_feature.dtype).reshape(1, -1, 1) # create 1D position IDs
+ music_freqs = self.music_rope_embedder(music_ids).movedim(1, 2)
+
+ # apply encoder layers
+ for layer in self.music_encoder:
+ music_feature = layer(music_feature, music_freqs)
+
+ # interpolate
+ audio_emb = torch.nn.functional.interpolate(music_feature.unsqueeze(1), size=(latent_frames * 8, self.dim), mode='bilinear').squeeze(1)
+
+ context_img_len = 0
+ if self.img_emb is not None and clip_fea is not None:
+ context_clip = self.img_emb(clip_fea) # bs x 257 x dim
+ context = torch.cat([context_clip, context], dim=1)
+ context_img_len += clip_fea.shape[-2]
+ if self.img_emb_refimage is not None and clip_fea_ref is not None:
+ context_clip_ref = self.img_emb_refimage(clip_fea_ref)
+ context = torch.cat([context_clip_ref, context], dim=1)
+ context_img_len += clip_fea_ref.shape[-2]
+
+ patches_replace = transformer_options.get("patches_replace", {})
+ patches = transformer_options.get("patches", {})
+ blocks_replace = patches_replace.get("dit", {})
+ transformer_options["total_blocks"] = len(self.blocks)
+ transformer_options["block_type"] = "double"
+ for i, block in enumerate(self.blocks):
+ transformer_options["block_index"] = i
+ if ("double_block", i) in blocks_replace:
+ def block_wrap(args):
+ out = {}
+ out["img"] = block(args["img"], context=args["txt"], e=args["vec"], freqs=args["pe"], context_img_len=context_img_len, transformer_options=args["transformer_options"])
+ return out
+ out = blocks_replace[("double_block", i)]({"img": x, "txt": context, "vec": e0, "pe": freqs, "transformer_options": transformer_options}, {"original_block": block_wrap})
+ x = out["img"]
+ else:
+ x = block(x, e=e0, freqs=freqs, context=context, context_img_len=context_img_len, transformer_options=transformer_options)
+
+ if "double_block" in patches:
+ for p in patches["double_block"]:
+ out = p({"img": x, "x": x_input, "vec": e, "block_index": i, "img_offset": img_offset, "transformer_options": transformer_options})
+ x = out["img"]
+
+ if audio_emb is not None:
+ x = self.music_injector(x, i, audio_emb, audio_emb_global=None, seq_len=seq_len, scale=audio_inject_scale)
+
+ # head
+ if int(fps + 0.5) != 30:
+ x = self.head_global(x, e)
+ else:
+ x = self.head(x, e)
+
+ if full_ref is not None:
+ x = x[:, full_ref.shape[1]:]
+
+ # unpatchify
+ x = self.unpatchify(x, grid_sizes)
+ return x
+
+ def _forward(self, x, timestep, context, clip_fea=None, time_dim_concat=None, transformer_options={}, clip_fea_ref=None, fps=30, audio_inject_scale=1.0, **kwargs):
+ bs, c, t, h, w = x.shape
+ x = comfy.ldm.common_dit.pad_to_patch_size(x, self.patch_size)
+
+ t_len = t
+ if time_dim_concat is not None:
+ time_dim_concat = comfy.ldm.common_dit.pad_to_patch_size(time_dim_concat, self.patch_size)
+ x = torch.cat([x, time_dim_concat], dim=2)
+ t_len = x.shape[2]
+
+ freqs = self.rope_encode(t_len, h, w, device=x.device, dtype=x.dtype, fps=fps, transformer_options=transformer_options)
+ return self.forward_orig(x, timestep, context, clip_fea=clip_fea, clip_fea_ref=clip_fea_ref, freqs=freqs, fps=fps, audio_inject_scale=audio_inject_scale, transformer_options=transformer_options, **kwargs)[:, :, :t, :h, :w]
+
+ def rope_encode(self, t, h, w, t_start=0, steps_t=None, steps_h=None, steps_w=None, fps=30, device=None, dtype=None, transformer_options={}):
+ patch_size = self.patch_size
+ t_len = ((t + (patch_size[0] // 2)) // patch_size[0])
+ h_len = ((h + (patch_size[1] // 2)) // patch_size[1])
+ w_len = ((w + (patch_size[2] // 2)) // patch_size[2])
+
+ if steps_t is None:
+ steps_t = t_len
+ if steps_h is None:
+ steps_h = h_len
+ if steps_w is None:
+ steps_w = w_len
+
+ h_start = 0
+ w_start = 0
+ rope_options = transformer_options.get("rope_options", None)
+ if rope_options is not None:
+ t_len = (t_len - 1.0) * rope_options.get("scale_t", 1.0) + 1.0
+ h_len = (h_len - 1.0) * rope_options.get("scale_y", 1.0) + 1.0
+ w_len = (w_len - 1.0) * rope_options.get("scale_x", 1.0) + 1.0
+
+ t_start += rope_options.get("shift_t", 0.0)
+ h_start += rope_options.get("shift_y", 0.0)
+ w_start += rope_options.get("shift_x", 0.0)
+
+ img_ids = torch.zeros((steps_t, steps_h, steps_w, 3), device=device, dtype=dtype)
+
+ if int(fps + 0.5) != 30:
+ time_scale = 30.0 / fps # how many time units each frame represents relative to 30fps
+ positions_new = torch.arange(steps_t, device=device, dtype=dtype) * time_scale + t_start
+ total_frames_at_30fps = int(time_scale * steps_t + 0.5)
+ positions_new[-1] = t_start + (total_frames_at_30fps - 1)
+
+ img_ids[:, :, :, 0] = img_ids[:, :, :, 0] + positions_new.reshape(-1, 1, 1)
+ else:
+ img_ids[:, :, :, 0] = img_ids[:, :, :, 0] + torch.linspace(t_start, t_start + (t_len - 1), steps=steps_t, device=device, dtype=dtype).reshape(-1, 1, 1)
+
+ img_ids[:, :, :, 1] = img_ids[:, :, :, 1] + torch.linspace(h_start, h_start + (h_len - 1), steps=steps_h, device=device, dtype=dtype).reshape(1, -1, 1)
+ img_ids[:, :, :, 2] = img_ids[:, :, :, 2] + torch.linspace(w_start, w_start + (w_len - 1), steps=steps_w, device=device, dtype=dtype).reshape(1, 1, -1)
+ img_ids = img_ids.reshape(1, -1, img_ids.shape[-1])
+
+ freqs = self.rope_embedder(img_ids).movedim(1, 2)
+ return freqs
diff --git a/ComfyUI/comfy/ldm/wan/uni3c.py b/ComfyUI/comfy/ldm/wan/uni3c.py
new file mode 100644
index 0000000000000000000000000000000000000000..827ad233995d147d8bf79d467232a18d01119970
--- /dev/null
+++ b/ComfyUI/comfy/ldm/wan/uni3c.py
@@ -0,0 +1,149 @@
+# Uni3C controlnet for Wan 2.1: https://github.com/ewrfcas/Uni3C
+# Converted from the original diffusers based implementation.
+import torch
+import torch.nn as nn
+
+from comfy.ldm.flux.layers import EmbedND
+from .model import WanSelfAttention
+
+
+class Uni3CLayerNormZero(nn.Module):
+ def __init__(
+ self,
+ conditioning_dim,
+ embedding_dim,
+ eps=1e-5,
+ device=None, dtype=None, operations=None
+ ):
+ super().__init__()
+ self.silu = nn.SiLU()
+ self.linear = operations.Linear(conditioning_dim, 3 * embedding_dim, device=device, dtype=dtype)
+ self.norm = operations.LayerNorm(embedding_dim, eps=eps, elementwise_affine=True, device=device, dtype=dtype)
+
+ def forward(self, x, temb):
+ shift, scale, gate = self.linear(self.silu(temb)).chunk(3, dim=1)
+ x = self.norm(x) * (1 + scale)[:, None, :] + shift[:, None, :]
+ return x, gate[:, None, :]
+
+
+class Uni3CAttentionBlock(nn.Module):
+ def __init__(
+ self,
+ dim,
+ ffn_dim,
+ num_heads,
+ time_embed_dim=5120,
+ eps=1e-6,
+ device=None, dtype=None, operations=None
+ ):
+ super().__init__()
+ operation_settings = {"operations": operations, "device": device, "dtype": dtype}
+ self.norm1 = Uni3CLayerNormZero(time_embed_dim, dim, device=device, dtype=dtype, operations=operations)
+ self.self_attn = WanSelfAttention(dim, num_heads, qk_norm=True, eps=eps, operation_settings=operation_settings)
+ self.norm2 = Uni3CLayerNormZero(time_embed_dim, dim, device=device, dtype=dtype, operations=operations)
+ self.ffn = nn.Sequential(
+ operations.Linear(dim, ffn_dim, device=device, dtype=dtype), nn.GELU(approximate='tanh'),
+ operations.Linear(ffn_dim, dim, device=device, dtype=dtype))
+
+ def forward(self, x, temb, freqs):
+ norm_x, gate_msa = self.norm1(x, temb)
+ x = x + gate_msa * self.self_attn(norm_x, freqs)
+ norm_x, gate_ff = self.norm2(x, temb)
+ x = x + gate_ff * self.ffn(norm_x)
+ return x
+
+
+class MaskCamEmbed(nn.Module):
+ def __init__(
+ self,
+ add_channels=7,
+ mid_channels=256,
+ conv_out_dim=5120,
+ device=None, dtype=None, operations=None
+ ):
+ super().__init__()
+ self.mask_padding = [0, 0, 0, 0, 3, 0] # first frame conditioning
+ self.mask_proj = nn.Sequential(
+ operations.Conv3d(add_channels, mid_channels, kernel_size=(4, 8, 8), stride=(4, 8, 8), device=device, dtype=dtype),
+ operations.GroupNorm(mid_channels // 8, mid_channels, device=device, dtype=dtype),
+ nn.SiLU())
+ self.mask_zero_proj = operations.Conv3d(mid_channels, conv_out_dim, kernel_size=(1, 2, 2), stride=(1, 2, 2), device=device, dtype=dtype)
+
+ def forward(self, add_inputs):
+ add_padded = torch.nn.functional.pad(add_inputs, self.mask_padding, mode="constant", value=0)
+ add_embeds = self.mask_proj(add_padded)
+ add_embeds = self.mask_zero_proj(add_embeds)
+ add_embeds = add_embeds.flatten(2).transpose(1, 2)
+ return add_embeds
+
+
+class WanUni3CControlnet(nn.Module):
+ def __init__(
+ self,
+ in_channels=36,
+ conv_out_dim=5120,
+ dim=1024,
+ ffn_dim=8192,
+ num_heads=16,
+ num_layers=20,
+ time_embed_dim=5120,
+ out_proj_dim=5120,
+ add_channels=7,
+ mid_channels=256,
+ device=None, dtype=None, operations=None
+ ):
+ super().__init__()
+ patch_size = (1, 2, 2)
+ self.num_layers = num_layers
+
+ self.controlnet_patch_embedding = operations.Conv3d(
+ in_channels, conv_out_dim, kernel_size=patch_size, stride=patch_size, device=device, dtype=torch.float32)
+ self.controlnet_mask_embedding = MaskCamEmbed(add_channels, mid_channels, conv_out_dim, device=device, dtype=dtype, operations=operations)
+
+ if conv_out_dim != dim:
+ self.proj_in = operations.Linear(conv_out_dim, dim, device=device, dtype=dtype)
+ else:
+ self.proj_in = nn.Identity()
+
+ self.controlnet_blocks = nn.ModuleList([
+ Uni3CAttentionBlock(dim, ffn_dim, num_heads, time_embed_dim, device=device, dtype=dtype, operations=operations)
+ for _ in range(num_layers)])
+ self.proj_out = nn.ModuleList([
+ operations.Linear(dim, out_proj_dim, device=device, dtype=dtype)
+ for _ in range(num_layers)])
+
+ head_dim = dim // num_heads
+ self.rope_embedder = EmbedND(dim=head_dim, theta=10000.0, axes_dim=[head_dim - 4 * (head_dim // 6), 2 * (head_dim // 6), 2 * (head_dim // 6)])
+
+ def rope_encode(self, t_len, h_len, w_len, device=None, dtype=None):
+ img_ids = torch.zeros((t_len, h_len, w_len, 3), device=device, dtype=dtype)
+ img_ids[:, :, :, 0] = img_ids[:, :, :, 0] + torch.arange(t_len, device=device, dtype=dtype).reshape(-1, 1, 1)
+ img_ids[:, :, :, 1] = img_ids[:, :, :, 1] + torch.arange(h_len, device=device, dtype=dtype).reshape(1, -1, 1)
+ img_ids[:, :, :, 2] = img_ids[:, :, :, 2] + torch.arange(w_len, device=device, dtype=dtype).reshape(1, 1, -1)
+ img_ids = img_ids.reshape(1, -1, img_ids.shape[-1])
+ freqs = self.rope_embedder(img_ids).movedim(1, 2)
+ return freqs
+
+ def process_input(self, control_input, render_mask=None, camera_embedding=None):
+ # render_mask/camera_embedding are the checkpoint's extra conditioning path, not wired up yet
+ hidden = self.controlnet_patch_embedding(control_input.float()).to(control_input.dtype)
+ t_len, h_len, w_len = hidden.shape[2:]
+ freqs = self.rope_encode(t_len, h_len, w_len, device=hidden.device, dtype=hidden.dtype)
+ hidden = hidden.flatten(2).transpose(1, 2)
+
+ add_inputs = None
+ if camera_embedding is not None and render_mask is not None:
+ add_inputs = torch.cat([render_mask, camera_embedding], dim=1)
+ elif render_mask is not None:
+ add_inputs = render_mask
+
+ if add_inputs is not None:
+ hidden = hidden + self.controlnet_mask_embedding(add_inputs.to(hidden.dtype))
+
+ hidden = self.proj_in(hidden)
+ return hidden, freqs
+
+ def forward_block(self, block_index, hidden, temb, freqs):
+ hidden = self.controlnet_blocks[block_index](hidden, temb, freqs)
+ residual = self.proj_out[block_index](hidden)
+ return hidden, residual
diff --git a/ComfyUI/comfy/ldm/wan/vae.py b/ComfyUI/comfy/ldm/wan/vae.py
new file mode 100644
index 0000000000000000000000000000000000000000..57b0dabf72f2d6f042ed956d16cc313932a5da27
--- /dev/null
+++ b/ComfyUI/comfy/ldm/wan/vae.py
@@ -0,0 +1,511 @@
+# original version: https://github.com/Wan-Video/Wan2.1/blob/main/wan/modules/vae.py
+# Copyright 2024-2025 The Alibaba Wan Team Authors. All rights reserved.
+
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+from einops import rearrange
+from comfy.ldm.modules.diffusionmodules.model import vae_attention, torch_cat_if_needed
+
+import comfy.ops
+ops = comfy.ops.disable_weight_init
+
+CACHE_T = 2
+
+
+class CausalConv3d(ops.Conv3d):
+ """
+ Causal 3d convolusion.
+ """
+
+ def __init__(self, *args, **kwargs):
+ super().__init__(*args, **kwargs)
+ self._padding = 2 * self.padding[0]
+ self.padding = (0, self.padding[1], self.padding[2])
+
+ def forward(self, x, cache_x=None, cache_list=None, cache_idx=None):
+ if cache_list is not None:
+ cache_x = cache_list[cache_idx]
+ cache_list[cache_idx] = None
+
+ if cache_x is None and x.shape[2] == 1:
+ #Fast path - the op will pad for use by truncating the weight
+ #and save math on a pile of zeros.
+ return super().forward(x, autopad="causal_zero")
+
+ if self._padding > 0:
+ padding_needed = self._padding
+ if cache_x is not None:
+ cache_x = cache_x.to(x.device)
+ padding_needed = max(0, padding_needed - cache_x.shape[2])
+ padding_shape = list(x.shape)
+ padding_shape[2] = padding_needed
+ padding = torch.zeros(padding_shape, device=x.device, dtype=x.dtype)
+ x = torch_cat_if_needed([padding, cache_x, x], dim=2)
+ del cache_x
+
+ return super().forward(x)
+
+
+class RMS_norm(nn.Module):
+
+ def __init__(self, dim, channel_first=True, images=True, bias=False):
+ super().__init__()
+ broadcastable_dims = (1, 1, 1) if not images else (1, 1)
+ shape = (dim, *broadcastable_dims) if channel_first else (dim,)
+
+ self.channel_first = channel_first
+ self.scale = dim**0.5
+ self.gamma = nn.Parameter(torch.ones(shape))
+ self.bias = nn.Parameter(torch.zeros(shape)) if bias else None
+
+ def forward(self, x):
+ return F.normalize(
+ x, dim=(1 if self.channel_first else -1)) * self.scale * self.gamma.to(x) + (self.bias.to(x) if self.bias is not None else 0)
+
+
+class Resample(nn.Module):
+
+ def __init__(self, dim, mode):
+ assert mode in ('none', 'upsample2d', 'upsample3d', 'downsample2d',
+ 'downsample3d')
+ super().__init__()
+ self.dim = dim
+ self.mode = mode
+
+ # layers
+ if mode == 'upsample2d':
+ self.resample = nn.Sequential(
+ nn.Upsample(scale_factor=(2., 2.), mode='nearest-exact'),
+ ops.Conv2d(dim, dim // 2, 3, padding=1))
+ elif mode == 'upsample3d':
+ self.resample = nn.Sequential(
+ nn.Upsample(scale_factor=(2., 2.), mode='nearest-exact'),
+ ops.Conv2d(dim, dim // 2, 3, padding=1))
+ self.time_conv = CausalConv3d(
+ dim, dim * 2, (3, 1, 1), padding=(1, 0, 0))
+
+ elif mode == 'downsample2d':
+ self.resample = nn.Sequential(
+ nn.ZeroPad2d((0, 1, 0, 1)),
+ ops.Conv2d(dim, dim, 3, stride=(2, 2)))
+ elif mode == 'downsample3d':
+ self.resample = nn.Sequential(
+ nn.ZeroPad2d((0, 1, 0, 1)),
+ ops.Conv2d(dim, dim, 3, stride=(2, 2)))
+ self.time_conv = CausalConv3d(
+ dim, dim, (3, 1, 1), stride=(2, 1, 1), padding=(0, 0, 0))
+
+ else:
+ self.resample = nn.Identity()
+
+ def forward(self, x, feat_cache=None, feat_idx=[0], final=False):
+ b, c, t, h, w = x.size()
+ if self.mode == 'upsample3d':
+ if feat_cache is not None:
+ idx = feat_idx[0]
+ if feat_cache[idx] is None:
+ feat_cache[idx] = 'Rep'
+ feat_idx[0] += 1
+ else:
+
+ cache_x = x[:, :, -CACHE_T:, :, :]
+ if feat_cache[idx] == 'Rep':
+ x = self.time_conv(x)
+ else:
+ x = self.time_conv(x, feat_cache[idx])
+ feat_cache[idx] = cache_x
+ feat_idx[0] += 1
+
+ x = x.reshape(b, 2, c, t, h, w)
+ x = torch.stack((x[:, 0, :, :, :, :], x[:, 1, :, :, :, :]),
+ 3)
+ x = x.reshape(b, c, t * 2, h, w)
+ t = x.shape[2]
+ x = rearrange(x, 'b c t h w -> (b t) c h w')
+ x = self.resample(x)
+ x = rearrange(x, '(b t) c h w -> b c t h w', t=t)
+
+ if self.mode == 'downsample3d':
+ if feat_cache is not None:
+ idx = feat_idx[0]
+ if feat_cache[idx] is None:
+ feat_cache[idx] = x
+ else:
+
+ cache_x = x[:, :, -1:, :, :]
+ x = self.time_conv(
+ torch.cat([feat_cache[idx][:, :, -1:, :, :], x], 2))
+ feat_cache[idx] = cache_x
+
+ deferred_x = feat_cache[idx + 1]
+ if deferred_x is not None:
+ x = torch.cat([deferred_x, x], 2)
+ feat_cache[idx + 1] = None
+
+ if x.shape[2] == 1 and not final:
+ feat_cache[idx + 1] = x
+ x = None
+
+ feat_idx[0] += 2
+ return x
+
+
+class ResidualBlock(nn.Module):
+
+ def __init__(self, in_dim, out_dim, dropout=0.0):
+ super().__init__()
+ self.in_dim = in_dim
+ self.out_dim = out_dim
+
+ # layers
+ self.residual = nn.Sequential(
+ RMS_norm(in_dim, images=False), nn.SiLU(),
+ CausalConv3d(in_dim, out_dim, 3, padding=1),
+ RMS_norm(out_dim, images=False), nn.SiLU(), nn.Dropout(dropout),
+ CausalConv3d(out_dim, out_dim, 3, padding=1))
+ self.shortcut = CausalConv3d(in_dim, out_dim, 1) \
+ if in_dim != out_dim else nn.Identity()
+
+ def forward(self, x, feat_cache=None, feat_idx=[0], final=False):
+ old_x = x
+ for layer in self.residual:
+ if isinstance(layer, CausalConv3d) and feat_cache is not None:
+ idx = feat_idx[0]
+ cache_x = x[:, :, -CACHE_T:, :, :]
+ x = layer(x, cache_list=feat_cache, cache_idx=idx)
+ feat_cache[idx] = cache_x
+ feat_idx[0] += 1
+ else:
+ x = layer(x)
+ return x + self.shortcut(old_x)
+
+
+class AttentionBlock(nn.Module):
+ """
+ Causal self-attention with a single head.
+ """
+
+ def __init__(self, dim):
+ super().__init__()
+ self.dim = dim
+
+ # layers
+ self.norm = RMS_norm(dim)
+ self.to_qkv = ops.Conv2d(dim, dim * 3, 1)
+ self.proj = ops.Conv2d(dim, dim, 1)
+ self.optimized_attention = vae_attention()
+
+ def forward(self, x, feat_cache=None, feat_idx=[0], final=False):
+ identity = x
+ b, c, t, h, w = x.size()
+ x = rearrange(x, 'b c t h w -> (b t) c h w')
+ x = self.norm(x)
+ # compute query, key, value
+
+ q, k, v = self.to_qkv(x).chunk(3, dim=1)
+ x = self.optimized_attention(q, k, v)
+
+ # output
+ x = self.proj(x)
+ x = rearrange(x, '(b t) c h w-> b c t h w', t=t)
+ return x + identity
+
+
+class Encoder3d(nn.Module):
+
+ def __init__(self,
+ dim=128,
+ z_dim=4,
+ input_channels=3,
+ dim_mult=[1, 2, 4, 4],
+ num_res_blocks=2,
+ attn_scales=[],
+ temperal_downsample=[True, True, False],
+ dropout=0.0):
+ super().__init__()
+ self.dim = dim
+ self.z_dim = z_dim
+ self.dim_mult = dim_mult
+ self.num_res_blocks = num_res_blocks
+ self.attn_scales = attn_scales
+ self.temperal_downsample = temperal_downsample
+
+ # dimensions
+ dims = [dim * u for u in [1] + dim_mult]
+ scale = 1.0
+
+ # init block
+ self.conv1 = CausalConv3d(input_channels, dims[0], 3, padding=1)
+
+ # downsample blocks
+ downsamples = []
+ for i, (in_dim, out_dim) in enumerate(zip(dims[:-1], dims[1:])):
+ # residual (+attention) blocks
+ for _ in range(num_res_blocks):
+ downsamples.append(ResidualBlock(in_dim, out_dim, dropout))
+ if scale in attn_scales:
+ downsamples.append(AttentionBlock(out_dim))
+ in_dim = out_dim
+
+ # downsample block
+ if i != len(dim_mult) - 1:
+ mode = 'downsample3d' if temperal_downsample[
+ i] else 'downsample2d'
+ downsamples.append(Resample(out_dim, mode=mode))
+ scale /= 2.0
+ self.downsamples = nn.Sequential(*downsamples)
+
+ # middle blocks
+ self.middle = nn.Sequential(
+ ResidualBlock(out_dim, out_dim, dropout), AttentionBlock(out_dim),
+ ResidualBlock(out_dim, out_dim, dropout))
+
+ # output blocks
+ self.head = nn.Sequential(
+ RMS_norm(out_dim, images=False), nn.SiLU(),
+ CausalConv3d(out_dim, z_dim, 3, padding=1))
+
+ def forward(self, x, feat_cache=None, feat_idx=[0], final=False):
+ if feat_cache is not None:
+ idx = feat_idx[0]
+ cache_x = x[:, :, -CACHE_T:, :, :]
+ x = self.conv1(x, feat_cache[idx])
+ feat_cache[idx] = cache_x
+ feat_idx[0] += 1
+ else:
+ x = self.conv1(x)
+
+ ## downsamples
+ for layer in self.downsamples:
+ if feat_cache is not None:
+ x = layer(x, feat_cache, feat_idx, final=final)
+ if x is None:
+ return None
+ else:
+ x = layer(x)
+
+ ## middle
+ for layer in self.middle:
+ if feat_cache is not None:
+ x = layer(x, feat_cache, feat_idx, final=final)
+ else:
+ x = layer(x)
+
+ ## head
+ for layer in self.head:
+ if isinstance(layer, CausalConv3d) and feat_cache is not None:
+ idx = feat_idx[0]
+ cache_x = x[:, :, -CACHE_T:, :, :]
+ x = layer(x, feat_cache[idx])
+ feat_cache[idx] = cache_x
+ feat_idx[0] += 1
+ else:
+ x = layer(x)
+ return x
+
+
+class Decoder3d(nn.Module):
+
+ def __init__(self,
+ dim=128,
+ z_dim=4,
+ output_channels=3,
+ dim_mult=[1, 2, 4, 4],
+ num_res_blocks=2,
+ attn_scales=[],
+ temperal_upsample=[False, True, True],
+ dropout=0.0):
+ super().__init__()
+ self.dim = dim
+ self.z_dim = z_dim
+ self.dim_mult = dim_mult
+ self.num_res_blocks = num_res_blocks
+ self.attn_scales = attn_scales
+ self.temperal_upsample = temperal_upsample
+
+ # dimensions
+ dims = [dim * u for u in [dim_mult[-1]] + dim_mult[::-1]]
+ scale = 1.0 / 2**(len(dim_mult) - 2)
+
+ # init block
+ self.conv1 = CausalConv3d(z_dim, dims[0], 3, padding=1)
+
+ # middle blocks
+ self.middle = nn.Sequential(
+ ResidualBlock(dims[0], dims[0], dropout), AttentionBlock(dims[0]),
+ ResidualBlock(dims[0], dims[0], dropout))
+
+ # upsample blocks
+ upsamples = []
+ for i, (in_dim, out_dim) in enumerate(zip(dims[:-1], dims[1:])):
+ # residual (+attention) blocks
+ if i == 1 or i == 2 or i == 3:
+ in_dim = in_dim // 2
+ for _ in range(num_res_blocks + 1):
+ upsamples.append(ResidualBlock(in_dim, out_dim, dropout))
+ if scale in attn_scales:
+ upsamples.append(AttentionBlock(out_dim))
+ in_dim = out_dim
+
+ # upsample block
+ if i != len(dim_mult) - 1:
+ mode = 'upsample3d' if temperal_upsample[i] else 'upsample2d'
+ upsamples.append(Resample(out_dim, mode=mode))
+ scale *= 2.0
+ self.upsamples = nn.Sequential(*upsamples)
+
+ # output blocks
+ self.head = nn.Sequential(
+ RMS_norm(out_dim, images=False), nn.SiLU(),
+ CausalConv3d(out_dim, output_channels, 3, padding=1))
+
+ def run_up(self, layer_idx, x_ref, feat_cache, feat_idx, out_chunks):
+ x = x_ref[0]
+ x_ref[0] = None
+ if layer_idx >= len(self.upsamples):
+ for layer in self.head:
+ if isinstance(layer, CausalConv3d) and feat_cache is not None:
+ cache_x = x[:, :, -CACHE_T:, :, :]
+ x = layer(x, feat_cache[feat_idx[0]])
+ feat_cache[feat_idx[0]] = cache_x
+ feat_idx[0] += 1
+ else:
+ x = layer(x)
+ out_chunks.append(x)
+ return
+
+ layer = self.upsamples[layer_idx]
+ if feat_cache is not None:
+ x = layer(x, feat_cache, feat_idx)
+ else:
+ x = layer(x)
+
+ if isinstance(layer, Resample) and layer.mode == 'upsample3d' and x.shape[2] > 2:
+ for frame_idx in range(0, x.shape[2], 2):
+ self.run_up(
+ layer_idx + 1,
+ [x[:, :, frame_idx:frame_idx + 2, :, :]],
+ feat_cache,
+ feat_idx.copy(),
+ out_chunks,
+ )
+ del x
+ return
+
+ next_x_ref = [x]
+ del x
+ self.run_up(layer_idx + 1, next_x_ref, feat_cache, feat_idx, out_chunks)
+
+ def forward(self, x, feat_cache=None, feat_idx=[0]):
+ ## conv1
+ if feat_cache is not None:
+ idx = feat_idx[0]
+ cache_x = x[:, :, -CACHE_T:, :, :]
+ x = self.conv1(x, feat_cache[idx])
+ feat_cache[idx] = cache_x
+ feat_idx[0] += 1
+ else:
+ x = self.conv1(x)
+
+ ## middle
+ for layer in self.middle:
+ if feat_cache is not None:
+ x = layer(x, feat_cache, feat_idx)
+ else:
+ x = layer(x)
+
+ out_chunks = []
+
+ self.run_up(0, [x], feat_cache, feat_idx, out_chunks)
+ return out_chunks
+
+
+def count_cache_layers(model):
+ count = 0
+ for m in model.modules():
+ if isinstance(m, CausalConv3d) or (isinstance(m, Resample) and m.mode == 'downsample3d'):
+ count += 1
+ return count
+
+
+class WanVAE(nn.Module):
+
+ def __init__(self,
+ dim=128,
+ z_dim=4,
+ dim_mult=[1, 2, 4, 4],
+ num_res_blocks=2,
+ attn_scales=[],
+ temperal_downsample=[True, True, False],
+ image_channels=3,
+ conv_out_channels=3,
+ dropout=0.0):
+ super().__init__()
+ self.dim = dim
+ self.z_dim = z_dim
+ self.dim_mult = dim_mult
+ self.num_res_blocks = num_res_blocks
+ self.attn_scales = attn_scales
+ self.temperal_downsample = temperal_downsample
+ self.temperal_upsample = temperal_downsample[::-1]
+
+ # modules
+ self.encoder = Encoder3d(dim, z_dim * 2, image_channels, dim_mult, num_res_blocks,
+ attn_scales, self.temperal_downsample, dropout)
+ self.conv1 = CausalConv3d(z_dim * 2, z_dim * 2, 1)
+ self.conv2 = CausalConv3d(z_dim, z_dim, 1)
+ self.decoder = Decoder3d(dim, z_dim, conv_out_channels, dim_mult, num_res_blocks,
+ attn_scales, self.temperal_upsample, dropout)
+
+ def encode(self, x):
+ conv_idx = [0]
+ ## cache
+ t = x.shape[2]
+ t = 1 + ((t - 1) // 4) * 4
+ iter_ = 1 + (t - 1) // 2
+ feat_map = None
+ if iter_ > 1:
+ feat_map = [None] * count_cache_layers(self.encoder)
+ ## 对encode输入的x,按时间拆分为1、2、2、2....(总帧数先按4N+1向下取整)
+ for i in range(iter_):
+ conv_idx = [0]
+ if i == 0:
+ out = self.encoder(
+ x[:, :, :1, :, :],
+ feat_cache=feat_map,
+ feat_idx=conv_idx)
+ else:
+ out_ = self.encoder(
+ x[:, :, 1 + 2 * (i - 1):1 + 2 * i, :, :],
+ feat_cache=feat_map,
+ feat_idx=conv_idx,
+ final=(i == (iter_ - 1)))
+ if out_ is None:
+ continue
+ out = torch.cat([out, out_], 2)
+
+ mu, log_var = self.conv1(out).chunk(2, dim=1)
+ return mu
+
+ def decode(self, z):
+ # z: [b,c,t,h,w]
+ iter_ = 1 + z.shape[2] // 2
+ feat_map = None
+ if iter_ > 1:
+ feat_map = [None] * count_cache_layers(self.decoder)
+ x = self.conv2(z)
+ for i in range(iter_):
+ conv_idx = [0]
+ if i == 0:
+ out = self.decoder(
+ x[:, :, i:i + 1, :, :],
+ feat_cache=feat_map,
+ feat_idx=conv_idx)
+ else:
+ out_ = self.decoder(
+ x[:, :, 1 + 2 * (i - 1):1 + 2 * i, :, :],
+ feat_cache=feat_map,
+ feat_idx=conv_idx)
+ out += out_
+ return torch.cat(out, 2)
diff --git a/ComfyUI/comfy/ldm/wan/vae2_2.py b/ComfyUI/comfy/ldm/wan/vae2_2.py
new file mode 100644
index 0000000000000000000000000000000000000000..8e1593a54c9464aa685f8cafc05e3e155d9f02d0
--- /dev/null
+++ b/ComfyUI/comfy/ldm/wan/vae2_2.py
@@ -0,0 +1,717 @@
+# original version: https://github.com/Wan-Video/Wan2.2/blob/main/wan/modules/vae2_2.py
+# Copyright 2024-2025 The Alibaba Wan Team Authors. All rights reserved.
+
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+from einops import rearrange
+from .vae import AttentionBlock, CausalConv3d, RMS_norm
+
+import comfy.ops
+ops = comfy.ops.disable_weight_init
+
+CACHE_T = 2
+
+
+class Resample(nn.Module):
+
+ def __init__(self, dim, mode):
+ assert mode in (
+ "none",
+ "upsample2d",
+ "upsample3d",
+ "downsample2d",
+ "downsample3d",
+ )
+ super().__init__()
+ self.dim = dim
+ self.mode = mode
+
+ # layers
+ if mode == "upsample2d":
+ self.resample = nn.Sequential(
+ nn.Upsample(scale_factor=(2.0, 2.0), mode="nearest-exact"),
+ ops.Conv2d(dim, dim, 3, padding=1),
+ )
+ elif mode == "upsample3d":
+ self.resample = nn.Sequential(
+ nn.Upsample(scale_factor=(2.0, 2.0), mode="nearest-exact"),
+ ops.Conv2d(dim, dim, 3, padding=1),
+ # ops.Conv2d(dim, dim//2, 3, padding=1)
+ )
+ self.time_conv = CausalConv3d(
+ dim, dim * 2, (3, 1, 1), padding=(1, 0, 0))
+ elif mode == "downsample2d":
+ self.resample = nn.Sequential(
+ nn.ZeroPad2d((0, 1, 0, 1)),
+ ops.Conv2d(dim, dim, 3, stride=(2, 2)))
+ elif mode == "downsample3d":
+ self.resample = nn.Sequential(
+ nn.ZeroPad2d((0, 1, 0, 1)),
+ ops.Conv2d(dim, dim, 3, stride=(2, 2)))
+ self.time_conv = CausalConv3d(
+ dim, dim, (3, 1, 1), stride=(2, 1, 1), padding=(0, 0, 0))
+ else:
+ self.resample = nn.Identity()
+
+ def forward(self, x, feat_cache=None, feat_idx=[0]):
+ b, c, t, h, w = x.size()
+ if self.mode == "upsample3d":
+ if feat_cache is not None:
+ idx = feat_idx[0]
+ if feat_cache[idx] is None:
+ feat_cache[idx] = "Rep"
+ feat_idx[0] += 1
+ else:
+ cache_x = x[:, :, -CACHE_T:, :, :].clone()
+ if (cache_x.shape[2] < 2 and feat_cache[idx] is not None and
+ feat_cache[idx] != "Rep"):
+ # cache last frame of last two chunk
+ cache_x = torch.cat(
+ [
+ feat_cache[idx][:, :, -1, :, :].unsqueeze(2).to(
+ cache_x.device),
+ cache_x,
+ ],
+ dim=2,
+ )
+ if (cache_x.shape[2] < 2 and feat_cache[idx] is not None and
+ feat_cache[idx] == "Rep"):
+ cache_x = torch.cat(
+ [
+ torch.zeros_like(cache_x).to(cache_x.device),
+ cache_x
+ ],
+ dim=2,
+ )
+ if feat_cache[idx] == "Rep":
+ x = self.time_conv(x)
+ else:
+ x = self.time_conv(x, feat_cache[idx])
+ feat_cache[idx] = cache_x
+ feat_idx[0] += 1
+ x = x.reshape(b, 2, c, t, h, w)
+ x = torch.stack((x[:, 0, :, :, :, :], x[:, 1, :, :, :, :]),
+ 3)
+ x = x.reshape(b, c, t * 2, h, w)
+ t = x.shape[2]
+ x = rearrange(x, "b c t h w -> (b t) c h w")
+ x = self.resample(x)
+ x = rearrange(x, "(b t) c h w -> b c t h w", t=t)
+
+ if self.mode == "downsample3d":
+ if feat_cache is not None:
+ idx = feat_idx[0]
+ if feat_cache[idx] is None:
+ feat_cache[idx] = x.clone()
+ feat_idx[0] += 1
+ else:
+ cache_x = x[:, :, -1:, :, :].clone()
+ x = self.time_conv(
+ torch.cat([feat_cache[idx][:, :, -1:, :, :], x], 2))
+ feat_cache[idx] = cache_x
+ feat_idx[0] += 1
+ return x
+
+
+class ResidualBlock(nn.Module):
+
+ def __init__(self, in_dim, out_dim, dropout=0.0):
+ super().__init__()
+ self.in_dim = in_dim
+ self.out_dim = out_dim
+
+ # layers
+ self.residual = nn.Sequential(
+ RMS_norm(in_dim, images=False),
+ nn.SiLU(),
+ CausalConv3d(in_dim, out_dim, 3, padding=1),
+ RMS_norm(out_dim, images=False),
+ nn.SiLU(),
+ nn.Dropout(dropout),
+ CausalConv3d(out_dim, out_dim, 3, padding=1),
+ )
+ self.shortcut = (
+ CausalConv3d(in_dim, out_dim, 1)
+ if in_dim != out_dim else nn.Identity())
+
+ def forward(self, x, feat_cache=None, feat_idx=[0]):
+ old_x = x
+ for layer in self.residual:
+ if isinstance(layer, CausalConv3d) and feat_cache is not None:
+ idx = feat_idx[0]
+ cache_x = x[:, :, -CACHE_T:, :, :].clone()
+ if cache_x.shape[2] < 2 and feat_cache[idx] is not None:
+ # cache last frame of last two chunk
+ cache_x = torch.cat(
+ [
+ feat_cache[idx][:, :, -1, :, :].unsqueeze(2).to(
+ cache_x.device),
+ cache_x,
+ ],
+ dim=2,
+ )
+ x = layer(x, cache_list=feat_cache, cache_idx=idx)
+ feat_cache[idx] = cache_x
+ feat_idx[0] += 1
+ else:
+ x = layer(x)
+ return x + self.shortcut(old_x)
+
+
+def patchify(x, patch_size):
+ if patch_size == 1:
+ return x
+ if x.dim() == 4:
+ x = rearrange(
+ x, "b c (h q) (w r) -> b (c r q) h w", q=patch_size, r=patch_size)
+ elif x.dim() == 5:
+ x = rearrange(
+ x,
+ "b c f (h q) (w r) -> b (c r q) f h w",
+ q=patch_size,
+ r=patch_size,
+ )
+ else:
+ raise ValueError(f"Invalid input shape: {x.shape}")
+
+ return x
+
+
+def unpatchify(x, patch_size):
+ if patch_size == 1:
+ return x
+
+ if x.dim() == 4:
+ x = rearrange(
+ x, "b (c r q) h w -> b c (h q) (w r)", q=patch_size, r=patch_size)
+ elif x.dim() == 5:
+ x = rearrange(
+ x,
+ "b (c r q) f h w -> b c f (h q) (w r)",
+ q=patch_size,
+ r=patch_size,
+ )
+ return x
+
+
+class AvgDown3D(nn.Module):
+
+ def __init__(
+ self,
+ in_channels,
+ out_channels,
+ factor_t,
+ factor_s=1,
+ ):
+ super().__init__()
+ self.in_channels = in_channels
+ self.out_channels = out_channels
+ self.factor_t = factor_t
+ self.factor_s = factor_s
+ self.factor = self.factor_t * self.factor_s * self.factor_s
+
+ assert in_channels * self.factor % out_channels == 0
+ self.group_size = in_channels * self.factor // out_channels
+
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
+ pad_t = (self.factor_t - x.shape[2] % self.factor_t) % self.factor_t
+ pad = (0, 0, 0, 0, pad_t, 0)
+ x = F.pad(x, pad)
+ B, C, T, H, W = x.shape
+ x = x.view(
+ B,
+ C,
+ T // self.factor_t,
+ self.factor_t,
+ H // self.factor_s,
+ self.factor_s,
+ W // self.factor_s,
+ self.factor_s,
+ )
+ x = x.permute(0, 1, 3, 5, 7, 2, 4, 6).contiguous()
+ x = x.view(
+ B,
+ C * self.factor,
+ T // self.factor_t,
+ H // self.factor_s,
+ W // self.factor_s,
+ )
+ x = x.view(
+ B,
+ self.out_channels,
+ self.group_size,
+ T // self.factor_t,
+ H // self.factor_s,
+ W // self.factor_s,
+ )
+ x = x.mean(dim=2)
+ return x
+
+
+class DupUp3D(nn.Module):
+
+ def __init__(
+ self,
+ in_channels: int,
+ out_channels: int,
+ factor_t,
+ factor_s=1,
+ ):
+ super().__init__()
+ self.in_channels = in_channels
+ self.out_channels = out_channels
+
+ self.factor_t = factor_t
+ self.factor_s = factor_s
+ self.factor = self.factor_t * self.factor_s * self.factor_s
+
+ assert out_channels * self.factor % in_channels == 0
+ self.repeats = out_channels * self.factor // in_channels
+
+ def forward(self, x: torch.Tensor, first_chunk=False) -> torch.Tensor:
+ x = x.repeat_interleave(self.repeats, dim=1)
+ x = x.view(
+ x.size(0),
+ self.out_channels,
+ self.factor_t,
+ self.factor_s,
+ self.factor_s,
+ x.size(2),
+ x.size(3),
+ x.size(4),
+ )
+ x = x.permute(0, 1, 5, 2, 6, 3, 7, 4).contiguous()
+ x = x.view(
+ x.size(0),
+ self.out_channels,
+ x.size(2) * self.factor_t,
+ x.size(4) * self.factor_s,
+ x.size(6) * self.factor_s,
+ )
+ if first_chunk:
+ x = x[:, :, self.factor_t - 1:, :, :]
+ return x
+
+
+class Down_ResidualBlock(nn.Module):
+
+ def __init__(self,
+ in_dim,
+ out_dim,
+ dropout,
+ mult,
+ temperal_downsample=False,
+ down_flag=False):
+ super().__init__()
+
+ # Shortcut path with downsample
+ self.avg_shortcut = AvgDown3D(
+ in_dim,
+ out_dim,
+ factor_t=2 if temperal_downsample else 1,
+ factor_s=2 if down_flag else 1,
+ )
+
+ # Main path with residual blocks and downsample
+ downsamples = []
+ for _ in range(mult):
+ downsamples.append(ResidualBlock(in_dim, out_dim, dropout))
+ in_dim = out_dim
+
+ # Add the final downsample block
+ if down_flag:
+ mode = "downsample3d" if temperal_downsample else "downsample2d"
+ downsamples.append(Resample(out_dim, mode=mode))
+
+ self.downsamples = nn.Sequential(*downsamples)
+
+ def forward(self, x, feat_cache=None, feat_idx=[0]):
+ x_copy = x
+ for module in self.downsamples:
+ x = module(x, feat_cache, feat_idx)
+
+ return x + self.avg_shortcut(x_copy)
+
+
+class Up_ResidualBlock(nn.Module):
+
+ def __init__(self,
+ in_dim,
+ out_dim,
+ dropout,
+ mult,
+ temperal_upsample=False,
+ up_flag=False):
+ super().__init__()
+ # Shortcut path with upsample
+ if up_flag:
+ self.avg_shortcut = DupUp3D(
+ in_dim,
+ out_dim,
+ factor_t=2 if temperal_upsample else 1,
+ factor_s=2 if up_flag else 1,
+ )
+ else:
+ self.avg_shortcut = None
+
+ # Main path with residual blocks and upsample
+ upsamples = []
+ for _ in range(mult):
+ upsamples.append(ResidualBlock(in_dim, out_dim, dropout))
+ in_dim = out_dim
+
+ # Add the final upsample block
+ if up_flag:
+ mode = "upsample3d" if temperal_upsample else "upsample2d"
+ upsamples.append(Resample(out_dim, mode=mode))
+
+ self.upsamples = nn.Sequential(*upsamples)
+
+ def forward(self, x, feat_cache=None, feat_idx=[0], first_chunk=False):
+ x_main = x
+ for module in self.upsamples:
+ x_main = module(x_main, feat_cache, feat_idx)
+ if self.avg_shortcut is not None:
+ x_shortcut = self.avg_shortcut(x, first_chunk)
+ return x_main + x_shortcut
+ else:
+ return x_main
+
+
+class Encoder3d(nn.Module):
+
+ def __init__(
+ self,
+ dim=128,
+ z_dim=4,
+ dim_mult=[1, 2, 4, 4],
+ num_res_blocks=2,
+ attn_scales=[],
+ temperal_downsample=[True, True, False],
+ dropout=0.0,
+ ):
+ super().__init__()
+ self.dim = dim
+ self.z_dim = z_dim
+ self.dim_mult = dim_mult
+ self.num_res_blocks = num_res_blocks
+ self.attn_scales = attn_scales
+ self.temperal_downsample = temperal_downsample
+
+ # dimensions
+ dims = [dim * u for u in [1] + dim_mult]
+ scale = 1.0
+
+ # init block
+ self.conv1 = CausalConv3d(12, dims[0], 3, padding=1)
+
+ # downsample blocks
+ downsamples = []
+ for i, (in_dim, out_dim) in enumerate(zip(dims[:-1], dims[1:])):
+ t_down_flag = (
+ temperal_downsample[i]
+ if i < len(temperal_downsample) else False)
+ downsamples.append(
+ Down_ResidualBlock(
+ in_dim=in_dim,
+ out_dim=out_dim,
+ dropout=dropout,
+ mult=num_res_blocks,
+ temperal_downsample=t_down_flag,
+ down_flag=i != len(dim_mult) - 1,
+ ))
+ scale /= 2.0
+ self.downsamples = nn.Sequential(*downsamples)
+
+ # middle blocks
+ self.middle = nn.Sequential(
+ ResidualBlock(out_dim, out_dim, dropout),
+ AttentionBlock(out_dim),
+ ResidualBlock(out_dim, out_dim, dropout),
+ )
+
+ # # output blocks
+ self.head = nn.Sequential(
+ RMS_norm(out_dim, images=False),
+ nn.SiLU(),
+ CausalConv3d(out_dim, z_dim, 3, padding=1),
+ )
+
+ def forward(self, x, feat_cache=None, feat_idx=[0]):
+
+ if feat_cache is not None:
+ idx = feat_idx[0]
+ cache_x = x[:, :, -CACHE_T:, :, :].clone()
+ if cache_x.shape[2] < 2 and feat_cache[idx] is not None:
+ cache_x = torch.cat(
+ [
+ feat_cache[idx][:, :, -1, :, :].unsqueeze(2).to(
+ cache_x.device),
+ cache_x,
+ ],
+ dim=2,
+ )
+ x = self.conv1(x, feat_cache[idx])
+ feat_cache[idx] = cache_x
+ feat_idx[0] += 1
+ else:
+ x = self.conv1(x)
+
+ ## downsamples
+ for layer in self.downsamples:
+ if feat_cache is not None:
+ x = layer(x, feat_cache, feat_idx)
+ else:
+ x = layer(x)
+
+ ## middle
+ for layer in self.middle:
+ if isinstance(layer, ResidualBlock) and feat_cache is not None:
+ x = layer(x, feat_cache, feat_idx)
+ else:
+ x = layer(x)
+
+ ## head
+ for layer in self.head:
+ if isinstance(layer, CausalConv3d) and feat_cache is not None:
+ idx = feat_idx[0]
+ cache_x = x[:, :, -CACHE_T:, :, :].clone()
+ if cache_x.shape[2] < 2 and feat_cache[idx] is not None:
+ cache_x = torch.cat(
+ [
+ feat_cache[idx][:, :, -1, :, :].unsqueeze(2).to(
+ cache_x.device),
+ cache_x,
+ ],
+ dim=2,
+ )
+ x = layer(x, feat_cache[idx])
+ feat_cache[idx] = cache_x
+ feat_idx[0] += 1
+ else:
+ x = layer(x)
+
+ return x
+
+
+class Decoder3d(nn.Module):
+
+ def __init__(
+ self,
+ dim=128,
+ z_dim=4,
+ dim_mult=[1, 2, 4, 4],
+ num_res_blocks=2,
+ attn_scales=[],
+ temperal_upsample=[False, True, True],
+ dropout=0.0,
+ ):
+ super().__init__()
+ self.dim = dim
+ self.z_dim = z_dim
+ self.dim_mult = dim_mult
+ self.num_res_blocks = num_res_blocks
+ self.attn_scales = attn_scales
+ self.temperal_upsample = temperal_upsample
+
+ # dimensions
+ dims = [dim * u for u in [dim_mult[-1]] + dim_mult[::-1]]
+ # init block
+ self.conv1 = CausalConv3d(z_dim, dims[0], 3, padding=1)
+
+ # middle blocks
+ self.middle = nn.Sequential(
+ ResidualBlock(dims[0], dims[0], dropout),
+ AttentionBlock(dims[0]),
+ ResidualBlock(dims[0], dims[0], dropout),
+ )
+
+ # upsample blocks
+ upsamples = []
+ for i, (in_dim, out_dim) in enumerate(zip(dims[:-1], dims[1:])):
+ t_up_flag = temperal_upsample[i] if i < len(
+ temperal_upsample) else False
+ upsamples.append(
+ Up_ResidualBlock(
+ in_dim=in_dim,
+ out_dim=out_dim,
+ dropout=dropout,
+ mult=num_res_blocks + 1,
+ temperal_upsample=t_up_flag,
+ up_flag=i != len(dim_mult) - 1,
+ ))
+ self.upsamples = nn.Sequential(*upsamples)
+
+ # output blocks
+ self.head = nn.Sequential(
+ RMS_norm(out_dim, images=False),
+ nn.SiLU(),
+ CausalConv3d(out_dim, 12, 3, padding=1),
+ )
+
+ def forward(self, x, feat_cache=None, feat_idx=[0], first_chunk=False):
+ if feat_cache is not None:
+ idx = feat_idx[0]
+ cache_x = x[:, :, -CACHE_T:, :, :].clone()
+ if cache_x.shape[2] < 2 and feat_cache[idx] is not None:
+ cache_x = torch.cat(
+ [
+ feat_cache[idx][:, :, -1, :, :].unsqueeze(2).to(
+ cache_x.device),
+ cache_x,
+ ],
+ dim=2,
+ )
+ x = self.conv1(x, feat_cache[idx])
+ feat_cache[idx] = cache_x
+ feat_idx[0] += 1
+ else:
+ x = self.conv1(x)
+
+ for layer in self.middle:
+ if isinstance(layer, ResidualBlock) and feat_cache is not None:
+ x = layer(x, feat_cache, feat_idx)
+ else:
+ x = layer(x)
+
+ ## upsamples
+ for layer in self.upsamples:
+ if feat_cache is not None:
+ x = layer(x, feat_cache, feat_idx, first_chunk)
+ else:
+ x = layer(x)
+
+ ## head
+ for layer in self.head:
+ if isinstance(layer, CausalConv3d) and feat_cache is not None:
+ idx = feat_idx[0]
+ cache_x = x[:, :, -CACHE_T:, :, :].clone()
+ if cache_x.shape[2] < 2 and feat_cache[idx] is not None:
+ cache_x = torch.cat(
+ [
+ feat_cache[idx][:, :, -1, :, :].unsqueeze(2).to(
+ cache_x.device),
+ cache_x,
+ ],
+ dim=2,
+ )
+ x = layer(x, feat_cache[idx])
+ feat_cache[idx] = cache_x
+ feat_idx[0] += 1
+ else:
+ x = layer(x)
+ return x
+
+
+def count_conv3d(model):
+ count = 0
+ for m in model.modules():
+ if isinstance(m, CausalConv3d):
+ count += 1
+ return count
+
+
+class WanVAE(nn.Module):
+
+ def __init__(
+ self,
+ dim=160,
+ dec_dim=256,
+ z_dim=16,
+ dim_mult=[1, 2, 4, 4],
+ num_res_blocks=2,
+ attn_scales=[],
+ temperal_downsample=[True, True, False],
+ dropout=0.0,
+ ):
+ super().__init__()
+ self.dim = dim
+ self.z_dim = z_dim
+ self.dim_mult = dim_mult
+ self.num_res_blocks = num_res_blocks
+ self.attn_scales = attn_scales
+ self.temperal_downsample = temperal_downsample
+ self.temperal_upsample = temperal_downsample[::-1]
+
+ # modules
+ self.encoder = Encoder3d(
+ dim,
+ z_dim * 2,
+ dim_mult,
+ num_res_blocks,
+ attn_scales,
+ self.temperal_downsample,
+ dropout,
+ )
+ self.conv1 = CausalConv3d(z_dim * 2, z_dim * 2, 1)
+ self.conv2 = CausalConv3d(z_dim, z_dim, 1)
+ self.decoder = Decoder3d(
+ dec_dim,
+ z_dim,
+ dim_mult,
+ num_res_blocks,
+ attn_scales,
+ self.temperal_upsample,
+ dropout,
+ )
+
+ def encode(self, x):
+ conv_idx = [0]
+ feat_map = [None] * count_conv3d(self.encoder)
+ x = patchify(x, patch_size=2)
+ t = x.shape[2]
+ iter_ = 1 + (t - 1) // 4
+ for i in range(iter_):
+ conv_idx = [0]
+ if i == 0:
+ out = self.encoder(
+ x[:, :, :1, :, :],
+ feat_cache=feat_map,
+ feat_idx=conv_idx,
+ )
+ else:
+ out_ = self.encoder(
+ x[:, :, 1 + 4 * (i - 1):1 + 4 * i, :, :],
+ feat_cache=feat_map,
+ feat_idx=conv_idx,
+ )
+ out = torch.cat([out, out_], 2)
+ mu, log_var = self.conv1(out).chunk(2, dim=1)
+ return mu
+
+ def decode(self, z):
+ conv_idx = [0]
+ feat_map = [None] * count_conv3d(self.decoder)
+ iter_ = z.shape[2]
+ x = self.conv2(z)
+ for i in range(iter_):
+ conv_idx = [0]
+ if i == 0:
+ out = self.decoder(
+ x[:, :, i:i + 1, :, :],
+ feat_cache=feat_map,
+ feat_idx=conv_idx,
+ first_chunk=True,
+ )
+ else:
+ out_ = self.decoder(
+ x[:, :, i:i + 1, :, :],
+ feat_cache=feat_map,
+ feat_idx=conv_idx,
+ )
+ out = torch.cat([out, out_], 2)
+ out = unpatchify(out, patch_size=2)
+ return out
+
+ def reparameterize(self, mu, log_var):
+ std = torch.exp(0.5 * log_var)
+ eps = torch.randn_like(std)
+ return eps * std + mu
+
+ def sample(self, imgs, deterministic=False):
+ mu, log_var = self.encode(imgs)
+ if deterministic:
+ return mu
+ std = torch.exp(0.5 * log_var.clamp(-30.0, 20.0))
+ return mu + std * torch.randn_like(std)
diff --git a/ComfyUI/comfy/lora.py b/ComfyUI/comfy/lora.py
new file mode 100644
index 0000000000000000000000000000000000000000..427cf98aa4f62308e916f16ee3dbd4bd5ece3b3f
--- /dev/null
+++ b/ComfyUI/comfy/lora.py
@@ -0,0 +1,522 @@
+"""
+ This file is part of ComfyUI.
+ Copyright (C) 2024 Comfy
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+"""
+
+import comfy.memory_management
+import comfy.utils
+import comfy.model_management
+import comfy.model_base
+import comfy.weight_adapter as weight_adapter
+import logging
+import torch
+
+LORA_CLIP_MAP = {
+ "mlp.fc1": "mlp_fc1",
+ "mlp.fc2": "mlp_fc2",
+ "self_attn.k_proj": "self_attn_k_proj",
+ "self_attn.q_proj": "self_attn_q_proj",
+ "self_attn.v_proj": "self_attn_v_proj",
+ "self_attn.out_proj": "self_attn_out_proj",
+}
+
+
+def load_lora(lora, to_load, log_missing=True):
+ patch_dict = {}
+ loaded_keys = set()
+ for x in to_load:
+ alpha_name = "{}.alpha".format(x)
+ alpha = None
+ if alpha_name in lora.keys():
+ alpha = lora[alpha_name].item()
+ loaded_keys.add(alpha_name)
+
+ dora_scale_name = "{}.dora_scale".format(x)
+ dora_scale = None
+ if dora_scale_name in lora.keys():
+ dora_scale = lora[dora_scale_name]
+ loaded_keys.add(dora_scale_name)
+
+ for adapter_cls in weight_adapter.adapters:
+ adapter = adapter_cls.load(x, lora, alpha, dora_scale, loaded_keys)
+ if adapter is not None:
+ patch_dict[to_load[x]] = adapter
+ loaded_keys.update(adapter.loaded_keys)
+ continue
+
+ w_norm_name = "{}.w_norm".format(x)
+ b_norm_name = "{}.b_norm".format(x)
+ w_norm = lora.get(w_norm_name, None)
+ b_norm = lora.get(b_norm_name, None)
+
+ if w_norm is not None:
+ loaded_keys.add(w_norm_name)
+ patch_dict[to_load[x]] = ("diff", (w_norm,))
+ if b_norm is not None:
+ loaded_keys.add(b_norm_name)
+ patch_dict["{}.bias".format(to_load[x][:-len(".weight")])] = ("diff", (b_norm,))
+
+ diff_name = "{}.diff".format(x)
+ diff_weight = lora.get(diff_name, None)
+ if diff_weight is not None:
+ patch_dict[to_load[x]] = ("diff", (diff_weight,))
+ loaded_keys.add(diff_name)
+
+ diff_bias_name = "{}.diff_b".format(x)
+ diff_bias = lora.get(diff_bias_name, None)
+ if diff_bias is not None:
+ patch_dict["{}.bias".format(to_load[x][:-len(".weight")])] = ("diff", (diff_bias,))
+ loaded_keys.add(diff_bias_name)
+
+ set_weight_name = "{}.set_weight".format(x)
+ set_weight = lora.get(set_weight_name, None)
+ if set_weight is not None:
+ patch_dict[to_load[x]] = ("set", (set_weight,))
+ loaded_keys.add(set_weight_name)
+
+ if log_missing:
+ for x in lora.keys():
+ if x not in loaded_keys:
+ logging.warning("lora key not loaded: {}".format(x))
+
+ return patch_dict
+
+def model_lora_keys_clip(model, key_map={}):
+ sdk = model.state_dict().keys()
+ prefix_set = set()
+ for k in sdk:
+ if k.endswith(".weight"):
+ key_map["text_encoders.{}".format(k[:-len(".weight")])] = k #generic lora format without any weird key names
+ tp = k.find(".transformer.") #also map without wrapper prefix for composite text encoder models
+ if tp > 0 and not k.startswith("clip_"):
+ key_map["text_encoders.{}".format(k[tp + 1:-len(".weight")])] = k
+ prefix_set.add(k.split('.')[0])
+
+ text_model_lora_key = "lora_te_text_model_encoder_layers_{}_{}"
+ clip_l_present = False
+ clip_g_present = False
+ for b in range(32): #TODO: clean up
+ for c in LORA_CLIP_MAP:
+ k = "clip_h.transformer.text_model.encoder.layers.{}.{}.weight".format(b, c)
+ if k in sdk:
+ lora_key = text_model_lora_key.format(b, LORA_CLIP_MAP[c])
+ key_map[lora_key] = k
+ lora_key = "lora_te1_text_model_encoder_layers_{}_{}".format(b, LORA_CLIP_MAP[c])
+ key_map[lora_key] = k
+ lora_key = "text_encoder.text_model.encoder.layers.{}.{}".format(b, c) #diffusers lora
+ key_map[lora_key] = k
+
+ k = "clip_l.transformer.text_model.encoder.layers.{}.{}.weight".format(b, c)
+ if k in sdk:
+ lora_key = text_model_lora_key.format(b, LORA_CLIP_MAP[c])
+ key_map[lora_key] = k
+ lora_key = "lora_te1_text_model_encoder_layers_{}_{}".format(b, LORA_CLIP_MAP[c]) #SDXL base
+ key_map[lora_key] = k
+ clip_l_present = True
+ lora_key = "text_encoder.text_model.encoder.layers.{}.{}".format(b, c) #diffusers lora
+ key_map[lora_key] = k
+
+ k = "clip_g.transformer.text_model.encoder.layers.{}.{}.weight".format(b, c)
+ if k in sdk:
+ clip_g_present = True
+ if clip_l_present:
+ lora_key = "lora_te2_text_model_encoder_layers_{}_{}".format(b, LORA_CLIP_MAP[c]) #SDXL base
+ key_map[lora_key] = k
+ lora_key = "text_encoder_2.text_model.encoder.layers.{}.{}".format(b, c) #diffusers lora
+ key_map[lora_key] = k
+ else:
+ lora_key = "lora_te_text_model_encoder_layers_{}_{}".format(b, LORA_CLIP_MAP[c]) #TODO: test if this is correct for SDXL-Refiner
+ key_map[lora_key] = k
+ lora_key = "text_encoder.text_model.encoder.layers.{}.{}".format(b, c) #diffusers lora
+ key_map[lora_key] = k
+ lora_key = "lora_prior_te_text_model_encoder_layers_{}_{}".format(b, LORA_CLIP_MAP[c]) #cascade lora: TODO put lora key prefix in the model config
+ key_map[lora_key] = k
+
+ for k in sdk:
+ if k.endswith(".weight"):
+ if k.startswith("t5xxl.transformer."):#OneTrainer SD3 and Flux lora
+ l_key = k[len("t5xxl.transformer."):-len(".weight")]
+ t5_index = 1
+ if clip_g_present:
+ t5_index += 1
+ if clip_l_present:
+ t5_index += 1
+ if t5_index == 2:
+ key_map["lora_te{}_{}".format(t5_index, l_key.replace(".", "_"))] = k #OneTrainer Flux
+ t5_index += 1
+
+ key_map["lora_te{}_{}".format(t5_index, l_key.replace(".", "_"))] = k
+ elif k.startswith("hydit_clip.transformer.bert."): #HunyuanDiT Lora
+ l_key = k[len("hydit_clip.transformer.bert."):-len(".weight")]
+ lora_key = "lora_te1_{}".format(l_key.replace(".", "_"))
+ key_map[lora_key] = k
+
+ if len(prefix_set) == 1:
+ full_prefix = "{}.transformer.model.".format(next(iter(prefix_set))) # kohya anima and maybe other single TE models that use a single llama arch based te
+ for k in sdk:
+ if k.endswith(".weight"):
+ if k.startswith(full_prefix):
+ l_key = k[len(full_prefix):-len(".weight")]
+ key_map["lora_te_{}".format(l_key.replace(".", "_"))] = k
+
+ k = "clip_g.transformer.text_projection.weight"
+ if k in sdk:
+ key_map["lora_prior_te_text_projection"] = k #cascade lora?
+ # key_map["text_encoder.text_projection"] = k #TODO: check if other lora have the text_projection too
+ key_map["lora_te2_text_projection"] = k #OneTrainer SD3 lora
+
+ k = "clip_l.transformer.text_projection.weight"
+ if k in sdk:
+ key_map["lora_te1_text_projection"] = k #OneTrainer SD3 lora, not necessary but omits warning
+
+ return key_map
+
+def model_lora_keys_unet(model, key_map={}):
+ sd = model.state_dict()
+ sdk = sd.keys()
+
+ for k in sdk:
+ if k.startswith("diffusion_model."):
+ if k.endswith(".weight"):
+ key_lora = k[len("diffusion_model."):-len(".weight")].replace(".", "_")
+ key_map["lora_unet_{}".format(key_lora)] = k
+ key_map["{}".format(k[:-len(".weight")])] = k #generic lora format without any weird key names
+ else:
+ key_map["{}".format(k)] = k #generic lora format for not .weight without any weird key names
+
+ diffusers_keys = comfy.utils.unet_to_diffusers(model.model_config.unet_config)
+ for k in diffusers_keys:
+ if k.endswith(".weight"):
+ unet_key = "diffusion_model.{}".format(diffusers_keys[k])
+ key_lora = k[:-len(".weight")].replace(".", "_")
+ key_map["lora_unet_{}".format(key_lora)] = unet_key
+ key_map["lycoris_{}".format(key_lora)] = unet_key #simpletuner lycoris format
+
+ diffusers_lora_prefix = ["", "unet."]
+ for p in diffusers_lora_prefix:
+ diffusers_lora_key = "{}{}".format(p, k[:-len(".weight")].replace(".to_", ".processor.to_"))
+ if diffusers_lora_key.endswith(".to_out.0"):
+ diffusers_lora_key = diffusers_lora_key[:-2]
+ key_map[diffusers_lora_key] = unet_key
+
+ if isinstance(model, comfy.model_base.StableCascade_C):
+ for k in sdk:
+ if k.startswith("diffusion_model."):
+ if k.endswith(".weight"):
+ key_lora = k[len("diffusion_model."):-len(".weight")].replace(".", "_")
+ key_map["lora_prior_unet_{}".format(key_lora)] = k
+
+ if isinstance(model, comfy.model_base.SD3): #Diffusers lora SD3
+ diffusers_keys = comfy.utils.mmdit_to_diffusers(model.model_config.unet_config, output_prefix="diffusion_model.")
+ for k in diffusers_keys:
+ if k.endswith(".weight"):
+ to = diffusers_keys[k]
+ key_lora = "transformer.{}".format(k[:-len(".weight")]) #regular diffusers sd3 lora format
+ key_map[key_lora] = to
+
+ key_lora = "base_model.model.{}".format(k[:-len(".weight")]) #format for flash-sd3 lora and others?
+ key_map[key_lora] = to
+
+ key_lora = "lora_transformer_{}".format(k[:-len(".weight")].replace(".", "_")) #OneTrainer lora
+ key_map[key_lora] = to
+
+ key_lora = "lycoris_{}".format(k[:-len(".weight")].replace(".", "_")) #simpletuner lycoris format
+ key_map[key_lora] = to
+
+ if isinstance(model, comfy.model_base.AuraFlow): #Diffusers lora AuraFlow
+ diffusers_keys = comfy.utils.auraflow_to_diffusers(model.model_config.unet_config, output_prefix="diffusion_model.")
+ for k in diffusers_keys:
+ if k.endswith(".weight"):
+ to = diffusers_keys[k]
+ key_lora = "transformer.{}".format(k[:-len(".weight")]) #simpletrainer and probably regular diffusers lora format
+ key_map[key_lora] = to
+
+ if isinstance(model, comfy.model_base.PixArt):
+ diffusers_keys = comfy.utils.pixart_to_diffusers(model.model_config.unet_config, output_prefix="diffusion_model.")
+ for k in diffusers_keys:
+ if k.endswith(".weight"):
+ to = diffusers_keys[k]
+ key_lora = "transformer.{}".format(k[:-len(".weight")]) #default format
+ key_map[key_lora] = to
+
+ key_lora = "base_model.model.{}".format(k[:-len(".weight")]) #diffusers training script
+ key_map[key_lora] = to
+
+ key_lora = "unet.base_model.model.{}".format(k[:-len(".weight")]) #old reference peft script
+ key_map[key_lora] = to
+
+ if isinstance(model, comfy.model_base.HunyuanDiT):
+ for k in sdk:
+ if k.startswith("diffusion_model.") and k.endswith(".weight"):
+ key_lora = k[len("diffusion_model."):-len(".weight")]
+ key_map["base_model.model.{}".format(key_lora)] = k #official hunyuan lora format
+
+ if isinstance(model, comfy.model_base.Flux): #Diffusers lora Flux
+ diffusers_keys = comfy.utils.flux_to_diffusers(model.model_config.unet_config, output_prefix="diffusion_model.")
+ for k in diffusers_keys:
+ if k.endswith(".weight"):
+ to = diffusers_keys[k]
+ key_map["transformer.{}".format(k[:-len(".weight")])] = to #simpletrainer and probably regular diffusers flux lora format
+ key_map["lycoris_{}".format(k[:-len(".weight")].replace(".", "_"))] = to #simpletrainer lycoris
+ key_map["lora_transformer_{}".format(k[:-len(".weight")].replace(".", "_"))] = to #onetrainer
+ key_map[k[:-len(".weight")]] = to #DiffSynth lora format
+ for k in sdk:
+ hidden_size = model.model_config.unet_config.get("hidden_size", 0)
+ if k.endswith(".weight") and ".linear1." in k:
+ key_map["{}".format(k.replace(".linear1.weight", ".linear1_qkv"))] = (k, (0, 0, hidden_size * 3))
+
+ if isinstance(model, comfy.model_base.GenmoMochi):
+ for k in sdk:
+ if k.startswith("diffusion_model.") and k.endswith(".weight"): #Official Mochi lora format
+ key_lora = k[len("diffusion_model."):-len(".weight")]
+ key_map["{}".format(key_lora)] = k
+
+ if isinstance(model, comfy.model_base.HunyuanVideo):
+ for k in sdk:
+ if k.startswith("diffusion_model.") and k.endswith(".weight"):
+ # diffusion-pipe lora format
+ key_lora = k
+ key_lora = key_lora.replace("_mod.lin.", "_mod.linear.").replace("_attn.qkv.", "_attn_qkv.").replace("_attn.proj.", "_attn_proj.")
+ key_lora = key_lora.replace("mlp.0.", "mlp.fc1.").replace("mlp.2.", "mlp.fc2.")
+ key_lora = key_lora.replace(".modulation.lin.", ".modulation.linear.")
+ key_lora = key_lora[len("diffusion_model."):-len(".weight")]
+ key_map["transformer.{}".format(key_lora)] = k
+ key_map["diffusion_model.{}".format(key_lora)] = k # Old loras
+
+ if isinstance(model, comfy.model_base.HiDream):
+ for k in sdk:
+ if k.startswith("diffusion_model."):
+ if k.endswith(".weight"):
+ key_lora = k[len("diffusion_model."):-len(".weight")]
+ key_map["lycoris_{}".format(key_lora.replace(".", "_"))] = k #SimpleTuner lycoris format
+ key_map["transformer.{}".format(key_lora)] = k #SimpleTuner regular format
+
+ if isinstance(model, comfy.model_base.ACEStep):
+ for k in sdk:
+ if k.startswith("diffusion_model.") and k.endswith(".weight"): #Official ACE step lora format
+ key_lora = k[len("diffusion_model."):-len(".weight")]
+ key_map["{}".format(key_lora)] = k
+
+ if isinstance(model, comfy.model_base.Omnigen2):
+ for k in sdk:
+ if k.startswith("diffusion_model.") and k.endswith(".weight"):
+ key_lora = k[len("diffusion_model."):-len(".weight")]
+ key_map["{}".format(key_lora)] = k
+
+ if isinstance(model, comfy.model_base.QwenImage):
+ for k in sdk:
+ if k.startswith("diffusion_model.") and k.endswith(".weight"): #QwenImage lora format
+ key_lora = k[len("diffusion_model."):-len(".weight")]
+ # Direct mapping for transformer_blocks format (QwenImage LoRA format)
+ key_map["{}".format(key_lora)] = k
+ # Support transformer prefix format
+ key_map["transformer.{}".format(key_lora)] = k
+ key_map["lycoris_{}".format(key_lora.replace(".", "_"))] = k #SimpleTuner lycoris format
+
+ if isinstance(model, comfy.model_base.Krea2):
+ diffusers_keys = comfy.utils.krea2_to_diffusers(model.model_config.unet_config, output_prefix="diffusion_model.")
+ for k in diffusers_keys:
+ if k.endswith(".weight"):
+ to = diffusers_keys[k]
+ key_lora = k[:-len(".weight")]
+ key_map["diffusion_model.{}".format(key_lora)] = to
+ key_map["transformer.{}".format(key_lora)] = to
+ key_map["lycoris_{}".format(key_lora.replace(".", "_"))] = to
+ key_map[key_lora] = to
+
+ if isinstance(model, comfy.model_base.Lumina2):
+ diffusers_keys = comfy.utils.z_image_to_diffusers(model.model_config.unet_config, output_prefix="diffusion_model.")
+ for k in diffusers_keys:
+ if k.endswith(".weight"):
+ to = diffusers_keys[k]
+ key_lora = k[:-len(".weight")]
+ key_map["diffusion_model.{}".format(key_lora)] = to
+ key_map["transformer.{}".format(key_lora)] = to
+ key_map["lycoris_{}".format(key_lora.replace(".", "_"))] = to
+ key_map[key_lora] = to
+
+ if isinstance(model, comfy.model_base.Kandinsky5):
+ for k in sdk:
+ if k.startswith("diffusion_model.") and k.endswith(".weight"):
+ key_lora = k[len("diffusion_model."):-len(".weight")]
+ key_map["{}".format(key_lora)] = k
+ key_map["transformer.{}".format(key_lora)] = k
+
+ if isinstance(model, comfy.model_base.ACEStep15):
+ for k in sdk:
+ if k.startswith("diffusion_model.decoder.") and k.endswith(".weight"):
+ key_lora = k[len("diffusion_model.decoder."):-len(".weight")]
+ key_map["base_model.model.{}".format(key_lora)] = k # Official base model loras
+ key_map["lycoris_{}".format(key_lora.replace(".", "_"))] = k # LyCORIS/LoKR format
+
+ if isinstance(model, comfy.model_base.ErnieImage):
+ for k in sdk:
+ if k.startswith("diffusion_model.") and k.endswith(".weight"):
+ key_lora = k[len("diffusion_model."):-len(".weight")]
+ key_map["transformer.{}".format(key_lora)] = k
+
+ if isinstance(model, (comfy.model_base.LTXV, comfy.model_base.LTXAV)):
+ for k in sdk:
+ if k.startswith("diffusion_model.") and k.endswith(".weight"):
+ key_lora = k[len("diffusion_model."):-len(".weight")]
+ key_map["{}".format(key_lora)] = k
+
+ return key_map
+
+
+def pad_tensor_to_shape(tensor: torch.Tensor, new_shape: list[int]) -> torch.Tensor:
+ """
+ Pad a tensor to a new shape with zeros.
+
+ Args:
+ tensor (torch.Tensor): The original tensor to be padded.
+ new_shape (List[int]): The desired shape of the padded tensor.
+
+ Returns:
+ torch.Tensor: A new tensor padded with zeros to the specified shape.
+
+ Note:
+ If the new shape is smaller than the original tensor in any dimension,
+ the original tensor will be truncated in that dimension.
+ """
+ if any([new_shape[i] < tensor.shape[i] for i in range(len(new_shape))]):
+ raise ValueError("The new shape must be larger than the original tensor in all dimensions")
+
+ if len(new_shape) != len(tensor.shape):
+ raise ValueError("The new shape must have the same number of dimensions as the original tensor")
+
+ # Create a new tensor filled with zeros
+ padded_tensor = torch.zeros(new_shape, dtype=tensor.dtype, device=tensor.device)
+
+ # Create slicing tuples for both tensors
+ orig_slices = tuple(slice(0, dim) for dim in tensor.shape)
+ new_slices = tuple(slice(0, dim) for dim in tensor.shape)
+
+ # Copy the original tensor into the new tensor
+ padded_tensor[new_slices] = tensor[orig_slices]
+
+ return padded_tensor
+
+def calculate_shape(patches, weight, key, original_weights=None):
+ current_shape = weight.shape
+
+ for p in patches:
+ v = p[1]
+ offset = p[3]
+
+ # Offsets restore the old shape; lists force a diff without metadata
+ if offset is not None or isinstance(v, list):
+ continue
+
+ if isinstance(v, weight_adapter.WeightAdapterBase):
+ adapter_shape = v.calculate_shape(key)
+ if adapter_shape is not None:
+ current_shape = adapter_shape
+ continue
+
+ # Standard diff logic with padding
+ if len(v) == 2:
+ patch_type, patch_data = v[0], v[1]
+ if patch_type == "diff" and len(patch_data) > 1 and patch_data[1]['pad_weight']:
+ current_shape = patch_data[0].shape
+
+ return current_shape
+
+def calculate_weight(patches, weight, key, intermediate_dtype=torch.float32, original_weights=None):
+ for p in patches:
+ strength = p[0]
+ v = p[1]
+ strength_model = p[2]
+ offset = p[3]
+ function = p[4]
+ if function is None:
+ function = lambda a: a
+
+ old_weight = None
+ if offset is not None:
+ old_weight = weight
+ weight = weight.narrow(offset[0], offset[1], offset[2])
+
+ if strength_model != 1.0:
+ weight *= strength_model
+
+ if isinstance(v, list):
+ v = (calculate_weight(v[1:], v[0][1](comfy.model_management.cast_to_device(v[0][0], weight.device, intermediate_dtype, copy=True), inplace=True), key, intermediate_dtype=intermediate_dtype), )
+
+ if isinstance(v, weight_adapter.WeightAdapterBase):
+ output = v.calculate_weight(weight, key, strength, strength_model, offset, function, intermediate_dtype, original_weights)
+ if output is None:
+ logging.warning("Calculate Weight Failed: {} {}".format(v.name, key))
+ else:
+ weight = output
+ if old_weight is not None:
+ weight = old_weight
+ continue
+
+ if len(v) == 1:
+ patch_type = "diff"
+ elif len(v) == 2:
+ patch_type = v[0]
+ v = v[1]
+
+ if patch_type == "diff":
+ diff: torch.Tensor = v[0]
+ # An extra flag to pad the weight if the diff's shape is larger than the weight
+ do_pad_weight = len(v) > 1 and v[1]['pad_weight']
+ if do_pad_weight and diff.shape != weight.shape:
+ logging.info("Pad weight {} from {} to shape: {}".format(key, weight.shape, diff.shape))
+ weight = pad_tensor_to_shape(weight, diff.shape)
+
+ if strength != 0.0:
+ if diff.shape != weight.shape:
+ logging.warning("WARNING SHAPE MISMATCH {} WEIGHT NOT MERGED {} != {}".format(key, diff.shape, weight.shape))
+ else:
+ weight += function(strength * comfy.model_management.cast_to_device(diff, weight.device, weight.dtype))
+ elif patch_type == "set":
+ weight.copy_(v[0])
+ elif patch_type == "model_as_lora":
+ target_weight: torch.Tensor = v[0]
+ diff_weight = comfy.model_management.cast_to_device(target_weight, weight.device, intermediate_dtype) - \
+ comfy.model_management.cast_to_device(original_weights[key][0][0], weight.device, intermediate_dtype)
+ weight += function(strength * comfy.model_management.cast_to_device(diff_weight, weight.device, weight.dtype))
+ else:
+ logging.warning("patch type not recognized {} {}".format(patch_type, key))
+
+ if old_weight is not None:
+ weight = old_weight
+
+ return weight
+
+def prefetch_prepared_value(value, counter, destination, stream, copy):
+ if isinstance(value, torch.Tensor):
+ size = comfy.memory_management.vram_aligned_size(value)
+ offset = counter[0]
+ counter[0] += size
+ if destination is None:
+ return value
+
+ dest = destination[offset:offset + size]
+ if copy:
+ comfy.model_management.cast_to_gathered([value], dest, non_blocking=True, stream=stream)
+ return comfy.memory_management.interpret_gathered_like([value], dest)[0]
+ elif isinstance(value, weight_adapter.WeightAdapterBase):
+ return type(value)(value.loaded_keys, prefetch_prepared_value(value.weights, counter, destination, stream, copy))
+ elif isinstance(value, tuple):
+ return tuple(prefetch_prepared_value(item, counter, destination, stream, copy) for item in value)
+ elif isinstance(value, list):
+ return [prefetch_prepared_value(item, counter, destination, stream, copy) for item in value]
+
+ return value
diff --git a/ComfyUI/comfy/lora_convert.py b/ComfyUI/comfy/lora_convert.py
new file mode 100644
index 0000000000000000000000000000000000000000..749e81df3a24c0a26327ed93b7b3c4823e350482
--- /dev/null
+++ b/ComfyUI/comfy/lora_convert.py
@@ -0,0 +1,43 @@
+import torch
+import comfy.utils
+
+
+def convert_lora_bfl_control(sd): #BFL loras for Flux
+ sd_out = {}
+ for k in sd:
+ k_to = "diffusion_model.{}".format(k.replace(".lora_B.bias", ".diff_b").replace("_norm.scale", "_norm.set_weight"))
+ sd_out[k_to] = sd[k]
+
+ sd_out["diffusion_model.img_in.reshape_weight"] = torch.tensor([sd["img_in.lora_B.weight"].shape[0], sd["img_in.lora_A.weight"].shape[1]])
+ return sd_out
+
+
+def convert_lora_wan_fun(sd): #Wan Fun loras
+ return comfy.utils.state_dict_prefix_replace(sd, {"lora_unet__": "lora_unet_"})
+
+def convert_uso_lora(sd):
+ sd_out = {}
+ for k in sd:
+ tensor = sd[k]
+ k_to = "diffusion_model.{}".format(k.replace(".down.weight", ".lora_down.weight")
+ .replace(".up.weight", ".lora_up.weight")
+ .replace(".qkv_lora2.", ".txt_attn.qkv.")
+ .replace(".qkv_lora1.", ".img_attn.qkv.")
+ .replace(".proj_lora1.", ".img_attn.proj.")
+ .replace(".proj_lora2.", ".txt_attn.proj.")
+ .replace(".qkv_lora.", ".linear1_qkv.")
+ .replace(".proj_lora.", ".linear2.")
+ .replace(".processor.", ".")
+ )
+ sd_out[k_to] = tensor
+ return sd_out
+
+
+def convert_lora(sd):
+ if "img_in.lora_A.weight" in sd and "single_blocks.0.norm.key_norm.scale" in sd:
+ return convert_lora_bfl_control(sd)
+ if "lora_unet__blocks_0_cross_attn_k.lora_down.weight" in sd:
+ return convert_lora_wan_fun(sd)
+ if "single_blocks.37.processor.qkv_lora.up.weight" in sd and "double_blocks.18.processor.qkv_lora2.up.weight" in sd:
+ return convert_uso_lora(sd)
+ return sd
diff --git a/ComfyUI/comfy/memory_management.py b/ComfyUI/comfy/memory_management.py
new file mode 100644
index 0000000000000000000000000000000000000000..e032b7dcdae5b69cbec6caf690dfbd9988f5f1ea
--- /dev/null
+++ b/ComfyUI/comfy/memory_management.py
@@ -0,0 +1,187 @@
+import math
+import ctypes
+import dataclasses
+import torch
+from typing import NamedTuple
+
+import comfy_aimdo.host_buffer
+from comfy.quant_ops import QuantizedTensor
+
+
+class TensorFileSlice(NamedTuple):
+ file_ref: object
+ lock: object
+ offset: int
+ size: int
+
+
+def read_tensor_file_slice_into(tensor, destination, stream=None, destination2=None):
+
+ if isinstance(tensor, QuantizedTensor):
+ if not read_tensor_file_slice_into(tensor._qdata,
+ destination._qdata if destination is not None else None, stream=stream,
+ destination2=(destination2._qdata if destination2 is not None else None)):
+ return False
+
+ if destination is not None:
+ dst_orig_dtype = destination._params.orig_dtype
+ destination._params.copy_from(tensor._params, non_blocking=False)
+ destination._params = dataclasses.replace(destination._params, orig_dtype=dst_orig_dtype)
+ if destination2 is not None:
+ dst_orig_dtype = destination2._params.orig_dtype
+ destination2._params.copy_from(destination._params if destination is not None else tensor._params, non_blocking=True)
+ destination2._params = dataclasses.replace(destination2._params, orig_dtype=dst_orig_dtype)
+ return True
+
+ info = getattr(tensor.untyped_storage(), "_comfy_tensor_file_slice", None)
+ if info is None:
+ return False
+
+ if destination is not None and destination.device.type != "cpu" and destination2 is None:
+ destination2 = destination
+ destination = None
+
+ file_obj = info.file_ref
+ if (file_obj is None
+ or (destination is None and destination2 is None)
+ or (destination is not None and (destination.device.type != "cpu" or destination.numel() * destination.element_size() < info.size))
+ or (destination2 is not None and (destination2.device.type == "cpu" or destination2.numel() * destination2.element_size() < info.size))
+ or tensor.numel() * tensor.element_size() != info.size
+ or tensor.storage_offset() != 0
+ or not tensor.is_contiguous()):
+ return False
+
+ if info.size == 0:
+ return True
+
+ if destination is None:
+ stream_ptr = getattr(stream, "cuda_stream", 0) if stream is not None else 0
+ comfy_aimdo.host_buffer.read_file_to_device(file_obj, info.offset, info.size,
+ stream_ptr, destination2.data_ptr(),
+ destination2.device.index,
+ mark_cold=False)
+ return True
+
+ hostbuf = getattr(destination.untyped_storage(), "_comfy_hostbuf", None)
+ if hostbuf is not None:
+ stream_ptr = getattr(stream, "cuda_stream", 0) if stream is not None else 0
+ device_ptr = destination2.data_ptr() if destination2 is not None else 0
+ with info.lock:
+ hostbuf.read_file_slice(file_obj, info.offset, info.size,
+ offset=destination.data_ptr() - hostbuf.get_raw_address(),
+ stream=stream_ptr,
+ device_ptr=device_ptr,
+ device=None if destination2 is None else destination2.device.index)
+ return True
+
+ if not hasattr(file_obj, "seek") or not hasattr(file_obj, "readinto"):
+ return False
+
+ buf_type = ctypes.c_ubyte * info.size
+ view = memoryview(buf_type.from_address(destination.data_ptr()))
+
+ try:
+ with info.lock:
+ file_obj.seek(info.offset)
+ done = 0
+ while done < info.size:
+ try:
+ n = file_obj.readinto(view[done:])
+ except OSError:
+ return False
+ if n <= 0:
+ return False
+ done += n
+ return True
+ finally:
+ view.release()
+
+class TensorGeometry(NamedTuple):
+ shape: any
+ dtype: torch.dtype
+
+ def element_size(self):
+ info = torch.finfo(self.dtype) if self.dtype.is_floating_point else torch.iinfo(self.dtype)
+ return info.bits // 8
+
+ def numel(self):
+ return math.prod(self.shape)
+
+def tensors_to_geometries(tensors, dtype=None):
+ geometries = []
+ for t in tensors:
+ if t is None or isinstance(t, QuantizedTensor):
+ geometries.append(t)
+ continue
+ tdtype = t.dtype
+ if hasattr(t, "_model_dtype"):
+ tdtype = t._model_dtype
+ if dtype is not None:
+ tdtype = dtype
+ geometries.append(TensorGeometry(shape=t.shape, dtype=tdtype))
+ return geometries
+
+def vram_aligned_size(tensor):
+ if isinstance(tensor, list):
+ return sum([vram_aligned_size(t) for t in tensor])
+
+ if isinstance(tensor, QuantizedTensor):
+ inner_tensors, _ = tensor.__tensor_flatten__()
+ return vram_aligned_size([ getattr(tensor, attr) for attr in inner_tensors ])
+
+ if tensor is None:
+ return 0
+
+ size = tensor.numel() * tensor.element_size()
+ aligment_req = 1024
+ return (size + aligment_req - 1) // aligment_req * aligment_req
+
+def interpret_gathered_like(tensors, gathered):
+ offset = 0
+ dest_views = []
+
+ if gathered.dim() != 1 or gathered.element_size() != 1:
+ raise ValueError(f"Buffer must be 1D and single-byte (got {gathered.dim()}D {gathered.dtype})")
+
+ for tensor in tensors:
+
+ if tensor is None:
+ dest_views.append(None)
+ continue
+
+ if isinstance(tensor, QuantizedTensor):
+ inner_tensors, qt_ctx = tensor.__tensor_flatten__()
+ templates = { attr: getattr(tensor, attr) for attr in inner_tensors }
+ else:
+ templates = { "data": tensor }
+
+ actuals = {}
+ for attr, template in templates.items():
+ size = template.numel() * template.element_size()
+ if offset + size > gathered.numel():
+ raise ValueError(f"Buffer too small: needs {offset + size} bytes, but only has {gathered.numel()}. ")
+ actuals[attr] = gathered[offset:offset+size].view(dtype=template.dtype).view(template.shape)
+ offset += vram_aligned_size(template)
+
+ if isinstance(tensor, QuantizedTensor):
+ dest_views.append(QuantizedTensor.__tensor_unflatten__(actuals, qt_ctx, 0, 0))
+ else:
+ dest_views.append(actuals["data"])
+
+ return dest_views
+
+aimdo_enabled = False
+
+extra_ram_release_callback = None
+RAM_CACHE_HEADROOM = 0
+
+def set_ram_cache_release_state(callback, headroom):
+ global extra_ram_release_callback
+ global RAM_CACHE_HEADROOM
+ extra_ram_release_callback = callback
+ RAM_CACHE_HEADROOM = max(0, int(headroom))
+
+def extra_ram_release(target, free_active=False):
+ if extra_ram_release_callback is None:
+ return 0
+ return extra_ram_release_callback(target, free_active=free_active)
diff --git a/ComfyUI/comfy/model_base.py b/ComfyUI/comfy/model_base.py
new file mode 100644
index 0000000000000000000000000000000000000000..6631c9eb0e58f7328a11f2d042818c7faaa1bfee
--- /dev/null
+++ b/ComfyUI/comfy/model_base.py
@@ -0,0 +1,2680 @@
+"""
+ This file is part of ComfyUI.
+ Copyright (C) 2024 Comfy
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+"""
+
+import comfy.ldm.hunyuan3dv2_1
+import comfy.ldm.hunyuan3dv2_1.hunyuandit
+import torch
+import logging
+import comfy.ldm.lightricks.av_model
+import comfy.ldm.minimax.model
+import comfy.ldm.lightricks.symmetric_patchifier
+import comfy.context_windows
+from comfy.ldm.modules.diffusionmodules.openaimodel import UNetModel, Timestep
+from comfy.ldm.cascade.stage_c import StageC
+from comfy.ldm.cascade.stage_b import StageB
+from comfy.ldm.modules.encoders.noise_aug_modules import CLIPEmbeddingNoiseAugmentation
+from comfy.ldm.modules.diffusionmodules.upscaling import ImageConcatWithNoiseAugmentation
+from comfy.ldm.modules.diffusionmodules.mmdit import OpenAISignatureMMDITWrapper
+import comfy.ldm.genmo.joint_model.asymm_models_joint
+import comfy.ldm.aura.mmdit
+import comfy.ldm.pixart.pixartms
+import comfy.ldm.hydit.models
+import comfy.ldm.audio.dit
+import comfy.ldm.audio.embedders
+import comfy.ldm.flux.model
+import comfy.ldm.lens.model
+import comfy.ldm.lightricks.model
+import comfy.ldm.hunyuan_video.model
+import comfy.ldm.cosmos.model
+import comfy.ldm.cosmos.predict2
+import comfy.ldm.lumina.model
+import comfy.ldm.wan.model
+import comfy.ldm.wan.model_animate
+import comfy.ldm.wan.ar_model
+import comfy.ldm.wan.model_wandancer
+import comfy.ldm.hunyuan3d.model
+import comfy.ldm.triposplat.model
+import comfy.ldm.hidream.model
+import comfy.ldm.chroma.model
+import comfy.ldm.chroma_radiance.model
+import comfy.ldm.pixeldit.model
+import comfy.ldm.pixeldit.pid
+import comfy.ldm.ace.model
+import comfy.ldm.omnigen.omnigen2
+import comfy.ldm.seedvr.model
+import comfy.ldm.boogu.model
+import comfy.ldm.qwen_image.model
+import comfy.ldm.mage_flow.model
+import comfy.ldm.joyimage.model
+import comfy.ldm.ideogram4.model
+import comfy.ldm.krea2.model
+import comfy.ldm.kandinsky5.model
+import comfy.ldm.anima.model
+import comfy.ldm.ace.ace_step15
+import comfy.ldm.cogvideo.model
+import comfy.ldm.rt_detr.rtdetr_v4
+import comfy.ldm.ernie.model
+import comfy.ldm.sam3.detector
+import comfy.ldm.hidream_o1.model
+from comfy.ldm.hidream_o1.conditioning import build_extra_conds
+import comfy.ldm.depth_anything_3.model
+
+import comfy.model_management
+import comfy.patcher_extension
+import comfy.conds
+import comfy.ops
+from enum import Enum
+from . import utils
+import comfy.latent_formats
+import comfy.model_sampling
+import math
+from typing import TYPE_CHECKING
+if TYPE_CHECKING:
+ from comfy.model_patcher import ModelPatcher
+
+class ModelType(Enum):
+ EPS = 1
+ V_PREDICTION = 2
+ V_PREDICTION_EDM = 3
+ STABLE_CASCADE = 4
+ EDM = 5
+ FLOW = 6
+ V_PREDICTION_CONTINUOUS = 7
+ FLUX = 8
+ IMG_TO_IMG = 9
+ FLOW_COSMOS = 10
+ IMG_TO_IMG_FLOW = 11
+ V_PREDICTION_DDPM = 12
+
+
+def model_sampling(model_config, model_type):
+ s = comfy.model_sampling.ModelSamplingDiscrete
+
+ if model_type == ModelType.EPS:
+ c = comfy.model_sampling.EPS
+ elif model_type == ModelType.V_PREDICTION:
+ c = comfy.model_sampling.V_PREDICTION
+ elif model_type == ModelType.V_PREDICTION_EDM:
+ c = comfy.model_sampling.V_PREDICTION
+ s = comfy.model_sampling.ModelSamplingContinuousEDM
+ elif model_type == ModelType.FLOW:
+ c = comfy.model_sampling.CONST
+ s = comfy.model_sampling.ModelSamplingDiscreteFlow
+ elif model_type == ModelType.STABLE_CASCADE:
+ c = comfy.model_sampling.EPS
+ s = comfy.model_sampling.StableCascadeSampling
+ elif model_type == ModelType.EDM:
+ c = comfy.model_sampling.EDM
+ s = comfy.model_sampling.ModelSamplingContinuousEDM
+ elif model_type == ModelType.V_PREDICTION_CONTINUOUS:
+ c = comfy.model_sampling.V_PREDICTION
+ s = comfy.model_sampling.ModelSamplingContinuousV
+ elif model_type == ModelType.FLUX:
+ c = comfy.model_sampling.CONST
+ s = comfy.model_sampling.ModelSamplingFlux
+ elif model_type == ModelType.IMG_TO_IMG:
+ c = comfy.model_sampling.IMG_TO_IMG
+ elif model_type == ModelType.FLOW_COSMOS:
+ c = comfy.model_sampling.COSMOS_RFLOW
+ s = comfy.model_sampling.ModelSamplingCosmosRFlow
+ elif model_type == ModelType.IMG_TO_IMG_FLOW:
+ c = comfy.model_sampling.IMG_TO_IMG_FLOW
+ elif model_type == ModelType.V_PREDICTION_DDPM:
+ c = comfy.model_sampling.V_PREDICTION_DDPM
+
+ class ModelSampling(s, c):
+ pass
+
+ return ModelSampling(model_config)
+
+
+def convert_tensor(extra, dtype, device):
+ if hasattr(extra, "dtype"):
+ if extra.dtype != torch.int and extra.dtype != torch.long:
+ extra = comfy.model_management.cast_to_device(extra, device, dtype)
+ else:
+ extra = comfy.model_management.cast_to_device(extra, device, None)
+ return extra
+
+
+class BaseModel(torch.nn.Module):
+ def __init__(self, model_config, model_type=ModelType.EPS, device=None, unet_model=UNetModel):
+ super().__init__()
+
+ unet_config = model_config.unet_config
+ self.latent_format = model_config.latent_format
+ self.model_config = model_config
+ self.manual_cast_dtype = model_config.manual_cast_dtype
+ self.device = device
+ self.current_patcher: 'ModelPatcher' = None
+
+ if not unet_config.get("disable_unet_model_creation", False):
+ if model_config.custom_operations is None:
+ fp8 = model_config.optimizations.get("fp8", False)
+ operations = comfy.ops.pick_operations(unet_config.get("dtype", None), self.manual_cast_dtype, fp8_optimizations=fp8, model_config=model_config)
+ else:
+ operations = model_config.custom_operations
+ self.diffusion_model = unet_model(**unet_config, device=device, operations=operations)
+ self.diffusion_model.requires_grad_(False)
+ self.diffusion_model.eval()
+ if comfy.model_management.force_channels_last():
+ self.diffusion_model.to(memory_format=torch.channels_last)
+ logging.debug("using channels last mode for diffusion model")
+ logging.info("model weight dtype {}, manual cast: {}".format(self.get_dtype(), self.manual_cast_dtype))
+ comfy.model_management.archive_model_dtypes(self.diffusion_model)
+
+ self.model_type = model_type
+ self.model_sampling = model_sampling(model_config, model_type)
+
+ self.adm_channels = unet_config.get("adm_in_channels", None)
+ if self.adm_channels is None:
+ self.adm_channels = 0
+
+ self.concat_keys = ()
+ logging.info("model_type {}".format(model_type.name))
+ logging.debug("adm {}".format(self.adm_channels))
+ self.memory_usage_factor = model_config.memory_usage_factor
+ self.memory_usage_factor_conds = ()
+ self.memory_usage_shape_process = {}
+
+ def apply_model(self, x, t, c_concat=None, c_crossattn=None, control=None, transformer_options={}, **kwargs):
+ return comfy.patcher_extension.WrapperExecutor.new_class_executor(
+ self._apply_model,
+ self,
+ comfy.patcher_extension.get_all_wrappers(comfy.patcher_extension.WrappersMP.APPLY_MODEL, transformer_options)
+ ).execute(x, t, c_concat, c_crossattn, control, transformer_options, **kwargs)
+
+ def _apply_model(self, x, t, c_concat=None, c_crossattn=None, control=None, transformer_options={}, **kwargs):
+ sigma = t
+ xc = self.model_sampling.calculate_input(sigma, x)
+
+ if c_concat is not None:
+ xc = torch.cat([xc] + [comfy.model_management.cast_to_device(c_concat, xc.device, xc.dtype)], dim=1)
+
+ context = c_crossattn
+ dtype = self.get_dtype_inference()
+
+ xc = xc.to(dtype)
+ device = xc.device
+ t = self.model_sampling.timestep(t).float()
+ if context is not None:
+ context = comfy.model_management.cast_to_device(context, device, dtype)
+
+ extra_conds = {}
+ for o in kwargs:
+ extra = kwargs[o]
+
+ if hasattr(extra, "dtype"):
+ extra = convert_tensor(extra, dtype, device)
+ elif isinstance(extra, list):
+ ex = []
+ for ext in extra:
+ ex.append(convert_tensor(ext, dtype, device))
+ extra = ex
+ extra_conds[o] = extra
+
+ t = self.process_timestep(t, x=x, **extra_conds)
+ if "latent_shapes" in extra_conds:
+ xc = utils.unpack_latents(xc, extra_conds.pop("latent_shapes"))
+
+ transformer_options = transformer_options.copy()
+ transformer_options["prefetch_dynamic_vbars"] = (
+ self.current_patcher is not None and self.current_patcher.is_dynamic()
+ )
+
+ model_output = self.diffusion_model(xc, t, context=context, control=control, transformer_options=transformer_options, **extra_conds)
+ if len(model_output) > 1 and not torch.is_tensor(model_output):
+ model_output, _ = utils.pack_latents(model_output)
+
+ return self.model_sampling.calculate_denoised(sigma, model_output.float(), x)
+
+ def process_timestep(self, timestep, **kwargs):
+ return timestep
+
+ def get_dtype(self):
+ return self.diffusion_model.dtype
+
+ def get_dtype_inference(self):
+ dtype = self.get_dtype()
+
+ if self.manual_cast_dtype is not None:
+ dtype = self.manual_cast_dtype
+ return dtype
+
+ def encode_adm(self, **kwargs):
+ return None
+
+ def concat_cond(self, **kwargs):
+ if len(self.concat_keys) > 0:
+ cond_concat = []
+ denoise_mask = kwargs.get("concat_mask", kwargs.get("denoise_mask", None))
+ concat_latent_image = kwargs.get("concat_latent_image", None)
+ if concat_latent_image is None:
+ concat_latent_image = kwargs.get("latent_image", None)
+ else:
+ concat_latent_image = self.process_latent_in(concat_latent_image)
+
+ noise = kwargs.get("noise", None)
+ device = kwargs["device"]
+
+ if concat_latent_image.shape[1:] != noise.shape[1:]:
+ concat_latent_image = utils.common_upscale(concat_latent_image, noise.shape[-1], noise.shape[-2], "bilinear", "center")
+ if noise.ndim == 5:
+ if concat_latent_image.shape[-3] < noise.shape[-3]:
+ concat_latent_image = torch.nn.functional.pad(concat_latent_image, (0, 0, 0, 0, 0, noise.shape[-3] - concat_latent_image.shape[-3]), "constant", 0)
+ else:
+ concat_latent_image = concat_latent_image[:, :, :noise.shape[-3]]
+
+ concat_latent_image = utils.resize_to_batch_size(concat_latent_image, noise.shape[0])
+
+ if denoise_mask is not None:
+ if len(denoise_mask.shape) == len(noise.shape):
+ denoise_mask = denoise_mask[:, :1]
+
+ num_dim = noise.ndim - 2
+ denoise_mask = denoise_mask.reshape((-1, 1) + tuple(denoise_mask.shape[-num_dim:]))
+ if denoise_mask.shape[-2:] != noise.shape[-2:]:
+ denoise_mask = utils.common_upscale(denoise_mask, noise.shape[-1], noise.shape[-2], "bilinear", "center")
+ denoise_mask = utils.resize_to_batch_size(denoise_mask.round(), noise.shape[0])
+
+ for ck in self.concat_keys:
+ if denoise_mask is not None:
+ if ck == "mask":
+ cond_concat.append(denoise_mask.to(device))
+ elif ck == "masked_image":
+ cond_concat.append(concat_latent_image.to(device)) # NOTE: the latent_image should be masked by the mask in pixel space
+ elif ck == "mask_inverted":
+ cond_concat.append(1.0 - denoise_mask.to(device))
+ else:
+ if ck == "mask":
+ cond_concat.append(torch.ones_like(noise)[:, :1])
+ elif ck == "masked_image":
+ cond_concat.append(self.blank_inpaint_image_like(noise))
+ elif ck == "mask_inverted":
+ cond_concat.append(torch.zeros_like(noise)[:, :1])
+ if ck == "concat_image":
+ if concat_latent_image is not None:
+ cond_concat.append(concat_latent_image.to(device))
+ else:
+ cond_concat.append(torch.zeros_like(noise))
+ data = torch.cat(cond_concat, dim=1)
+ return data
+ return None
+
+ def resize_cond_for_context_window(self, cond_key, cond_value, window, x_in, device, retain_index_list=[]):
+ """Override in subclasses to handle model-specific cond slicing for context windows.
+ Return a sliced cond object, or None to fall through to default handling.
+ Use comfy.context_windows.slice_cond() for common cases."""
+ return None
+
+ def extra_conds(self, **kwargs):
+ out = {}
+ concat_cond = self.concat_cond(**kwargs)
+ if concat_cond is not None:
+ out['c_concat'] = comfy.conds.CONDNoiseShape(concat_cond)
+
+ adm = self.encode_adm(**kwargs)
+ if adm is not None:
+ out['y'] = comfy.conds.CONDRegular(adm)
+
+ cross_attn = kwargs.get("cross_attn", None)
+ if cross_attn is not None:
+ out['c_crossattn'] = comfy.conds.CONDCrossAttn(cross_attn)
+
+ cross_attn_cnet = kwargs.get("cross_attn_controlnet", None)
+ if cross_attn_cnet is not None:
+ out['crossattn_controlnet'] = comfy.conds.CONDCrossAttn(cross_attn_cnet)
+
+ c_concat = kwargs.get("noise_concat", None)
+ if c_concat is not None:
+ out['c_concat'] = comfy.conds.CONDNoiseShape(c_concat)
+
+ return out
+
+ def load_model_weights(self, sd, unet_prefix="", assign=False):
+ to_load = {}
+ keys = list(sd.keys())
+ for k in keys:
+ if k.startswith(unet_prefix):
+ to_load[k[len(unet_prefix):]] = sd.pop(k)
+
+ to_load = self.model_config.process_unet_state_dict(to_load)
+ m, u = self.diffusion_model.load_state_dict(to_load, strict=False, assign=assign)
+ if len(m) > 0:
+ logging.warning("unet missing: {}".format(m))
+
+ if len(u) > 0:
+ logging.warning("unet unexpected: {}".format(u))
+ del to_load
+ return self
+
+ def process_latent_in(self, latent):
+ return self.latent_format.process_in(latent)
+
+ def process_latent_out(self, latent):
+ return self.latent_format.process_out(latent)
+
+ def state_dict_for_saving(self, unet_state_dict, clip_state_dict=None, vae_state_dict=None, clip_vision_state_dict=None):
+ extra_sds = []
+ if clip_state_dict is not None:
+ extra_sds.append(self.model_config.process_clip_state_dict_for_saving(clip_state_dict))
+ if vae_state_dict is not None:
+ extra_sds.append(self.model_config.process_vae_state_dict_for_saving(vae_state_dict))
+ if clip_vision_state_dict is not None:
+ extra_sds.append(self.model_config.process_clip_vision_state_dict_for_saving(clip_vision_state_dict))
+ unet_state_dict = self.model_config.process_unet_state_dict_for_saving(unet_state_dict)
+ if self.model_type == ModelType.V_PREDICTION:
+ unet_state_dict["v_pred"] = torch.tensor([])
+
+ for sd in extra_sds:
+ unet_state_dict.update(sd)
+
+ return unet_state_dict
+
+ def set_inpaint(self):
+ self.concat_keys = ("mask", "masked_image")
+ def blank_inpaint_image_like(latent_image):
+ blank_image = torch.ones_like(latent_image)
+ # these are the values for "zero" in pixel space translated to latent space
+ blank_image[:,0] *= 0.8223
+ blank_image[:,1] *= -0.6876
+ blank_image[:,2] *= 0.6364
+ blank_image[:,3] *= 0.1380
+ return blank_image
+ self.blank_inpaint_image_like = blank_inpaint_image_like
+
+ def scale_latent_inpaint(self, sigma, noise, latent_image, **kwargs):
+ return self.model_sampling.noise_scaling(sigma.reshape([sigma.shape[0]] + [1] * (len(noise.shape) - 1)), noise, latent_image)
+
+ def memory_required(self, input_shape, cond_shapes={}):
+ input_shapes = [input_shape]
+ for c in self.memory_usage_factor_conds:
+ shape = cond_shapes.get(c, None)
+ if shape is not None:
+ if c in self.memory_usage_shape_process:
+ out = []
+ for s in shape:
+ out.append(self.memory_usage_shape_process[c](s))
+ shape = out
+
+ if len(shape) > 0:
+ input_shapes += shape
+
+ if comfy.model_management.xformers_enabled() or comfy.model_management.pytorch_attention_flash_attention():
+ dtype = self.get_dtype_inference()
+ #TODO: this needs to be tweaked
+ area = sum(map(lambda input_shape: input_shape[0] * math.prod(input_shape[2:]), input_shapes))
+ return (area * comfy.model_management.dtype_size(dtype) * 0.01 * self.memory_usage_factor) * (1024 * 1024)
+ else:
+ #TODO: this formula might be too aggressive since I tweaked the sub-quad and split algorithms to use less memory.
+ area = sum(map(lambda input_shape: input_shape[0] * math.prod(input_shape[2:]), input_shapes))
+ return (area * 0.15 * self.memory_usage_factor) * (1024 * 1024)
+
+ def extra_conds_shapes(self, **kwargs):
+ return {}
+
+
+def unclip_adm(unclip_conditioning, device, noise_augmentor, noise_augment_merge=0.0, seed=None):
+ adm_inputs = []
+ weights = []
+ noise_aug = []
+ for unclip_cond in unclip_conditioning:
+ for adm_cond in unclip_cond["clip_vision_output"].image_embeds:
+ weight = unclip_cond["strength"]
+ noise_augment = unclip_cond["noise_augmentation"]
+ noise_level = round((noise_augmentor.max_noise_level - 1) * noise_augment)
+ c_adm, noise_level_emb = noise_augmentor(adm_cond.to(device), noise_level=torch.tensor([noise_level], device=device), seed=seed)
+ adm_out = torch.cat((c_adm, noise_level_emb), 1) * weight
+ weights.append(weight)
+ noise_aug.append(noise_augment)
+ adm_inputs.append(adm_out)
+
+ if len(noise_aug) > 1:
+ adm_out = torch.stack(adm_inputs).sum(0)
+ noise_augment = noise_augment_merge
+ noise_level = round((noise_augmentor.max_noise_level - 1) * noise_augment)
+ c_adm, noise_level_emb = noise_augmentor(adm_out[:, :noise_augmentor.time_embed.dim], noise_level=torch.tensor([noise_level], device=device))
+ adm_out = torch.cat((c_adm, noise_level_emb), 1)
+
+ return adm_out
+
+class SD21UNCLIP(BaseModel):
+ def __init__(self, model_config, noise_aug_config, model_type=ModelType.V_PREDICTION, device=None):
+ super().__init__(model_config, model_type, device=device)
+ self.noise_augmentor = CLIPEmbeddingNoiseAugmentation(**noise_aug_config)
+
+ def encode_adm(self, **kwargs):
+ unclip_conditioning = kwargs.get("unclip_conditioning", None)
+ device = kwargs["device"]
+ if unclip_conditioning is None:
+ return torch.zeros((1, self.adm_channels), device=device)
+ else:
+ return unclip_adm(unclip_conditioning, device, self.noise_augmentor, kwargs.get("unclip_noise_augment_merge", 0.05), kwargs.get("seed", 0) - 10)
+
+def sdxl_pooled(args, noise_augmentor):
+ if "unclip_conditioning" in args:
+ return unclip_adm(args.get("unclip_conditioning", None), args["device"], noise_augmentor, seed=args.get("seed", 0) - 10)[:,:1280]
+ else:
+ return args["pooled_output"]
+
+class SDXLRefiner(BaseModel):
+ def __init__(self, model_config, model_type=ModelType.EPS, device=None):
+ super().__init__(model_config, model_type, device=device)
+ self.embedder = Timestep(256)
+ self.noise_augmentor = CLIPEmbeddingNoiseAugmentation(**{"noise_schedule_config": {"timesteps": 1000, "beta_schedule": "squaredcos_cap_v2"}, "timestep_dim": 1280})
+
+ def encode_adm(self, **kwargs):
+ clip_pooled = sdxl_pooled(kwargs, self.noise_augmentor)
+ width = kwargs.get("width", 768)
+ height = kwargs.get("height", 768)
+ crop_w = kwargs.get("crop_w", 0)
+ crop_h = kwargs.get("crop_h", 0)
+
+ if kwargs.get("prompt_type", "") == "negative":
+ aesthetic_score = kwargs.get("aesthetic_score", 2.5)
+ else:
+ aesthetic_score = kwargs.get("aesthetic_score", 6)
+
+ out = []
+ out.append(self.embedder(torch.Tensor([height])))
+ out.append(self.embedder(torch.Tensor([width])))
+ out.append(self.embedder(torch.Tensor([crop_h])))
+ out.append(self.embedder(torch.Tensor([crop_w])))
+ out.append(self.embedder(torch.Tensor([aesthetic_score])))
+ flat = torch.flatten(torch.cat(out)).unsqueeze(dim=0).repeat(clip_pooled.shape[0], 1)
+ return torch.cat((clip_pooled.to(flat.device), flat), dim=1)
+
+class SDXL(BaseModel):
+ def __init__(self, model_config, model_type=ModelType.EPS, device=None):
+ super().__init__(model_config, model_type, device=device)
+ self.embedder = Timestep(256)
+ self.noise_augmentor = CLIPEmbeddingNoiseAugmentation(**{"noise_schedule_config": {"timesteps": 1000, "beta_schedule": "squaredcos_cap_v2"}, "timestep_dim": 1280})
+
+ def encode_adm(self, **kwargs):
+ clip_pooled = sdxl_pooled(kwargs, self.noise_augmentor)
+ width = kwargs.get("width", 768)
+ height = kwargs.get("height", 768)
+ crop_w = kwargs.get("crop_w", 0)
+ crop_h = kwargs.get("crop_h", 0)
+ target_width = kwargs.get("target_width", width)
+ target_height = kwargs.get("target_height", height)
+
+ out = []
+ out.append(self.embedder(torch.Tensor([height])))
+ out.append(self.embedder(torch.Tensor([width])))
+ out.append(self.embedder(torch.Tensor([crop_h])))
+ out.append(self.embedder(torch.Tensor([crop_w])))
+ out.append(self.embedder(torch.Tensor([target_height])))
+ out.append(self.embedder(torch.Tensor([target_width])))
+ flat = torch.flatten(torch.cat(out)).unsqueeze(dim=0).repeat(clip_pooled.shape[0], 1)
+ return torch.cat((clip_pooled.to(flat.device), flat), dim=1)
+
+
+class SVD_img2vid(BaseModel):
+ def __init__(self, model_config, model_type=ModelType.V_PREDICTION_EDM, device=None):
+ super().__init__(model_config, model_type, device=device)
+ self.embedder = Timestep(256)
+
+ def encode_adm(self, **kwargs):
+ fps_id = kwargs.get("fps", 6) - 1
+ motion_bucket_id = kwargs.get("motion_bucket_id", 127)
+ augmentation = kwargs.get("augmentation_level", 0)
+
+ out = []
+ out.append(self.embedder(torch.Tensor([fps_id])))
+ out.append(self.embedder(torch.Tensor([motion_bucket_id])))
+ out.append(self.embedder(torch.Tensor([augmentation])))
+
+ flat = torch.flatten(torch.cat(out)).unsqueeze(dim=0)
+ return flat
+
+ def extra_conds(self, **kwargs):
+ out = {}
+ adm = self.encode_adm(**kwargs)
+ if adm is not None:
+ out['y'] = comfy.conds.CONDRegular(adm)
+
+ latent_image = kwargs.get("concat_latent_image", None)
+ noise = kwargs.get("noise", None)
+
+ if latent_image is None:
+ latent_image = torch.zeros_like(noise)
+
+ if latent_image.shape[1:] != noise.shape[1:]:
+ latent_image = utils.common_upscale(latent_image, noise.shape[-1], noise.shape[-2], "bilinear", "center")
+
+ latent_image = utils.resize_to_batch_size(latent_image, noise.shape[0])
+
+ out['c_concat'] = comfy.conds.CONDNoiseShape(latent_image)
+
+ cross_attn = kwargs.get("cross_attn", None)
+ if cross_attn is not None:
+ out['c_crossattn'] = comfy.conds.CONDCrossAttn(cross_attn)
+
+ if "time_conditioning" in kwargs:
+ out["time_context"] = comfy.conds.CONDCrossAttn(kwargs["time_conditioning"])
+
+ out['num_video_frames'] = comfy.conds.CONDConstant(noise.shape[0])
+ return out
+
+class SV3D_u(SVD_img2vid):
+ def encode_adm(self, **kwargs):
+ augmentation = kwargs.get("augmentation_level", 0)
+
+ out = []
+ out.append(self.embedder(torch.flatten(torch.Tensor([augmentation]))))
+
+ flat = torch.flatten(torch.cat(out)).unsqueeze(dim=0)
+ return flat
+
+class SV3D_p(SVD_img2vid):
+ def __init__(self, model_config, model_type=ModelType.V_PREDICTION_EDM, device=None):
+ super().__init__(model_config, model_type, device=device)
+ self.embedder_512 = Timestep(512)
+
+ def encode_adm(self, **kwargs):
+ augmentation = kwargs.get("augmentation_level", 0)
+ elevation = kwargs.get("elevation", 0) #elevation and azimuth are in degrees here
+ azimuth = kwargs.get("azimuth", 0)
+ noise = kwargs.get("noise", None)
+
+ out = []
+ out.append(self.embedder(torch.flatten(torch.Tensor([augmentation]))))
+ out.append(self.embedder_512(torch.deg2rad(torch.fmod(torch.flatten(90 - torch.Tensor([elevation])), 360.0))))
+ out.append(self.embedder_512(torch.deg2rad(torch.fmod(torch.flatten(torch.Tensor([azimuth])), 360.0))))
+
+ out = list(map(lambda a: utils.resize_to_batch_size(a, noise.shape[0]), out))
+ return torch.cat(out, dim=1)
+
+
+class Stable_Zero123(BaseModel):
+ def __init__(self, model_config, model_type=ModelType.EPS, device=None, cc_projection_weight=None, cc_projection_bias=None):
+ super().__init__(model_config, model_type, device=device)
+ self.cc_projection = comfy.ops.manual_cast.Linear(cc_projection_weight.shape[1], cc_projection_weight.shape[0], dtype=self.get_dtype(), device=device)
+ self.cc_projection.weight = torch.nn.Parameter(cc_projection_weight.clone())
+ self.cc_projection.bias = torch.nn.Parameter(cc_projection_bias.clone())
+
+ def extra_conds(self, **kwargs):
+ out = {}
+
+ latent_image = kwargs.get("concat_latent_image", None)
+ noise = kwargs.get("noise", None)
+
+ if latent_image is None:
+ latent_image = torch.zeros_like(noise)
+
+ if latent_image.shape[1:] != noise.shape[1:]:
+ latent_image = utils.common_upscale(latent_image, noise.shape[-1], noise.shape[-2], "bilinear", "center")
+
+ latent_image = utils.resize_to_batch_size(latent_image, noise.shape[0])
+
+ out['c_concat'] = comfy.conds.CONDNoiseShape(latent_image)
+
+ cross_attn = kwargs.get("cross_attn", None)
+ if cross_attn is not None:
+ if cross_attn.shape[-1] != 768:
+ cross_attn = self.cc_projection(cross_attn)
+ out['c_crossattn'] = comfy.conds.CONDCrossAttn(cross_attn)
+ return out
+
+class SD_X4Upscaler(BaseModel):
+ def __init__(self, model_config, model_type=ModelType.V_PREDICTION, device=None):
+ super().__init__(model_config, model_type, device=device)
+ self.noise_augmentor = ImageConcatWithNoiseAugmentation(noise_schedule_config={"linear_start": 0.0001, "linear_end": 0.02}, max_noise_level=350)
+
+ def extra_conds(self, **kwargs):
+ out = {}
+
+ image = kwargs.get("concat_image", None)
+ noise = kwargs.get("noise", None)
+ noise_augment = kwargs.get("noise_augmentation", 0.0)
+ device = kwargs["device"]
+ seed = kwargs["seed"] - 10
+
+ noise_level = round((self.noise_augmentor.max_noise_level) * noise_augment)
+
+ if image is None:
+ image = torch.zeros_like(noise)[:,:3]
+
+ if image.shape[1:] != noise.shape[1:]:
+ image = utils.common_upscale(image.to(device), noise.shape[-1], noise.shape[-2], "bilinear", "center")
+
+ noise_level = torch.tensor([noise_level], device=device)
+ if noise_augment > 0:
+ image, noise_level = self.noise_augmentor(image.to(device), noise_level=noise_level, seed=seed)
+
+ image = utils.resize_to_batch_size(image, noise.shape[0])
+
+ out['c_concat'] = comfy.conds.CONDNoiseShape(image)
+ out['y'] = comfy.conds.CONDRegular(noise_level)
+
+ cross_attn = kwargs.get("cross_attn", None)
+ if cross_attn is not None:
+ out['c_crossattn'] = comfy.conds.CONDCrossAttn(cross_attn)
+ return out
+
+class IP2P:
+ def concat_cond(self, **kwargs):
+ image = kwargs.get("concat_latent_image", None)
+ noise = kwargs.get("noise", None)
+ device = kwargs["device"]
+
+ if image is None:
+ image = torch.zeros_like(noise)
+ else:
+ image = image.to(device=device)
+
+ if image.shape[1:] != noise.shape[1:]:
+ image = utils.common_upscale(image, noise.shape[-1], noise.shape[-2], "bilinear", "center")
+
+ image = utils.resize_to_batch_size(image, noise.shape[0])
+ return self.process_ip2p_image_in(image)
+
+
+class SD15_instructpix2pix(IP2P, BaseModel):
+ def __init__(self, model_config, model_type=ModelType.EPS, device=None):
+ super().__init__(model_config, model_type, device=device)
+ self.process_ip2p_image_in = lambda image: image
+
+
+class SDXL_instructpix2pix(IP2P, SDXL):
+ def __init__(self, model_config, model_type=ModelType.EPS, device=None):
+ super().__init__(model_config, model_type, device=device)
+ if model_type == ModelType.V_PREDICTION_EDM:
+ self.process_ip2p_image_in = lambda image: comfy.latent_formats.SDXL().process_in(image) #cosxl ip2p
+ else:
+ self.process_ip2p_image_in = lambda image: image #diffusers ip2p
+
+class Lotus(BaseModel):
+ def extra_conds(self, **kwargs):
+ out = {}
+ cross_attn = kwargs.get("cross_attn", None)
+ out['c_crossattn'] = comfy.conds.CONDCrossAttn(cross_attn)
+ device = kwargs["device"]
+ task_emb = torch.tensor([1, 0]).float().to(device)
+ task_emb = torch.cat([torch.sin(task_emb), torch.cos(task_emb)]).unsqueeze(0)
+ out['y'] = comfy.conds.CONDRegular(task_emb)
+ return out
+
+ def __init__(self, model_config, model_type=ModelType.IMG_TO_IMG, device=None):
+ super().__init__(model_config, model_type, device=device)
+
+class StableCascade_C(BaseModel):
+ def __init__(self, model_config, model_type=ModelType.STABLE_CASCADE, device=None):
+ super().__init__(model_config, model_type, device=device, unet_model=StageC)
+
+ def extra_conds(self, **kwargs):
+ out = {}
+ clip_text_pooled = kwargs["pooled_output"]
+ if clip_text_pooled is not None:
+ out['clip_text_pooled'] = comfy.conds.CONDRegular(clip_text_pooled)
+
+ if "unclip_conditioning" in kwargs:
+ embeds = []
+ for unclip_cond in kwargs["unclip_conditioning"]:
+ weight = unclip_cond["strength"]
+ embeds.append(unclip_cond["clip_vision_output"].image_embeds.unsqueeze(0) * weight)
+ clip_img = torch.cat(embeds, dim=1)
+ else:
+ clip_img = torch.zeros((1, 1, 768))
+ out["clip_img"] = comfy.conds.CONDRegular(clip_img)
+ out["sca"] = comfy.conds.CONDRegular(torch.zeros((1,)))
+ out["crp"] = comfy.conds.CONDRegular(torch.zeros((1,)))
+
+ cross_attn = kwargs.get("cross_attn", None)
+ if cross_attn is not None:
+ out['clip_text'] = comfy.conds.CONDCrossAttn(cross_attn)
+ return out
+
+
+class StableCascade_B(BaseModel):
+ def __init__(self, model_config, model_type=ModelType.STABLE_CASCADE, device=None):
+ super().__init__(model_config, model_type, device=device, unet_model=StageB)
+
+ def extra_conds(self, **kwargs):
+ out = {}
+ noise = kwargs.get("noise", None)
+
+ clip_text_pooled = kwargs["pooled_output"]
+ if clip_text_pooled is not None:
+ out['clip'] = comfy.conds.CONDRegular(clip_text_pooled)
+
+ #size of prior doesn't really matter if zeros because it gets resized but I still want it to get batched
+ prior = kwargs.get("stable_cascade_prior", torch.zeros((1, 16, (noise.shape[2] * 4) // 42, (noise.shape[3] * 4) // 42), dtype=noise.dtype, layout=noise.layout, device=noise.device))
+
+ out["effnet"] = comfy.conds.CONDRegular(prior.to(device=noise.device))
+ out["sca"] = comfy.conds.CONDRegular(torch.zeros((1,)))
+ return out
+
+
+class SD3(BaseModel):
+ def __init__(self, model_config, model_type=ModelType.FLOW, device=None):
+ super().__init__(model_config, model_type, device=device, unet_model=OpenAISignatureMMDITWrapper)
+
+ def encode_adm(self, **kwargs):
+ return kwargs["pooled_output"]
+
+ def extra_conds(self, **kwargs):
+ out = super().extra_conds(**kwargs)
+ cross_attn = kwargs.get("cross_attn", None)
+ if cross_attn is not None:
+ out['c_crossattn'] = comfy.conds.CONDRegular(cross_attn)
+ return out
+
+
+class AuraFlow(BaseModel):
+ def __init__(self, model_config, model_type=ModelType.FLOW, device=None):
+ super().__init__(model_config, model_type, device=device, unet_model=comfy.ldm.aura.mmdit.MMDiT)
+
+ def extra_conds(self, **kwargs):
+ out = super().extra_conds(**kwargs)
+ cross_attn = kwargs.get("cross_attn", None)
+ if cross_attn is not None:
+ out['c_crossattn'] = comfy.conds.CONDRegular(cross_attn)
+ return out
+
+
+class StableAudio1(BaseModel):
+ def __init__(self, model_config, seconds_start_embedder_weights, seconds_total_embedder_weights, model_type=ModelType.V_PREDICTION_CONTINUOUS, device=None):
+ super().__init__(model_config, model_type, device=device, unet_model=comfy.ldm.audio.dit.AudioDiffusionTransformer)
+ self.seconds_start_embedder = comfy.ldm.audio.embedders.NumberConditioner(768, min_val=0, max_val=512)
+ self.seconds_total_embedder = comfy.ldm.audio.embedders.NumberConditioner(768, min_val=0, max_val=512)
+ self.seconds_start_embedder.load_state_dict(seconds_start_embedder_weights)
+ self.seconds_total_embedder.load_state_dict(seconds_total_embedder_weights)
+
+ def extra_conds(self, **kwargs):
+ out = {}
+
+ noise = kwargs.get("noise", None)
+ device = kwargs["device"]
+
+ seconds_start = kwargs.get("seconds_start", 0)
+ seconds_total = kwargs.get("seconds_total", int(noise.shape[-1] / 21.53))
+
+ seconds_start_embed = self.seconds_start_embedder([seconds_start])[0].to(device)
+ seconds_total_embed = self.seconds_total_embedder([seconds_total])[0].to(device)
+
+ global_embed = torch.cat([seconds_start_embed, seconds_total_embed], dim=-1).reshape((1, -1))
+ out['global_embed'] = comfy.conds.CONDRegular(global_embed)
+
+ cross_attn = kwargs.get("cross_attn", None)
+ if cross_attn is not None:
+ cross_attn = torch.cat([cross_attn.to(device), seconds_start_embed.repeat((cross_attn.shape[0], 1, 1)), seconds_total_embed.repeat((cross_attn.shape[0], 1, 1))], dim=1)
+ out['c_crossattn'] = comfy.conds.CONDRegular(cross_attn)
+ return out
+
+ def state_dict_for_saving(self, unet_state_dict, clip_state_dict=None, vae_state_dict=None, clip_vision_state_dict=None):
+ sd = super().state_dict_for_saving(unet_state_dict, clip_state_dict=clip_state_dict, vae_state_dict=vae_state_dict, clip_vision_state_dict=clip_vision_state_dict)
+ d = {"conditioner.conditioners.seconds_start.": self.seconds_start_embedder.state_dict(), "conditioner.conditioners.seconds_total.": self.seconds_total_embedder.state_dict()}
+ for k in d:
+ s = d[k]
+ for l in s:
+ sd["{}{}".format(k, l)] = s[l]
+ return sd
+
+class StableAudio3(BaseModel):
+ def __init__(self, model_config, seconds_total_embedder_weights, padding_embedding=None, model_type=ModelType.FLOW, device=None):
+ super().__init__(model_config, model_type, device=device, unet_model=comfy.ldm.audio.dit.AudioDiffusionTransformer)
+ self.seconds_total_embedder = comfy.ldm.audio.embedders.NumberConditioner(768, min_val=0, max_val=384, fourier_features_type=model_config.unet_config["timestep_features_type"])
+ self.seconds_total_embedder.load_state_dict(seconds_total_embedder_weights)
+ if padding_embedding is not None:
+ self.padding_embedding = torch.nn.Parameter(padding_embedding, requires_grad=False)
+ else:
+ self.padding_embedding = None
+
+ def concat_cond(self, **kwargs):
+ noise = kwargs.get("noise", None)
+ image = kwargs.get("concat_latent_image", None)
+
+ if image is None:
+ shape_image = list(noise.shape)
+ image = torch.zeros(shape_image, dtype=noise.dtype, layout=noise.layout, device=noise.device)
+ else:
+ image = self.process_latent_in(image)
+ # TODO: scale if not match
+ image = utils.resize_to_batch_size(image, noise.shape[0])
+
+ mask = kwargs.get("concat_mask", kwargs.get("denoise_mask", None))
+ if mask is None:
+ mask = torch.zeros_like(noise)[:, :1]
+ else:
+ if mask.shape[1] != 1:
+ mask = torch.mean(mask, dim=1, keepdim=True)
+ mask = 1.0 - mask
+ # TODO: scale if not match
+ mask = utils.resize_to_batch_size(mask, noise.shape[0])
+
+ return torch.cat((mask, image), dim=1)
+
+ def extra_conds(self, **kwargs):
+ out = {}
+
+ concat_cond = self.concat_cond(**kwargs)
+ if concat_cond is not None:
+ out['local_add_cond'] = comfy.conds.CONDNoiseShape(concat_cond)
+
+ noise = kwargs.get("noise", None)
+ device = kwargs["device"]
+
+ seconds_total = kwargs.get("seconds_total", int(noise.shape[-1] / 10.7666))
+ seconds_total_embed = self.seconds_total_embedder([seconds_total])[0].to(device)
+
+ global_embed = seconds_total_embed.reshape((1, -1))
+ out['global_embed'] = comfy.conds.CONDRegular(global_embed)
+
+ cross_attn = kwargs.get("cross_attn", None)
+ if cross_attn is not None:
+ cross_attn = cross_attn.to(device)
+ if self.padding_embedding is not None:
+ pe = self.padding_embedding.to(device=device, dtype=cross_attn.dtype)
+ max_text_tokens = self.model_config.unet_config.get("max_text_tokens", 256)
+ n_text = cross_attn.shape[1]
+ if n_text < max_text_tokens:
+ pad = pe.view(1, 1, -1).expand(cross_attn.shape[0], max_text_tokens - n_text, -1)
+ cross_attn = torch.cat([cross_attn, pad], dim=1)
+ cross_attn = torch.cat([cross_attn, seconds_total_embed.repeat((cross_attn.shape[0], 1, 1))], dim=1)
+ out['c_crossattn'] = comfy.conds.CONDRegular(cross_attn)
+
+ return out
+
+ def state_dict_for_saving(self, unet_state_dict, clip_state_dict=None, vae_state_dict=None, clip_vision_state_dict=None):
+ sd = super().state_dict_for_saving(unet_state_dict, clip_state_dict=clip_state_dict, vae_state_dict=vae_state_dict, clip_vision_state_dict=clip_vision_state_dict)
+
+ d = {"conditioner.conditioners.seconds_total.": self.seconds_total_embedder.state_dict()}
+
+ for k in d:
+ s = d[k]
+ for l in s:
+ sd["{}{}".format(k, l)] = s[l]
+
+ if self.padding_embedding is not None:
+ sd["conditioner.conditioners.prompt.padding_embedding"] = self.padding_embedding.data
+ return sd
+
+
+class HunyuanDiT(BaseModel):
+ def __init__(self, model_config, model_type=ModelType.V_PREDICTION, device=None):
+ super().__init__(model_config, model_type, device=device, unet_model=comfy.ldm.hydit.models.HunYuanDiT)
+
+ def extra_conds(self, **kwargs):
+ out = super().extra_conds(**kwargs)
+ cross_attn = kwargs.get("cross_attn", None)
+ if cross_attn is not None:
+ out['c_crossattn'] = comfy.conds.CONDRegular(cross_attn)
+
+ attention_mask = kwargs.get("attention_mask", None)
+ if attention_mask is not None:
+ out['text_embedding_mask'] = comfy.conds.CONDRegular(attention_mask)
+
+ conditioning_mt5xl = kwargs.get("conditioning_mt5xl", None)
+ if conditioning_mt5xl is not None:
+ out['encoder_hidden_states_t5'] = comfy.conds.CONDRegular(conditioning_mt5xl)
+
+ attention_mask_mt5xl = kwargs.get("attention_mask_mt5xl", None)
+ if attention_mask_mt5xl is not None:
+ out['text_embedding_mask_t5'] = comfy.conds.CONDRegular(attention_mask_mt5xl)
+
+ width = kwargs.get("width", 768)
+ height = kwargs.get("height", 768)
+ target_width = kwargs.get("target_width", width)
+ target_height = kwargs.get("target_height", height)
+
+ out['image_meta_size'] = comfy.conds.CONDRegular(torch.FloatTensor([[height, width, target_height, target_width, 0, 0]]))
+ return out
+
+class SeedVR2(BaseModel):
+ def __init__(self, model_config, model_type=ModelType.FLOW, device=None):
+ super().__init__(model_config, model_type, device=device, unet_model=comfy.ldm.seedvr.model.NaDiT)
+
+ def extra_conds(self, **kwargs):
+ out = super().extra_conds(**kwargs)
+ condition = kwargs.get("condition", None)
+ if condition is not None:
+ out["condition"] = comfy.conds.CONDRegular(condition)
+ return out
+
+class PixArt(BaseModel):
+ def __init__(self, model_config, model_type=ModelType.EPS, device=None):
+ super().__init__(model_config, model_type, device=device, unet_model=comfy.ldm.pixart.pixartms.PixArtMS)
+
+ def extra_conds(self, **kwargs):
+ out = super().extra_conds(**kwargs)
+
+ cross_attn = kwargs.get("cross_attn", None)
+ if cross_attn is not None:
+ out['c_crossattn'] = comfy.conds.CONDRegular(cross_attn)
+
+ width = kwargs.get("width", None)
+ height = kwargs.get("height", None)
+ if width is not None and height is not None:
+ out["c_size"] = comfy.conds.CONDRegular(torch.FloatTensor([[height, width]]))
+ out["c_ar"] = comfy.conds.CONDRegular(torch.FloatTensor([[kwargs.get("aspect_ratio", height/width)]]))
+
+ return out
+
+class Flux(BaseModel):
+ def __init__(self, model_config, model_type=ModelType.FLUX, device=None, unet_model=comfy.ldm.flux.model.Flux):
+ super().__init__(model_config, model_type, device=device, unet_model=unet_model)
+ self.memory_usage_factor_conds = ("ref_latents",)
+
+ def concat_cond(self, **kwargs):
+ try:
+ #Handle Flux control loras dynamically changing the img_in weight.
+ num_channels = self.diffusion_model.img_in.weight.shape[1] // (self.diffusion_model.patch_size * self.diffusion_model.patch_size)
+ except:
+ #Some cases like tensorrt might not have the weights accessible
+ num_channels = self.model_config.unet_config["in_channels"]
+
+ out_channels = self.model_config.unet_config["out_channels"]
+
+ if num_channels <= out_channels:
+ return None
+
+ image = kwargs.get("concat_latent_image", None)
+ noise = kwargs.get("noise", None)
+ device = kwargs["device"]
+
+ if image is None:
+ image = torch.zeros_like(noise)
+
+ image = utils.common_upscale(image.to(device), noise.shape[-1], noise.shape[-2], "bilinear", "center")
+ image = utils.resize_to_batch_size(image, noise.shape[0])
+ image = self.process_latent_in(image)
+ if num_channels <= out_channels * 2:
+ return image
+
+ #inpaint model
+ mask = kwargs.get("concat_mask", kwargs.get("denoise_mask", None))
+ if mask is None:
+ mask = torch.ones_like(noise)[:, :1]
+
+ mask = torch.mean(mask, dim=1, keepdim=True)
+ mask = utils.common_upscale(mask.to(device), noise.shape[-1] * 8, noise.shape[-2] * 8, "bilinear", "center")
+ mask = mask.view(mask.shape[0], mask.shape[2] // 8, 8, mask.shape[3] // 8, 8).permute(0, 2, 4, 1, 3).reshape(mask.shape[0], -1, mask.shape[2] // 8, mask.shape[3] // 8)
+ mask = utils.resize_to_batch_size(mask, noise.shape[0])
+ return torch.cat((image, mask), dim=1)
+
+ def encode_adm(self, **kwargs):
+ return kwargs.get("pooled_output", None)
+
+ def extra_conds(self, **kwargs):
+ out = super().extra_conds(**kwargs)
+ cross_attn = kwargs.get("cross_attn", None)
+ if cross_attn is not None:
+ out['c_crossattn'] = comfy.conds.CONDRegular(cross_attn)
+ # upscale the attention mask, since now we
+ attention_mask = kwargs.get("attention_mask", None)
+ if attention_mask is not None:
+ shape = kwargs["noise"].shape
+ mask_ref_size = kwargs.get("attention_mask_img_shape", None)
+ if mask_ref_size is not None:
+ # the model will pad to the patch size, and then divide
+ # essentially dividing and rounding up
+ (h_tok, w_tok) = (math.ceil(shape[2] / self.diffusion_model.patch_size), math.ceil(shape[3] / self.diffusion_model.patch_size))
+ attention_mask = utils.upscale_dit_mask(attention_mask, mask_ref_size, (h_tok, w_tok))
+ out['attention_mask'] = comfy.conds.CONDRegular(attention_mask)
+
+ guidance = kwargs.get("guidance", 3.5)
+ if guidance is not None:
+ out['guidance'] = comfy.conds.CONDRegular(torch.FloatTensor([guidance]))
+
+ ref_latents = kwargs.get("reference_latents", None)
+ if ref_latents is not None:
+ latents = []
+ for lat in ref_latents:
+ latents.append(self.process_latent_in(lat))
+ out['ref_latents'] = comfy.conds.CONDList(latents)
+
+ ref_latents_method = kwargs.get("reference_latents_method", None)
+ if ref_latents_method is not None:
+ out['ref_latents_method'] = comfy.conds.CONDConstant(ref_latents_method)
+ return out
+
+ def extra_conds_shapes(self, **kwargs):
+ out = {}
+ ref_latents = kwargs.get("reference_latents", None)
+ if ref_latents is not None:
+ out['ref_latents'] = list([1, 16, sum(map(lambda a: math.prod(a.size()[2:]), ref_latents))])
+ return out
+
+class LongCatImage(Flux):
+ def _apply_model(self, x, t, c_concat=None, c_crossattn=None, control=None, transformer_options={}, **kwargs):
+ transformer_options = transformer_options.copy()
+ rope_opts = transformer_options.get("rope_options", {})
+ rope_opts = dict(rope_opts)
+ pe_len = float(c_crossattn.shape[1]) if c_crossattn is not None else 512.0
+ rope_opts.setdefault("shift_t", 1.0)
+ rope_opts.setdefault("shift_y", pe_len)
+ rope_opts.setdefault("shift_x", pe_len)
+ transformer_options["rope_options"] = rope_opts
+ return super()._apply_model(x, t, c_concat, c_crossattn, control, transformer_options, **kwargs)
+
+ def encode_adm(self, **kwargs):
+ return None
+
+ def extra_conds(self, **kwargs):
+ out = super().extra_conds(**kwargs)
+ out.pop('guidance', None)
+ return out
+
+class Flux2(Flux):
+ def extra_conds(self, **kwargs):
+ out = super().extra_conds(**kwargs)
+ cross_attn = kwargs.get("cross_attn", None)
+ if cross_attn is not None:
+ target_text_len = 512
+ if cross_attn.shape[1] < target_text_len:
+ cross_attn = torch.nn.functional.pad(cross_attn, (0, 0, target_text_len - cross_attn.shape[1], 0))
+ out['c_crossattn'] = comfy.conds.CONDRegular(cross_attn)
+ return out
+
+
+class Lens(BaseModel):
+ def __init__(self, model_config, model_type=ModelType.FLUX, device=None):
+ super().__init__(
+ model_config, model_type, device=device,
+ unet_model=comfy.ldm.lens.model.LensTransformer2DModel,
+ )
+
+ def encode_adm(self, **kwargs):
+ return None # Lens has no pooled/ADM conditioning.
+
+ def extra_conds(self, **kwargs):
+ out = super().extra_conds(**kwargs)
+ cross_attn = kwargs.get("cross_attn", None)
+ if cross_attn is not None:
+ out['c_crossattn'] = comfy.conds.CONDRegular(cross_attn)
+ attention_mask = kwargs.get("attention_mask", None)
+ if attention_mask is not None:
+ out['attention_mask'] = comfy.conds.CONDRegular(attention_mask)
+ return out
+
+class GenmoMochi(BaseModel):
+ def __init__(self, model_config, model_type=ModelType.FLOW, device=None):
+ super().__init__(model_config, model_type, device=device, unet_model=comfy.ldm.genmo.joint_model.asymm_models_joint.AsymmDiTJoint)
+
+ def extra_conds(self, **kwargs):
+ out = super().extra_conds(**kwargs)
+ attention_mask = kwargs.get("attention_mask", None)
+ if attention_mask is not None:
+ out['attention_mask'] = comfy.conds.CONDRegular(attention_mask)
+ out['num_tokens'] = comfy.conds.CONDConstant(max(1, torch.sum(attention_mask).item()))
+ cross_attn = kwargs.get("cross_attn", None)
+ if cross_attn is not None:
+ out['c_crossattn'] = comfy.conds.CONDRegular(cross_attn)
+ return out
+
+class LTXV(BaseModel):
+ def __init__(self, model_config, model_type=ModelType.FLUX, device=None):
+ super().__init__(model_config, model_type, device=device, unet_model=comfy.ldm.lightricks.model.LTXVModel)
+
+ def extra_conds(self, **kwargs):
+ out = super().extra_conds(**kwargs)
+ attention_mask = kwargs.get("attention_mask", None)
+ if attention_mask is not None:
+ out['attention_mask'] = comfy.conds.CONDRegular(attention_mask)
+ cross_attn = kwargs.get("cross_attn", None)
+ if cross_attn is not None:
+ out['c_crossattn'] = comfy.conds.CONDRegular(cross_attn)
+
+ out['frame_rate'] = comfy.conds.CONDConstant(kwargs.get("frame_rate", 25))
+
+ denoise_mask = kwargs.get("concat_mask", kwargs.get("denoise_mask", None))
+ if denoise_mask is not None:
+ out["denoise_mask"] = comfy.conds.CONDRegular(denoise_mask)
+
+ keyframe_idxs = kwargs.get("keyframe_idxs", None)
+ if keyframe_idxs is not None:
+ out['keyframe_idxs'] = comfy.conds.CONDRegular(keyframe_idxs)
+
+ guide_attention_entries = kwargs.get("guide_attention_entries", None)
+ if guide_attention_entries is not None:
+ out['guide_attention_entries'] = comfy.conds.CONDConstant(guide_attention_entries)
+
+ return out
+
+ def process_timestep(self, timestep, x, denoise_mask=None, **kwargs):
+ if denoise_mask is None:
+ return timestep
+ return self.diffusion_model.patchifier.patchify(((denoise_mask) * timestep.view([timestep.shape[0]] + [1] * (denoise_mask.ndim - 1)))[:, :1])[0]
+
+ def scale_latent_inpaint(self, sigma, noise, latent_image, **kwargs):
+ return latent_image
+
+class LTXAV(BaseModel):
+ def __init__(self, model_config, model_type=ModelType.FLUX, device=None):
+ super().__init__(model_config, model_type, device=device, unet_model=comfy.ldm.lightricks.av_model.LTXAVModel) #TODO
+
+ def extra_conds(self, **kwargs):
+ out = super().extra_conds(**kwargs)
+ attention_mask = kwargs.get("attention_mask", None)
+ device = kwargs["device"]
+
+ if attention_mask is not None:
+ out['attention_mask'] = comfy.conds.CONDRegular(attention_mask)
+ cross_attn = kwargs.get("cross_attn", None)
+ if cross_attn is not None:
+ if hasattr(self.diffusion_model, "preprocess_text_embeds"):
+ cross_attn = self.diffusion_model.preprocess_text_embeds(cross_attn.to(device=device, dtype=self.get_dtype_inference()), unprocessed=kwargs.get("unprocessed_ltxav_embeds", False))
+ out['c_crossattn'] = comfy.conds.CONDRegular(cross_attn)
+
+ out['frame_rate'] = comfy.conds.CONDConstant(kwargs.get("frame_rate", 25))
+
+ denoise_mask = kwargs.get("concat_mask", kwargs.get("denoise_mask", None))
+
+ audio_denoise_mask = None
+ if denoise_mask is not None and "latent_shapes" in kwargs:
+ denoise_mask = utils.unpack_latents(denoise_mask, kwargs["latent_shapes"])
+ if len(denoise_mask) > 1:
+ audio_denoise_mask = denoise_mask[1]
+ denoise_mask = denoise_mask[0]
+
+ if denoise_mask is not None:
+ out["denoise_mask"] = comfy.conds.CONDRegular(denoise_mask)
+
+ if audio_denoise_mask is not None:
+ out["audio_denoise_mask"] = comfy.conds.CONDRegular(audio_denoise_mask)
+
+ keyframe_idxs = kwargs.get("keyframe_idxs", None)
+ if keyframe_idxs is not None:
+ out['keyframe_idxs'] = comfy.conds.CONDRegular(keyframe_idxs)
+
+ latent_shapes = kwargs.get("latent_shapes", None)
+ if latent_shapes is not None:
+ out['latent_shapes'] = comfy.conds.CONDConstant(latent_shapes)
+
+ guide_attention_entries = kwargs.get("guide_attention_entries", None)
+ if guide_attention_entries is not None:
+ out['guide_attention_entries'] = comfy.conds.CONDConstant(guide_attention_entries)
+
+ ref_audio = kwargs.get("ref_audio", None)
+ if ref_audio is not None:
+ out['ref_audio'] = comfy.conds.CONDConstant(ref_audio)
+
+ return out
+
+ def process_timestep(self, timestep, x, denoise_mask=None, audio_denoise_mask=None, **kwargs):
+ v_timestep = timestep
+ a_timestep = timestep
+
+ if denoise_mask is not None:
+ v_timestep = self.diffusion_model.patchifier.patchify(((denoise_mask) * timestep.view([timestep.shape[0]] + [1] * (denoise_mask.ndim - 1)))[:, :1])[0]
+ if audio_denoise_mask is not None:
+ a_timestep = self.diffusion_model.a_patchifier.patchify(((audio_denoise_mask) * timestep.view([timestep.shape[0]] + [1] * (audio_denoise_mask.ndim - 1)))[:, :1, :, :1])[0]
+
+ return v_timestep, a_timestep
+
+ def scale_latent_inpaint(self, sigma, noise, latent_image, **kwargs):
+ return latent_image
+
+ def map_context_window_to_modalities(self, primary_indices, latent_shapes, dim):
+ result = [primary_indices]
+ if len(latent_shapes) < 2:
+ return result
+
+ video_total = latent_shapes[0][dim]
+
+ for i in range(1, len(latent_shapes)):
+ mod_total = latent_shapes[i][dim]
+ # Map each primary index to its proportional range of modality indices and
+ # concatenate in order. Preserves wrapped/strided geometry so the modality
+ # attends to the same temporal regions as the primary window.
+ mod_indices = []
+ seen = set()
+ for v_idx in primary_indices:
+ a_start = min(int(round(v_idx * mod_total / video_total)), mod_total - 1)
+ a_end = min(int(round((v_idx + 1) * mod_total / video_total)), mod_total)
+ if a_end <= a_start:
+ a_end = a_start + 1
+ for a in range(a_start, a_end):
+ if a not in seen:
+ seen.add(a)
+ mod_indices.append(a)
+ result.append(mod_indices)
+
+ return result
+
+ @staticmethod
+ def _get_guide_entries(conds):
+ for cond_list in conds:
+ if cond_list is None:
+ continue
+ for cond_dict in cond_list:
+ model_conds = cond_dict.get('model_conds', {})
+ entries = model_conds.get('guide_attention_entries')
+ if entries is not None and hasattr(entries, 'cond') and entries.cond:
+ return entries.cond
+ return None
+
+ def resize_cond_for_context_window(self, cond_key, cond_value, window, x_in, device, retain_index_list=[]):
+ # Audio denoise mask — slice using audio modality window
+ if cond_key == "audio_denoise_mask" and hasattr(window, 'modality_windows') and window.modality_windows:
+ audio_window = window.modality_windows.get(1)
+ if audio_window is not None and hasattr(cond_value, "cond") and isinstance(cond_value.cond, torch.Tensor):
+ sliced = audio_window.get_tensor(cond_value.cond, device, dim=2)
+ return cond_value._copy_with(sliced)
+
+ # Video denoise mask — split into video + guide portions, slice each
+ if cond_key == "denoise_mask" and hasattr(cond_value, "cond") and isinstance(cond_value.cond, torch.Tensor):
+ cond_tensor = cond_value.cond
+ guide_count = cond_tensor.size(window.dim) - x_in.size(window.dim)
+ if guide_count > 0:
+ T_video = x_in.size(window.dim)
+ video_mask = cond_tensor.narrow(window.dim, 0, T_video)
+ guide_mask = cond_tensor.narrow(window.dim, T_video, guide_count)
+ sliced_video = window.get_tensor(video_mask, device, retain_index_list=retain_index_list)
+ suffix_indices = window.guide_frames_indices
+ if suffix_indices:
+ idx = tuple([slice(None)] * window.dim + [suffix_indices])
+ sliced_guide = guide_mask[idx].to(device)
+ return cond_value._copy_with(torch.cat([sliced_video, sliced_guide], dim=window.dim))
+ else:
+ return cond_value._copy_with(sliced_video)
+
+ # Keyframe indices — regenerate pixel coords for window, select guide positions
+ if cond_key == "keyframe_idxs":
+ kf_local_pos = window.guide_kf_local_positions
+ if not kf_local_pos:
+ return cond_value._copy_with(cond_value.cond[:, :, :0, :]) # empty
+ H, W = x_in.shape[3], x_in.shape[4]
+ window_len = len(window.index_list)
+ # account for causal_window_fix anchor in coord space size
+ anchor_idx = getattr(window, 'causal_anchor_index', None)
+ if anchor_idx is not None and anchor_idx >= 0:
+ window_len += 1
+ patchifier = self.diffusion_model.patchifier
+ latent_coords = patchifier.get_latent_coords(window_len, H, W, 1, cond_value.cond.device)
+ scale_factors = self.diffusion_model.vae_scale_factors
+ pixel_coords = comfy.ldm.lightricks.symmetric_patchifier.latent_to_pixel_coords(
+ latent_coords,
+ scale_factors,
+ causal_fix=self.diffusion_model.causal_temporal_positioning)
+ tokens = []
+ for pos in kf_local_pos:
+ tokens.extend(range(pos * H * W, (pos + 1) * H * W))
+ pixel_coords = pixel_coords[:, :, tokens, :]
+
+ # Adjust spatial end positions for dilated (downscaled) guides.
+ # Each guide entry may have a different downscale factor; expand the
+ # per-entry factor to cover all tokens belonging to that entry.
+ downscale_factors = window.guide_downscale_factors
+ overlap_info = window.guide_overlap_info
+ if downscale_factors:
+ per_token_factor = []
+ for (entry_idx, overlap_count), dsf in zip(overlap_info, downscale_factors):
+ per_token_factor.extend([dsf] * (overlap_count * H * W))
+ factor_tensor = torch.tensor(per_token_factor, device=pixel_coords.device, dtype=pixel_coords.dtype)
+ spatial_end_offset = (factor_tensor.unsqueeze(0).unsqueeze(0).unsqueeze(-1) - 1) * torch.tensor(
+ scale_factors[1:], device=pixel_coords.device, dtype=pixel_coords.dtype,
+ ).view(1, -1, 1, 1)
+ pixel_coords[:, 1:, :, 1:] += spatial_end_offset
+
+ B = cond_value.cond.shape[0]
+ if B > 1:
+ pixel_coords = pixel_coords.expand(B, -1, -1, -1)
+ return cond_value._copy_with(pixel_coords)
+
+ # Guide attention entries — adjust per-guide counts based on window overlap
+ if cond_key == "guide_attention_entries":
+ overlap_info = window.guide_overlap_info
+ H, W = x_in.shape[3], x_in.shape[4]
+ new_entries = []
+ for entry_idx, overlap_count in overlap_info:
+ e = cond_value.cond[entry_idx]
+ new_entries.append({**e,
+ "pre_filter_count": overlap_count * H * W,
+ "latent_shape": [overlap_count, H, W]})
+ return cond_value._copy_with(new_entries)
+
+ return None
+
+class HunyuanVideo(BaseModel):
+ def __init__(self, model_config, model_type=ModelType.FLOW, device=None):
+ super().__init__(model_config, model_type, device=device, unet_model=comfy.ldm.hunyuan_video.model.HunyuanVideo)
+
+ def encode_adm(self, **kwargs):
+ return kwargs["pooled_output"]
+
+ def extra_conds(self, **kwargs):
+ out = super().extra_conds(**kwargs)
+ attention_mask = kwargs.get("attention_mask", None)
+ if attention_mask is not None:
+ out['attention_mask'] = comfy.conds.CONDRegular(attention_mask)
+ cross_attn = kwargs.get("cross_attn", None)
+ if cross_attn is not None:
+ out['c_crossattn'] = comfy.conds.CONDRegular(cross_attn)
+
+ guidance = kwargs.get("guidance", 6.0)
+ if guidance is not None:
+ out['guidance'] = comfy.conds.CONDRegular(torch.FloatTensor([guidance]))
+
+ guiding_frame_index = kwargs.get("guiding_frame_index", None)
+ if guiding_frame_index is not None:
+ out['guiding_frame_index'] = comfy.conds.CONDRegular(torch.FloatTensor([guiding_frame_index]))
+
+ ref_latent = kwargs.get("ref_latent", None)
+ if ref_latent is not None:
+ out['ref_latent'] = comfy.conds.CONDRegular(self.process_latent_in(ref_latent))
+
+ return out
+
+ def scale_latent_inpaint(self, latent_image, **kwargs):
+ return latent_image
+
+class HunyuanVideoI2V(HunyuanVideo):
+ def __init__(self, model_config, model_type=ModelType.FLOW, device=None):
+ super().__init__(model_config, model_type, device=device)
+ self.concat_keys = ("concat_image", "mask_inverted")
+
+ def scale_latent_inpaint(self, latent_image, **kwargs):
+ return super().scale_latent_inpaint(latent_image=latent_image, **kwargs)
+
+class HunyuanVideoSkyreelsI2V(HunyuanVideo):
+ def __init__(self, model_config, model_type=ModelType.FLOW, device=None):
+ super().__init__(model_config, model_type, device=device)
+ self.concat_keys = ("concat_image",)
+
+ def scale_latent_inpaint(self, latent_image, **kwargs):
+ return super().scale_latent_inpaint(latent_image=latent_image, **kwargs)
+
+class CosmosVideo(BaseModel):
+ def __init__(self, model_config, model_type=ModelType.EDM, image_to_video=False, device=None):
+ super().__init__(model_config, model_type, device=device, unet_model=comfy.ldm.cosmos.model.GeneralDIT)
+ self.image_to_video = image_to_video
+ if self.image_to_video:
+ self.concat_keys = ("mask_inverted",)
+
+ def extra_conds(self, **kwargs):
+ out = super().extra_conds(**kwargs)
+ attention_mask = kwargs.get("attention_mask", None)
+ if attention_mask is not None:
+ out['attention_mask'] = comfy.conds.CONDRegular(attention_mask)
+ cross_attn = kwargs.get("cross_attn", None)
+ if cross_attn is not None:
+ out['c_crossattn'] = comfy.conds.CONDRegular(cross_attn)
+
+ out['fps'] = comfy.conds.CONDConstant(kwargs.get("frame_rate", None))
+ return out
+
+ def scale_latent_inpaint(self, sigma, noise, latent_image, **kwargs):
+ sigma = sigma.reshape([sigma.shape[0]] + [1] * (len(noise.shape) - 1))
+ sigma_noise_augmentation = 0 #TODO
+ if sigma_noise_augmentation != 0:
+ latent_image = latent_image + noise
+ latent_image = self.model_sampling.calculate_input(torch.tensor([sigma_noise_augmentation], device=latent_image.device, dtype=latent_image.dtype), latent_image)
+ return latent_image * ((sigma ** 2 + self.model_sampling.sigma_data ** 2) ** 0.5)
+
+class CosmosPredict2(BaseModel):
+ def __init__(self, model_config, model_type=ModelType.FLOW_COSMOS, image_to_video=False, device=None):
+ super().__init__(model_config, model_type, device=device, unet_model=comfy.ldm.cosmos.predict2.MiniTrainDIT)
+ self.image_to_video = image_to_video
+ if self.image_to_video:
+ self.concat_keys = ("mask_inverted",)
+
+ def extra_conds(self, **kwargs):
+ out = super().extra_conds(**kwargs)
+ cross_attn = kwargs.get("cross_attn", None)
+ if cross_attn is not None:
+ out['c_crossattn'] = comfy.conds.CONDRegular(cross_attn)
+
+ denoise_mask = kwargs.get("concat_mask", kwargs.get("denoise_mask", None))
+ if denoise_mask is not None:
+ out["denoise_mask"] = comfy.conds.CONDRegular(denoise_mask)
+
+ out['fps'] = comfy.conds.CONDConstant(kwargs.get("frame_rate", None))
+ return out
+
+ def process_timestep(self, timestep, x, denoise_mask=None, **kwargs):
+ if denoise_mask is None:
+ return timestep
+ if denoise_mask.ndim <= 4:
+ return timestep
+ condition_video_mask_B_1_T_1_1 = denoise_mask.mean(dim=[1, 3, 4], keepdim=True)
+ c_noise_B_1_T_1_1 = 0.0 * (1.0 - condition_video_mask_B_1_T_1_1) + timestep.reshape(timestep.shape[0], 1, 1, 1, 1) * condition_video_mask_B_1_T_1_1
+ out = c_noise_B_1_T_1_1.squeeze(dim=[1, 3, 4])
+ return out
+
+ def scale_latent_inpaint(self, sigma, noise, latent_image, **kwargs):
+ sigma = sigma.reshape([sigma.shape[0]] + [1] * (len(noise.shape) - 1))
+ sigma_noise_augmentation = 0 #TODO
+ if sigma_noise_augmentation != 0:
+ latent_image = latent_image + noise
+ latent_image = self.model_sampling.calculate_input(torch.tensor([sigma_noise_augmentation], device=latent_image.device, dtype=latent_image.dtype), latent_image)
+ sigma = (sigma / (sigma + 1))
+ return latent_image / (1.0 - sigma)
+
+class Anima(BaseModel):
+ def __init__(self, model_config, model_type=ModelType.FLOW, device=None):
+ super().__init__(model_config, model_type, device=device, unet_model=comfy.ldm.anima.model.Anima)
+
+ def extra_conds(self, **kwargs):
+ out = super().extra_conds(**kwargs)
+ cross_attn = kwargs.get("cross_attn", None)
+ t5xxl_ids = kwargs.get("t5xxl_ids", None)
+ t5xxl_weights = kwargs.get("t5xxl_weights", None)
+ device = kwargs["device"]
+ if cross_attn is not None:
+ if t5xxl_ids is not None:
+ if t5xxl_weights is not None:
+ t5xxl_weights = t5xxl_weights.unsqueeze(0).unsqueeze(-1).to(cross_attn)
+ t5xxl_ids = t5xxl_ids.unsqueeze(0)
+
+ if torch.is_inference_mode_enabled(): # if not we are training
+ cross_attn = self.diffusion_model.preprocess_text_embeds(cross_attn.to(device=device, dtype=self.get_dtype_inference()), t5xxl_ids.to(device=device), t5xxl_weights=t5xxl_weights.to(device=device, dtype=self.get_dtype_inference()))
+ else:
+ out['t5xxl_ids'] = comfy.conds.CONDRegular(t5xxl_ids)
+ out['t5xxl_weights'] = comfy.conds.CONDRegular(t5xxl_weights)
+
+ out['c_crossattn'] = comfy.conds.CONDRegular(cross_attn)
+ return out
+
+class Lumina2(BaseModel):
+ def __init__(self, model_config, model_type=ModelType.FLOW, device=None):
+ super().__init__(model_config, model_type, device=device, unet_model=comfy.ldm.lumina.model.NextDiT)
+ self.memory_usage_factor_conds = ("ref_latents",)
+
+ def extra_conds(self, **kwargs):
+ out = super().extra_conds(**kwargs)
+ attention_mask = kwargs.get("attention_mask", None)
+ if attention_mask is not None:
+ if torch.numel(attention_mask) != attention_mask.sum():
+ out['attention_mask'] = comfy.conds.CONDRegular(attention_mask)
+ out['num_tokens'] = comfy.conds.CONDConstant(max(1, torch.sum(attention_mask).item()))
+
+ cross_attn = kwargs.get("cross_attn", None)
+ if cross_attn is not None:
+ out['c_crossattn'] = comfy.conds.CONDRegular(cross_attn)
+ if 'num_tokens' not in out:
+ out['num_tokens'] = comfy.conds.CONDConstant(cross_attn.shape[1])
+
+ clip_text_pooled = kwargs.get("pooled_output", None) # NewBie
+ if clip_text_pooled is not None:
+ out['clip_text_pooled'] = comfy.conds.CONDRegular(clip_text_pooled)
+
+ clip_vision_outputs = kwargs.get("clip_vision_outputs", list(map(lambda a: a.get("clip_vision_output"), kwargs.get("unclip_conditioning", [{}])))) # Z Image omni
+ if clip_vision_outputs is not None and len(clip_vision_outputs) > 0:
+ sigfeats = []
+ for clip_vision_output in clip_vision_outputs:
+ if clip_vision_output is not None:
+ image_size = clip_vision_output.image_sizes[0]
+ shape = clip_vision_output.last_hidden_state.shape
+ sigfeats.append(clip_vision_output.last_hidden_state.reshape(shape[0], image_size[1] // 16, image_size[2] // 16, shape[-1]))
+ if len(sigfeats) > 0:
+ out['siglip_feats'] = comfy.conds.CONDList(sigfeats)
+
+ ref_latents = kwargs.get("reference_latents", None)
+ if ref_latents is not None:
+ latents = []
+ for lat in ref_latents:
+ latents.append(self.process_latent_in(lat))
+ out['ref_latents'] = comfy.conds.CONDList(latents)
+
+ ref_contexts = kwargs.get("reference_latents_text_embeds", None)
+ if ref_contexts is not None:
+ out['ref_contexts'] = comfy.conds.CONDList(ref_contexts)
+
+ return out
+
+ def extra_conds_shapes(self, **kwargs):
+ out = {}
+ ref_latents = kwargs.get("reference_latents", None)
+ if ref_latents is not None:
+ out['ref_latents'] = list([1, 16, sum(map(lambda a: math.prod(a.size()[2:]), ref_latents))])
+ return out
+
+class ZImagePixelSpace(Lumina2):
+ def __init__(self, model_config, model_type=ModelType.FLOW, device=None):
+ BaseModel.__init__(self, model_config, model_type, device=device, unet_model=comfy.ldm.lumina.model.NextDiTPixelSpace)
+ self.memory_usage_factor_conds = ("ref_latents",)
+
+
+class PixelDiTT2I(BaseModel):
+ def __init__(self, model_config, model_type=ModelType.FLOW, device=None):
+ super().__init__(model_config, model_type, device=device,
+ unet_model=comfy.ldm.pixeldit.model.PixDiT_T2I)
+
+ def extra_conds(self, **kwargs):
+ out = super().extra_conds(**kwargs)
+ attention_mask = kwargs.get("attention_mask", None)
+ if attention_mask is not None:
+ out["attention_mask"] = comfy.conds.CONDRegular(attention_mask)
+ return out
+
+
+class PiD(PixelDiTT2I):
+ def __init__(self, model_config, model_type=ModelType.FLOW, device=None):
+ BaseModel.__init__(self, model_config, model_type, device=device,
+ unet_model=comfy.ldm.pixeldit.pid.PidNet)
+
+ def extra_conds(self, **kwargs):
+ out = super().extra_conds(**kwargs)
+ lq_latent = kwargs.get("lq_latent", None)
+ if lq_latent is not None:
+ out["lq_latent"] = comfy.conds.CONDRegular(lq_latent)
+ degrade_sigma = kwargs.get("degrade_sigma", None)
+ if degrade_sigma is not None:
+ out["degrade_sigma"] = comfy.conds.CONDRegular(degrade_sigma)
+ return out
+
+ def resize_cond_for_context_window(self, cond_key, cond_value, window, x_in, device, retain_index_list=[]):
+ if cond_key == "lq_latent" and hasattr(cond_value, "cond") and isinstance(cond_value.cond, torch.Tensor):
+ lq = cond_value.cond
+ dim = window.dim
+ if dim >= lq.ndim:
+ return None
+ lq_proj = self.diffusion_model.lq_proj
+ ratio = lq_proj.sr_scale * lq_proj.latent_spatial_down_factor
+ # Map x window indices -> lq indices (deduplicated, sorted, in-bounds).
+ lq_size = lq.size(dim)
+ lq_indices = sorted({i // ratio for i in window.index_list if 0 <= i // ratio < lq_size})
+ if not lq_indices:
+ return None
+ idx = tuple([slice(None)] * dim + [lq_indices])
+ return cond_value._copy_with(lq[idx].to(device))
+ return super().resize_cond_for_context_window(cond_key, cond_value, window, x_in, device, retain_index_list=retain_index_list)
+
+
+class WAN21(BaseModel):
+ def __init__(self, model_config, model_type=ModelType.FLOW, image_to_video=False, device=None):
+ super().__init__(model_config, model_type, device=device, unet_model=comfy.ldm.wan.model.WanModel)
+ self.image_to_video = image_to_video
+
+ def concat_cond(self, **kwargs):
+ noise = kwargs.get("noise", None)
+ extra_channels = self.diffusion_model.patch_embedding.weight.shape[1] - noise.shape[1]
+ if extra_channels == 0:
+ return None
+
+ image = kwargs.get("concat_latent_image", None)
+ device = kwargs["device"]
+
+ if image is None:
+ shape_image = list(noise.shape)
+ shape_image[1] = extra_channels
+ image = torch.zeros(shape_image, dtype=noise.dtype, layout=noise.layout, device=noise.device)
+ else:
+ latent_dim = self.latent_format.latent_channels
+ image = utils.common_upscale(image.to(device), noise.shape[-1], noise.shape[-2], "bilinear", "center")
+ for i in range(0, image.shape[1], latent_dim):
+ image[:, i: i + latent_dim] = self.process_latent_in(image[:, i: i + latent_dim])
+ image = utils.resize_to_batch_size(image, noise.shape[0])
+
+ if extra_channels != image.shape[1] + 4:
+ if not self.image_to_video or extra_channels == image.shape[1]:
+ return image
+
+ if image.shape[1] > (extra_channels - 4):
+ image = image[:, :(extra_channels - 4)]
+
+ mask = kwargs.get("concat_mask", kwargs.get("denoise_mask", None))
+ if mask is None:
+ mask = torch.zeros_like(noise)[:, :4]
+ else:
+ if mask.shape[1] != 4:
+ mask = torch.mean(mask, dim=1, keepdim=True)
+ mask = 1.0 - mask
+ mask = utils.common_upscale(mask.to(device), noise.shape[-1], noise.shape[-2], "bilinear", "center")
+ if mask.shape[-3] < noise.shape[-3]:
+ mask = torch.nn.functional.pad(mask, (0, 0, 0, 0, 0, noise.shape[-3] - mask.shape[-3]), mode='constant', value=0)
+ if mask.shape[1] == 1:
+ mask = mask.repeat(1, 4, 1, 1, 1)
+ mask = utils.resize_to_batch_size(mask, noise.shape[0])
+
+ concat_mask_index = kwargs.get("concat_mask_index", 0)
+ if concat_mask_index != 0:
+ return torch.cat((image[:, :concat_mask_index], mask, image[:, concat_mask_index:]), dim=1)
+ else:
+ return torch.cat((mask, image), dim=1)
+
+ def extra_conds(self, **kwargs):
+ out = super().extra_conds(**kwargs)
+ cross_attn = kwargs.get("cross_attn", None)
+ if cross_attn is not None:
+ out['c_crossattn'] = comfy.conds.CONDRegular(cross_attn)
+
+ clip_vision_output = kwargs.get("clip_vision_output", None)
+ if clip_vision_output is not None:
+ out['clip_fea'] = comfy.conds.CONDRegular(clip_vision_output.penultimate_hidden_states)
+
+ time_dim_concat = kwargs.get("time_dim_concat", None)
+ if time_dim_concat is not None:
+ out['time_dim_concat'] = comfy.conds.CONDRegular(self.process_latent_in(time_dim_concat))
+
+ reference_latents = kwargs.get("reference_latents", None)
+ if reference_latents is not None:
+ out['reference_latent'] = comfy.conds.CONDRegular(self.process_latent_in(reference_latents[-1])[:, :, 0])
+
+ # In-context reference conditioning (Bernini)
+ context_latents = kwargs.get("context_latents", None)
+ if context_latents is not None:
+ out['context_latents'] = comfy.conds.CONDList([self.process_latent_in(l) for l in context_latents])
+
+ return out
+
+ def resize_cond_for_context_window(self, cond_key, cond_value, window, x_in, device, retain_index_list=[]):
+ # In-context cond slicing (Bernini)
+ if cond_key == "context_latents" and isinstance(getattr(cond_value, "cond", None), list):
+ dim = window.dim
+ out = []
+ for lat in cond_value.cond:
+ if lat.ndim > dim and lat.shape[dim] > 1 and lat.shape[dim] == x_in.shape[dim]:
+ out.append(window.get_tensor(lat, device, dim=dim, retain_index_list=retain_index_list))
+ else:
+ out.append(lat.to(device))
+ return cond_value._copy_with(out)
+ return super().resize_cond_for_context_window(cond_key, cond_value, window, x_in, device, retain_index_list=retain_index_list)
+
+
+class WAN21_CausalAR(WAN21):
+ def __init__(self, model_config, model_type=ModelType.FLOW, device=None):
+ super(WAN21, self).__init__(model_config, model_type, device=device,
+ unet_model=comfy.ldm.wan.ar_model.CausalWanModel)
+ self.image_to_video = False
+
+
+class WAN21_Vace(WAN21):
+ def __init__(self, model_config, model_type=ModelType.FLOW, image_to_video=False, device=None):
+ super(WAN21, self).__init__(model_config, model_type, device=device, unet_model=comfy.ldm.wan.model.VaceWanModel)
+ self.image_to_video = image_to_video
+
+ def extra_conds(self, **kwargs):
+ out = super().extra_conds(**kwargs)
+ noise = kwargs.get("noise", None)
+ noise_shape = list(noise.shape)
+ vace_frames = kwargs.get("vace_frames", None)
+ if vace_frames is None:
+ noise_shape[1] = 32
+ vace_frames = [torch.zeros(noise_shape, device=noise.device, dtype=noise.dtype)]
+
+ mask = kwargs.get("vace_mask", None)
+ if mask is None:
+ noise_shape[1] = 64
+ mask = [torch.ones(noise_shape, device=noise.device, dtype=noise.dtype)] * len(vace_frames)
+
+ vace_frames_out = []
+ for j in range(len(vace_frames)):
+ vf = vace_frames[j].to(device=noise.device, dtype=noise.dtype, copy=True)
+ for i in range(0, vf.shape[1], 16):
+ vf[:, i:i + 16] = self.process_latent_in(vf[:, i:i + 16])
+ vf = torch.cat([vf, mask[j].to(device=noise.device, dtype=noise.dtype)], dim=1)
+ vace_frames_out.append(vf)
+
+ vace_frames = torch.stack(vace_frames_out, dim=1)
+ out['vace_context'] = comfy.conds.CONDRegular(vace_frames)
+
+ vace_strength = kwargs.get("vace_strength", [1.0] * len(vace_frames_out))
+ out['vace_strength'] = comfy.conds.CONDConstant(vace_strength)
+ return out
+
+ def resize_cond_for_context_window(self, cond_key, cond_value, window, x_in, device, retain_index_list=[]):
+ if cond_key == "vace_context":
+ return comfy.context_windows.slice_cond(cond_value, window, x_in, device, temporal_dim=3, retain_index_list=retain_index_list)
+ return super().resize_cond_for_context_window(cond_key, cond_value, window, x_in, device, retain_index_list=retain_index_list)
+
+class WAN21_Camera(WAN21):
+ def __init__(self, model_config, model_type=ModelType.FLOW, image_to_video=False, device=None):
+ super(WAN21, self).__init__(model_config, model_type, device=device, unet_model=comfy.ldm.wan.model.CameraWanModel)
+ self.image_to_video = image_to_video
+
+ def extra_conds(self, **kwargs):
+ out = super().extra_conds(**kwargs)
+ camera_conditions = kwargs.get("camera_conditions", None)
+ if camera_conditions is not None:
+ out['camera_conditions'] = comfy.conds.CONDRegular(camera_conditions)
+ return out
+
+class WAN21_HuMo(WAN21):
+ def __init__(self, model_config, model_type=ModelType.FLOW, image_to_video=False, device=None):
+ super(WAN21, self).__init__(model_config, model_type, device=device, unet_model=comfy.ldm.wan.model.HumoWanModel)
+ self.image_to_video = image_to_video
+
+ def extra_conds(self, **kwargs):
+ out = super().extra_conds(**kwargs)
+ noise = kwargs.get("noise", None)
+
+ audio_embed = kwargs.get("audio_embed", None)
+ if audio_embed is not None:
+ out['audio_embed'] = comfy.conds.CONDRegular(audio_embed)
+
+ if "c_concat" not in out: # 1.7B model
+ reference_latents = kwargs.get("reference_latents", None)
+ if reference_latents is not None:
+ out['reference_latent'] = comfy.conds.CONDRegular(self.process_latent_in(reference_latents[-1]))
+ else:
+ noise_shape = list(noise.shape)
+ noise_shape[1] += 4
+ concat_latent = torch.zeros(noise_shape, device=noise.device, dtype=noise.dtype)
+ zero_vae_values_first = torch.tensor([0.8660, -0.4326, -0.0017, -0.4884, -0.5283, 0.9207, -0.9896, 0.4433, -0.5543, -0.0113, 0.5753, -0.6000, -0.8346, -0.3497, -0.1926, -0.6938]).view(1, 16, 1, 1, 1)
+ zero_vae_values_second = torch.tensor([1.0869, -1.2370, 0.0206, -0.4357, -0.6411, 2.0307, -1.5972, 1.2659, -0.8595, -0.4654, 0.9638, -1.6330, -1.4310, -0.1098, -0.3856, -1.4583]).view(1, 16, 1, 1, 1)
+ zero_vae_values = torch.tensor([0.8642, -1.8583, 0.1577, 0.1350, -0.3641, 2.5863, -1.9670, 1.6065, -1.0475, -0.8678, 1.1734, -1.8138, -1.5933, -0.7721, -0.3289, -1.3745]).view(1, 16, 1, 1, 1)
+ concat_latent[:, 4:] = zero_vae_values
+ concat_latent[:, 4:, :1] = zero_vae_values_first
+ concat_latent[:, 4:, 1:2] = zero_vae_values_second
+ out['c_concat'] = comfy.conds.CONDNoiseShape(concat_latent)
+ reference_latents = kwargs.get("reference_latents", None)
+ if reference_latents is not None:
+ ref_latent = self.process_latent_in(reference_latents[-1])
+ ref_latent_shape = list(ref_latent.shape)
+ ref_latent_shape[1] += 4 + ref_latent_shape[1]
+ ref_latent_full = torch.zeros(ref_latent_shape, device=ref_latent.device, dtype=ref_latent.dtype)
+ ref_latent_full[:, 20:] = ref_latent
+ ref_latent_full[:, 16:20] = 1.0
+ out['reference_latent'] = comfy.conds.CONDRegular(ref_latent_full)
+
+ return out
+
+ def resize_cond_for_context_window(self, cond_key, cond_value, window, x_in, device, retain_index_list=[]):
+ if cond_key == "audio_embed":
+ return comfy.context_windows.slice_cond(cond_value, window, x_in, device, temporal_dim=1)
+ return super().resize_cond_for_context_window(cond_key, cond_value, window, x_in, device, retain_index_list=retain_index_list)
+
+class WAN22_Animate(WAN21):
+ def __init__(self, model_config, model_type=ModelType.FLOW, image_to_video=False, device=None):
+ super(WAN21, self).__init__(model_config, model_type, device=device, unet_model=comfy.ldm.wan.model_animate.AnimateWanModel)
+ self.image_to_video = image_to_video
+
+ def extra_conds(self, **kwargs):
+ out = super().extra_conds(**kwargs)
+
+ face_video_pixels = kwargs.get("face_video_pixels", None)
+ if face_video_pixels is not None:
+ out['face_pixel_values'] = comfy.conds.CONDRegular(face_video_pixels)
+
+ pose_latents = kwargs.get("pose_video_latent", None)
+ if pose_latents is not None:
+ out['pose_latents'] = comfy.conds.CONDRegular(self.process_latent_in(pose_latents))
+ return out
+
+ def resize_cond_for_context_window(self, cond_key, cond_value, window, x_in, device, retain_index_list=[]):
+ if cond_key == "face_pixel_values":
+ return comfy.context_windows.slice_cond(cond_value, window, x_in, device, temporal_dim=2, temporal_scale=4, temporal_offset=1)
+ if cond_key == "pose_latents":
+ return comfy.context_windows.slice_cond(cond_value, window, x_in, device, temporal_dim=2, temporal_offset=1)
+ return super().resize_cond_for_context_window(cond_key, cond_value, window, x_in, device, retain_index_list=retain_index_list)
+
+class WAN22_S2V(WAN21):
+ def __init__(self, model_config, model_type=ModelType.FLOW, device=None):
+ super(WAN21, self).__init__(model_config, model_type, device=device, unet_model=comfy.ldm.wan.model.WanModel_S2V)
+ self.memory_usage_factor_conds = ("reference_latent", "reference_motion")
+ self.memory_usage_shape_process = {"reference_motion": lambda shape: [shape[0], shape[1], 1.5, shape[-2], shape[-1]]}
+
+ def extra_conds(self, **kwargs):
+ out = super().extra_conds(**kwargs)
+ audio_embed = kwargs.get("audio_embed", None)
+ if audio_embed is not None:
+ out['audio_embed'] = comfy.conds.CONDRegular(audio_embed)
+
+ reference_latents = kwargs.get("reference_latents", None)
+ if reference_latents is not None:
+ out['reference_latent'] = comfy.conds.CONDRegular(self.process_latent_in(reference_latents[-1]))
+
+ reference_motion = kwargs.get("reference_motion", None)
+ if reference_motion is not None:
+ out['reference_motion'] = comfy.conds.CONDRegular(self.process_latent_in(reference_motion))
+
+ control_video = kwargs.get("control_video", None)
+ if control_video is not None:
+ out['control_video'] = comfy.conds.CONDRegular(self.process_latent_in(control_video))
+ return out
+
+ def extra_conds_shapes(self, **kwargs):
+ out = {}
+ ref_latents = kwargs.get("reference_latents", None)
+ if ref_latents is not None:
+ out['reference_latent'] = list([1, 16, sum(map(lambda a: math.prod(a.size()), ref_latents)) // 16])
+
+ reference_motion = kwargs.get("reference_motion", None)
+ if reference_motion is not None:
+ out['reference_motion'] = reference_motion.shape
+ return out
+
+ def resize_cond_for_context_window(self, cond_key, cond_value, window, x_in, device, retain_index_list=[]):
+ if cond_key == "audio_embed":
+ return comfy.context_windows.slice_cond(cond_value, window, x_in, device, temporal_dim=1)
+ return super().resize_cond_for_context_window(cond_key, cond_value, window, x_in, device, retain_index_list=retain_index_list)
+
+class WAN22(WAN21):
+ def __init__(self, model_config, model_type=ModelType.FLOW, image_to_video=False, device=None):
+ super(WAN21, self).__init__(model_config, model_type, device=device, unet_model=comfy.ldm.wan.model.WanModel)
+ self.image_to_video = image_to_video
+
+ def extra_conds(self, **kwargs):
+ out = super().extra_conds(**kwargs)
+ denoise_mask = kwargs.get("denoise_mask", None)
+ if denoise_mask is not None:
+ out["denoise_mask"] = comfy.conds.CONDRegular(denoise_mask)
+ return out
+
+ def process_timestep(self, timestep, x, denoise_mask=None, **kwargs):
+ if denoise_mask is None:
+ return timestep
+ temp_ts = (torch.mean(denoise_mask[:, :, :, :, :], dim=(1, 3, 4), keepdim=True) * timestep.view([timestep.shape[0]] + [1] * (denoise_mask.ndim - 1))).reshape(timestep.shape[0], -1)
+ return temp_ts
+
+ def scale_latent_inpaint(self, sigma, noise, latent_image, **kwargs):
+ return latent_image
+
+class WAN21_FlowRVS(WAN21):
+ def __init__(self, model_config, model_type=ModelType.IMG_TO_IMG_FLOW, image_to_video=False, device=None):
+ model_config.unet_config["model_type"] = "t2v"
+ super(WAN21, self).__init__(model_config, model_type, device=device, unet_model=comfy.ldm.wan.model.WanModel)
+ self.image_to_video = image_to_video
+
+class WAN21_SCAIL(WAN21):
+ def __init__(self, model_config, model_type=ModelType.FLOW, image_to_video=False, device=None):
+ super(WAN21, self).__init__(model_config, model_type, device=device, unet_model=comfy.ldm.wan.model.SCAILWanModel)
+ self.memory_usage_factor_conds = ("reference_latent", "pose_latents")
+ self.memory_usage_shape_process = {"pose_latents": lambda shape: [shape[0], shape[1], 1.5, shape[-2], shape[-1]]}
+ self.image_to_video = image_to_video
+
+ def extra_conds(self, **kwargs):
+ out = super().extra_conds(**kwargs)
+
+ reference_latents = kwargs.get("reference_latents", None)
+ if reference_latents is not None:
+ # SCAIL-2 multi-reference: reference_latents[0] is the primary ref, [1:] are additional
+ # references. Stack as [additional..., primary] so the primary stays adjacent to the video.
+ ordered = list(reference_latents[1:]) + list(reference_latents[:1])
+ stacked = []
+ for lat in ordered:
+ lat = self.process_latent_in(lat)
+ stacked.append(torch.cat([lat, torch.ones_like(lat[:, :4])], dim=1))
+ out['reference_latent'] = comfy.conds.CONDRegular(torch.cat(stacked, dim=2))
+
+ pose_latents = kwargs.get("pose_video_latent", None)
+ if pose_latents is not None:
+ pose_latents = self.process_latent_in(pose_latents)
+ pose_mask = torch.ones_like(pose_latents[:, :4])
+ pose_latents = torch.cat([pose_latents, pose_mask], dim=1)
+ out['pose_latents'] = comfy.conds.CONDRegular(pose_latents)
+
+ return out
+
+ def extra_conds_shapes(self, **kwargs):
+ out = {}
+ ref_latents = kwargs.get("reference_latents", None)
+ if ref_latents is not None:
+ out['reference_latent'] = list([1, 20, sum(map(lambda a: math.prod(a.size()), ref_latents)) // 16])
+
+ pose_latents = kwargs.get("pose_video_latent", None)
+ if pose_latents is not None:
+ out['pose_latents'] = [pose_latents.shape[0], 20, *pose_latents.shape[2:]]
+
+ return out
+
+class WAN21_SCAIL2(WAN21_SCAIL):
+ """SCAIL-2: SCAIL-Preview + an additive binary multi-identity mask stream."""
+
+ def __init__(self, model_config, model_type=ModelType.FLOW, image_to_video=False, device=None):
+ super(WAN21, self).__init__(model_config, model_type, device=device, unet_model=comfy.ldm.wan.model.SCAIL2WanModel)
+ self.memory_usage_factor_conds = ("reference_latent", "pose_latents", "ref_mask_latents", "sam_latents")
+ self.memory_usage_shape_process = {
+ "pose_latents": lambda shape: [shape[0], shape[1], 1.5, shape[-2], shape[-1]],
+ "sam_latents": lambda shape: [shape[0], shape[1], 1.5, shape[-2], shape[-1]],
+ }
+ self.image_to_video = image_to_video
+
+ def extra_conds(self, **kwargs):
+ out = super().extra_conds(**kwargs)
+
+ driving_mask_28ch = kwargs.get("driving_mask_28ch", None)
+ if driving_mask_28ch is not None:
+ out['sam_latents'] = comfy.conds.CONDRegular(driving_mask_28ch.movedim(1, 2).contiguous())
+
+ # ref_mask_28ch holds one identity mask per stacked reference frame (additional refs first, then the primary ref), followed by zeros over the video frames.
+ ref_mask_28ch = kwargs.get("ref_mask_28ch", None)
+ if ref_mask_28ch is not None:
+ out['ref_mask_latents'] = comfy.conds.CONDRegular(ref_mask_28ch.movedim(1, 2).contiguous())
+
+ ref_mask_flag = kwargs.get("ref_mask_flag", None)
+ if ref_mask_flag is not None:
+ out['ref_mask_flag'] = comfy.conds.CONDConstant(ref_mask_flag)
+
+ return out
+
+ def extra_conds_shapes(self, **kwargs):
+ out = super().extra_conds_shapes(**kwargs)
+ driving_mask_28ch = kwargs.get("driving_mask_28ch", None)
+ if driving_mask_28ch is not None:
+ s = driving_mask_28ch.shape
+ out['sam_latents'] = [s[0], 28, s[1], s[3], s[4]]
+ ref_mask_28ch = kwargs.get("ref_mask_28ch", None)
+ if ref_mask_28ch is not None:
+ s = ref_mask_28ch.shape
+ out['ref_mask_latents'] = [s[0], 28, s[1], s[3], s[4]]
+ return out
+
+ def resize_cond_for_context_window(self, cond_key, cond_value, window, x_in, device, retain_index_list=[]):
+ if cond_key in ("sam_latents", "pose_latents"):
+ # Return sliced view omitting retain_index_list
+ return comfy.context_windows.slice_cond(cond_value, window, x_in, device, temporal_dim=2, temporal_offset=0)
+ if cond_key == "ref_mask_latents" and hasattr(cond_value, "cond") and isinstance(cond_value.cond, torch.Tensor):
+ # The ref mask is N leading ref frames padded with frames of zeros, so just grab the first frames for all windows
+ full_ref_mask = cond_value.cond
+ video_frame_count = x_in.shape[2]
+ ref_frame_count = full_ref_mask.shape[2] - video_frame_count
+ if ref_frame_count < 1:
+ return None
+ window_length = len(window.index_list)
+
+ # Account for the causal anchor frame if it exists
+ anchor_index = getattr(window, "causal_anchor_index", None)
+ if anchor_index is not None and anchor_index >= 0:
+ window_length += 1
+
+ window_ref_mask = full_ref_mask[:, :, :window_length + ref_frame_count].to(device)
+ return cond_value._copy_with(window_ref_mask)
+
+ return super().resize_cond_for_context_window(cond_key, cond_value, window, x_in, device, retain_index_list=retain_index_list)
+
+ def concat_cond(self, **kwargs):
+ # The 4 extra channels are the history_mask (1 at clean-anchor frames).
+ noise = kwargs.get("noise", None)
+ extra_channels = self.diffusion_model.patch_embedding.weight.shape[1] - noise.shape[1]
+ if extra_channels != 4:
+ return super().concat_cond(**kwargs)
+
+ mask = kwargs.get("concat_mask", kwargs.get("denoise_mask", None))
+ if mask is None:
+ return torch.zeros_like(noise)[:, :4]
+
+ device = kwargs["device"]
+ if mask.shape[1] != 4:
+ mask = torch.mean(mask, dim=1, keepdim=True)
+ mask = 1.0 - mask
+ mask = utils.common_upscale(mask.to(device), noise.shape[-1], noise.shape[-2], "bilinear", "center")
+ if mask.shape[-3] < noise.shape[-3]:
+ mask = torch.nn.functional.pad(mask, (0, 0, 0, 0, 0, noise.shape[-3] - mask.shape[-3]), mode='constant', value=0)
+ if mask.shape[1] == 1:
+ mask = mask.repeat(1, 4, 1, 1, 1)
+ mask = utils.resize_to_batch_size(mask, noise.shape[0])
+ return mask
+
+ def scale_latent_inpaint(self, sigma, noise, latent_image, **kwargs):
+ # Hold anchor constant across all sigmas instead of base sigma*noise + (1-sigma)*latent_image.
+ return latent_image
+
+
+class WAN22_WanDancer(WAN21):
+ def __init__(self, model_config, model_type=ModelType.FLOW, image_to_video=True, device=None):
+ super(WAN21, self).__init__(model_config, model_type, device=device, unet_model=comfy.ldm.wan.model_wandancer.WanDancerModel)
+ self.image_to_video = image_to_video
+
+ def extra_conds(self, **kwargs):
+ out = super().extra_conds(**kwargs)
+ audio_embed = kwargs.get("audio_embed", None)
+ if audio_embed is not None:
+ out['audio_embed'] = comfy.conds.CONDRegular(audio_embed)
+
+ clip_vision_output_ref = kwargs.get("clip_vision_output_ref", None)
+ if clip_vision_output_ref is not None:
+ out['clip_fea_ref'] = comfy.conds.CONDRegular(clip_vision_output_ref.penultimate_hidden_states)
+
+ fps = kwargs.get("fps", None)
+ if fps is not None:
+ out['fps'] = comfy.conds.CONDConstant(fps)
+
+ audio_inject_scale = kwargs.get("audio_inject_scale", None)
+ if audio_inject_scale is not None:
+ out['audio_inject_scale'] = comfy.conds.CONDConstant(audio_inject_scale)
+ return out
+
+class Hunyuan3Dv2(BaseModel):
+ def __init__(self, model_config, model_type=ModelType.FLOW, device=None):
+ super().__init__(model_config, model_type, device=device, unet_model=comfy.ldm.hunyuan3d.model.Hunyuan3Dv2)
+
+ def extra_conds(self, **kwargs):
+ out = super().extra_conds(**kwargs)
+ cross_attn = kwargs.get("cross_attn", None)
+ if cross_attn is not None:
+ out['c_crossattn'] = comfy.conds.CONDRegular(cross_attn)
+
+ guidance = kwargs.get("guidance", 5.0)
+ if guidance is not None:
+ out['guidance'] = comfy.conds.CONDRegular(torch.FloatTensor([guidance]))
+ return out
+
+class Hunyuan3Dv2_1(BaseModel):
+ def __init__(self, model_config, model_type=ModelType.FLOW, device=None):
+ super().__init__(model_config, model_type, device=device, unet_model=comfy.ldm.hunyuan3dv2_1.hunyuandit.HunYuanDiTPlain)
+
+ def extra_conds(self, **kwargs):
+ out = super().extra_conds(**kwargs)
+ cross_attn = kwargs.get("cross_attn", None)
+ if cross_attn is not None:
+ out['c_crossattn'] = comfy.conds.CONDRegular(cross_attn)
+
+ guidance = kwargs.get("guidance", 5.0)
+ if guidance is not None:
+ out['guidance'] = comfy.conds.CONDRegular(torch.FloatTensor([guidance]))
+ return out
+
+class MiniMaxH3(BaseModel):
+ def __init__(self, model_config, model_type=ModelType.FLOW, device=None):
+ super().__init__(model_config, model_type, device=device, unet_model=comfy.ldm.minimax.model.MiniMaxH3Model)
+
+ def extra_conds(self, **kwargs):
+ out = super().extra_conds(**kwargs)
+ cross_attn = kwargs.get("cross_attn", None)
+ if cross_attn is not None:
+ # run condition_proj + token refiner once per sampling instead of per step
+ cross_attn = self.diffusion_model.preprocess_text_embeds(
+ cross_attn.to(device=kwargs["device"], dtype=self.get_dtype_inference()))
+ out['c_crossattn'] = comfy.conds.CONDRegular(cross_attn)
+
+ latent_shapes = kwargs.get("latent_shapes", None)
+ if latent_shapes is not None:
+ out['latent_shapes'] = comfy.conds.CONDConstant(latent_shapes)
+
+ # Everything H3-specific rides in one dict so _apply_model's dtype cast
+ # (which would flatten fp32 cond latents and long tags to bf16) skips it.
+ payload = {}
+ tags = kwargs.get("minimax_token_tags", None)
+ if tags is not None:
+ payload["text_token_tags"] = tags
+ keyframes = kwargs.get("minimax_keyframes", None)
+ if keyframes is not None:
+ payload["keyframes"] = keyframes
+ payload["frame_count"] = kwargs.get("minimax_frame_count", None)
+ payload["cond_video_latents"] = [kf["latent"] for kf in keyframes]
+ refs = kwargs.get("minimax_refs", None)
+ if refs is not None:
+ payload["refs"] = refs
+ payload["cond_video_latents"] = [r["latent"] for r in refs if "latent" in r]
+ payload["cond_audio_latents"] = [r["audio_latent"] for r in refs if r.get("audio_latent") is not None]
+ if kwargs.get("minimax_visual_cond_noise_aug", None) is not None:
+ payload["visual_cond_noise_aug"] = kwargs["minimax_visual_cond_noise_aug"]
+ if kwargs.get("minimax_audio_cond_noise_aug", None) is not None:
+ payload["audio_cond_noise_aug"] = kwargs["minimax_audio_cond_noise_aug"]
+ payload["seed"] = kwargs.get("seed", 0)
+ if cross_attn is not None and latent_shapes is not None and len(latent_shapes) > 1:
+ # packed layout built once per sampling run, h/w rounded up to the DiT's 2x2 patch
+ vs = latent_shapes[0]
+ payload["layout"] = comfy.ldm.minimax.model.PackedLayout(
+ cross_attn.shape[1], vs[2], (vs[3] + 1) // 2 * 2, (vs[4] + 1) // 2 * 2,
+ latent_shapes[1][-1], keyframes=payload.get("keyframes"),
+ refs=payload.get("refs"), frame_count=payload.get("frame_count"))
+ out['minimax_payload'] = comfy.conds.CONDConstant(payload)
+ return out
+
+ def scale_latent_inpaint(self, sigma, noise, latent_image, **kwargs):
+ return latent_image
+
+class TripoSplat(BaseModel):
+ def __init__(self, model_config, model_type=ModelType.FLOW, device=None):
+ super().__init__(model_config, model_type, device=device, unet_model=comfy.ldm.triposplat.model.LatentSeqMMFlowModel)
+
+ def extra_conds(self, **kwargs):
+ out = super().extra_conds(**kwargs)
+ cross_attn = kwargs.get("cross_attn", None) # DINOv3 token sequence -> cross-attention context.
+ if cross_attn is not None:
+ out['c_crossattn'] = comfy.conds.CONDRegular(cross_attn)
+ ref_latents = kwargs.get("reference_latents", None) # Flux2 VAE image latent -> additive second conditioning.
+ if ref_latents is not None:
+ out['ref_latents'] = comfy.conds.CONDList(list(ref_latents))
+ latent_shapes = kwargs.get("latent_shapes", None) # {latent, camera} nested latent
+ if latent_shapes is not None:
+ out['latent_shapes'] = comfy.conds.CONDConstant(latent_shapes)
+ return out
+
+
+class HiDream(BaseModel):
+ def __init__(self, model_config, model_type=ModelType.FLOW, device=None):
+ super().__init__(model_config, model_type, device=device, unet_model=comfy.ldm.hidream.model.HiDreamImageTransformer2DModel)
+
+ def encode_adm(self, **kwargs):
+ return kwargs["pooled_output"]
+
+ def extra_conds(self, **kwargs):
+ out = super().extra_conds(**kwargs)
+ cross_attn = kwargs.get("cross_attn", None)
+ if cross_attn is not None:
+ out['c_crossattn'] = comfy.conds.CONDRegular(cross_attn)
+ conditioning_llama3 = kwargs.get("conditioning_llama3", None)
+ if conditioning_llama3 is not None:
+ out['encoder_hidden_states_llama3'] = comfy.conds.CONDRegular(conditioning_llama3)
+ image_cond = kwargs.get("concat_latent_image", None)
+ if image_cond is not None:
+ out['image_cond'] = comfy.conds.CONDNoiseShape(self.process_latent_in(image_cond))
+ return out
+
+class HiDreamO1(BaseModel):
+ """HiDream-O1-Image: pixel-space DiT (no VAE). Refs from HiDreamO1ReferenceImages and tokens from the stub TE flow through
+ extra_conds; the heavy preprocessing lives in comfy.ldm.hidream_o1.conditioning."""
+ PATCH_SIZE = 32
+
+ def __init__(self, model_config, model_type=ModelType.FLOW, device=None):
+ super().__init__(model_config, model_type, device=device, unet_model=comfy.ldm.hidream_o1.model.HiDreamO1Transformer)
+
+ def extra_conds(self, **kwargs):
+ out = super().extra_conds(**kwargs)
+ text_input_ids = kwargs.get("text_input_ids", None)
+ noise = kwargs.get("noise", None)
+ if text_input_ids is None or noise is None:
+ return out
+
+ # handle area conds
+ area = kwargs.get("area", None)
+ if area is not None:
+ crop_h = min(noise.shape[-2] - area[2], area[0])
+ crop_w = min(noise.shape[-1] - area[3], area[1])
+ noise = torch.empty((noise.shape[0], 3, crop_h, crop_w), dtype=noise.dtype, device=noise.device)
+
+ conds = build_extra_conds(
+ text_input_ids, noise,
+ ref_images=kwargs.get("reference_latents", None),
+ target_patch_size=self.PATCH_SIZE,
+ )
+ for k, v in conds.items():
+ # ar_len is a Python int (precomputed to avoid a GPU sync in forward).
+ cls = comfy.conds.CONDConstant if k == "ar_len" else comfy.conds.CONDRegular
+ out[k] = cls(v)
+ return out
+
+class Chroma(Flux):
+ def __init__(self, model_config, model_type=ModelType.FLUX, device=None, unet_model=comfy.ldm.chroma.model.Chroma):
+ super().__init__(model_config, model_type, device=device, unet_model=unet_model)
+
+ def extra_conds(self, **kwargs):
+ out = super().extra_conds(**kwargs)
+
+ guidance = kwargs.get("guidance", 0)
+ if guidance is not None:
+ out['guidance'] = comfy.conds.CONDRegular(torch.FloatTensor([guidance]))
+ return out
+
+class ChromaRadiance(Chroma):
+ def __init__(self, model_config, model_type=ModelType.FLUX, device=None):
+ super().__init__(model_config, model_type, device=device, unet_model=comfy.ldm.chroma_radiance.model.ChromaRadiance)
+
+class ACEStep(BaseModel):
+ def __init__(self, model_config, model_type=ModelType.FLOW, device=None):
+ super().__init__(model_config, model_type, device=device, unet_model=comfy.ldm.ace.model.ACEStepTransformer2DModel)
+
+ def extra_conds(self, **kwargs):
+ out = super().extra_conds(**kwargs)
+ noise = kwargs.get("noise", None)
+
+ cross_attn = kwargs.get("cross_attn", None)
+ if cross_attn is not None:
+ out['c_crossattn'] = comfy.conds.CONDRegular(cross_attn)
+
+ conditioning_lyrics = kwargs.get("conditioning_lyrics", None)
+ if cross_attn is not None:
+ out['lyric_token_idx'] = comfy.conds.CONDRegular(conditioning_lyrics)
+ out['speaker_embeds'] = comfy.conds.CONDRegular(torch.zeros(noise.shape[0], 512, device=noise.device, dtype=noise.dtype))
+ out['lyrics_strength'] = comfy.conds.CONDConstant(kwargs.get("lyrics_strength", 1.0))
+ return out
+
+class ACEStep15(BaseModel):
+ def __init__(self, model_config, model_type=ModelType.FLOW, device=None):
+ super().__init__(model_config, model_type, device=device, unet_model=comfy.ldm.ace.ace_step15.AceStepConditionGenerationModel)
+
+ def extra_conds(self, **kwargs):
+ out = super().extra_conds(**kwargs)
+ device = kwargs["device"]
+ noise = kwargs["noise"]
+
+ cross_attn = kwargs.get("cross_attn", None)
+ if cross_attn is not None:
+ if torch.count_nonzero(cross_attn) == 0:
+ out['replace_with_null_embeds'] = comfy.conds.CONDConstant(True)
+ out['c_crossattn'] = comfy.conds.CONDRegular(cross_attn)
+
+ conditioning_lyrics = kwargs.get("conditioning_lyrics", None)
+ if cross_attn is not None:
+ out['lyric_embed'] = comfy.conds.CONDRegular(conditioning_lyrics)
+
+ refer_audio = kwargs.get("reference_audio_timbre_latents", None)
+ if refer_audio is None or len(refer_audio) == 0:
+ refer_audio = comfy.ldm.ace.ace_step15.get_silence_latent(noise.shape[2], device)
+ pass_audio_codes = True
+ else:
+ refer_audio = refer_audio[-1][:, :, :noise.shape[2]]
+ out['is_covers'] = comfy.conds.CONDConstant(True)
+ pass_audio_codes = False
+
+ if pass_audio_codes:
+ audio_codes = kwargs.get("audio_codes", None)
+ if audio_codes is not None:
+ out['audio_codes'] = comfy.conds.CONDRegular(torch.tensor(audio_codes, device=device))
+ refer_audio = refer_audio[:, :, :750]
+ else:
+ out['is_covers'] = comfy.conds.CONDConstant(False)
+
+ if refer_audio.shape[2] < noise.shape[2]:
+ pad = comfy.ldm.ace.ace_step15.get_silence_latent(noise.shape[2], device)
+ refer_audio = torch.cat([refer_audio.to(pad), pad[:, :, refer_audio.shape[2]:]], dim=2)
+
+ out['refer_audio'] = comfy.conds.CONDRegular(refer_audio)
+ return out
+
+class Omnigen2(BaseModel):
+ def __init__(self, model_config, model_type=ModelType.FLOW, device=None):
+ super().__init__(model_config, model_type, device=device, unet_model=comfy.ldm.omnigen.omnigen2.OmniGen2Transformer2DModel)
+ self.memory_usage_factor_conds = ("ref_latents",)
+
+ def extra_conds(self, **kwargs):
+ out = super().extra_conds(**kwargs)
+ attention_mask = kwargs.get("attention_mask", None)
+ if attention_mask is not None:
+ if torch.numel(attention_mask) != attention_mask.sum():
+ out['attention_mask'] = comfy.conds.CONDRegular(attention_mask)
+ out['num_tokens'] = comfy.conds.CONDConstant(max(1, torch.sum(attention_mask).item()))
+ cross_attn = kwargs.get("cross_attn", None)
+ if cross_attn is not None:
+ out['c_crossattn'] = comfy.conds.CONDRegular(cross_attn)
+ ref_latents = kwargs.get("reference_latents", None)
+ if ref_latents is not None:
+ out['ref_latents'] = comfy.conds.CONDList([self.process_latent_in(lat) for lat in ref_latents])
+ return out
+
+ def extra_conds_shapes(self, **kwargs):
+ out = {}
+ ref_latents = kwargs.get("reference_latents", None)
+ if ref_latents is not None:
+ out['ref_latents'] = list([1, 16, sum(map(lambda a: math.prod(a.size()), ref_latents)) // 16])
+ return out
+
+class Boogu(Omnigen2):
+ def __init__(self, model_config, model_type=ModelType.FLOW, device=None):
+ super(Omnigen2, self).__init__(model_config, model_type, device=device, unet_model=comfy.ldm.boogu.model.BooguTransformer2DModel)
+ self.memory_usage_factor_conds = ("ref_latents",)
+
+class QwenImage(BaseModel):
+ def __init__(self, model_config, model_type=ModelType.FLUX, device=None, unet_model=comfy.ldm.qwen_image.model.QwenImageTransformer2DModel):
+ super().__init__(model_config, model_type, device=device, unet_model=unet_model)
+ self.memory_usage_factor_conds = ("ref_latents",)
+
+ def extra_conds(self, **kwargs):
+ out = super().extra_conds(**kwargs)
+ attention_mask = kwargs.get("attention_mask", None)
+ if attention_mask is not None:
+ out['attention_mask'] = comfy.conds.CONDRegular(attention_mask)
+ cross_attn = kwargs.get("cross_attn", None)
+ if cross_attn is not None:
+ out['c_crossattn'] = comfy.conds.CONDRegular(cross_attn)
+ ref_latents = kwargs.get("reference_latents", None)
+ if ref_latents is not None:
+ latents = []
+ for lat in ref_latents:
+ latents.append(self.process_latent_in(lat))
+ out['ref_latents'] = comfy.conds.CONDList(latents)
+
+ ref_latents_method = kwargs.get("reference_latents_method", None)
+ if ref_latents_method is not None:
+ out['ref_latents_method'] = comfy.conds.CONDConstant(ref_latents_method)
+ return out
+
+ def extra_conds_shapes(self, **kwargs):
+ out = {}
+ ref_latents = kwargs.get("reference_latents", None)
+ if ref_latents is not None:
+ out['ref_latents'] = list([1, 16, sum(map(lambda a: math.prod(a.size()), ref_latents)) // 16])
+ return out
+
+class MageFlow(QwenImage):
+ def __init__(self, model_config, model_type=ModelType.FLOW, device=None):
+ super().__init__(model_config, model_type, device=device, unet_model=comfy.ldm.mage_flow.model.MageFlowTransformer2DModel)
+
+ def process_timestep(self, timestep, **kwargs):
+ # Mage runs in bf16 and rounds its timestep frequency table to the timestep dtype, keep that on fp32 devices.
+ return timestep.to(torch.bfloat16)
+
+ def extra_conds_shapes(self, **kwargs):
+ out = {}
+ ref_latents = kwargs.get("reference_latents", None)
+ if ref_latents is not None:
+ out['ref_latents'] = list([1, 128, sum(map(lambda a: math.prod(a.size()), ref_latents)) // 128])
+ return out
+
+class JoyImage(BaseModel):
+ def __init__(self, model_config, model_type=ModelType.FLOW, device=None):
+ super().__init__(model_config, model_type, device=device, unet_model=comfy.ldm.joyimage.model.JoyImageTransformer3DModel)
+ self.memory_usage_factor_conds = ("ref_latents",)
+
+ def extra_conds(self, **kwargs):
+ out = super().extra_conds(**kwargs)
+ cross_attn = kwargs.get("cross_attn", None)
+ if cross_attn is not None:
+ out['c_crossattn'] = comfy.conds.CONDRegular(cross_attn)
+ ref_latents = kwargs.get("reference_latents", None)
+ if ref_latents is not None:
+ out['ref_latents'] = comfy.conds.CONDList([self.process_latent_in(lat) for lat in ref_latents])
+ return out
+
+ def extra_conds_shapes(self, **kwargs):
+ out = {}
+ ref_latents = kwargs.get("reference_latents", None)
+ if ref_latents is not None:
+ out['ref_latents'] = list([1, 16, sum(map(lambda a: math.prod(a.size()), ref_latents)) // 16])
+ return out
+
+class Ideogram4(BaseModel):
+ def __init__(self, model_config, model_type=ModelType.FLOW, device=None):
+ super().__init__(model_config, model_type, device=device, unet_model=comfy.ldm.ideogram4.model.Ideogram4Transformer2DModel)
+
+ def extra_conds(self, **kwargs):
+ out = super().extra_conds(**kwargs)
+ attention_mask = kwargs.get("attention_mask", None)
+ if attention_mask is not None:
+ if torch.numel(attention_mask) != attention_mask.sum():
+ out['attention_mask'] = comfy.conds.CONDRegular(attention_mask)
+ cross_attn = kwargs.get("cross_attn", None)
+ if cross_attn is not None:
+ out['c_crossattn'] = comfy.conds.CONDRegular(cross_attn)
+ return out
+
+class Krea2(BaseModel):
+ def __init__(self, model_config, model_type=ModelType.FLUX, device=None):
+ super().__init__(model_config, model_type, device=device, unet_model=comfy.ldm.krea2.model.SingleStreamDiT)
+ self.memory_usage_factor_conds = ("ref_latents",)
+
+ def extra_conds(self, **kwargs):
+ out = super().extra_conds(**kwargs)
+ cross_attn = kwargs.get("cross_attn", None)
+ if cross_attn is not None:
+ out['c_crossattn'] = comfy.conds.CONDRegular(cross_attn)
+ ref_latents = kwargs.get("reference_latents", None)
+ if ref_latents is not None:
+ latents = []
+ for lat in ref_latents:
+ latents.append(self.process_latent_in(lat))
+ out['ref_latents'] = comfy.conds.CONDList(latents)
+
+ ref_latents_method = kwargs.get("reference_latents_method", None)
+ if ref_latents_method is not None:
+ out['ref_latents_method'] = comfy.conds.CONDConstant(ref_latents_method)
+ return out
+
+ def extra_conds_shapes(self, **kwargs):
+ out = {}
+ ref_latents = kwargs.get("reference_latents", None)
+ if ref_latents is not None:
+ out['ref_latents'] = list([1, 16, sum(map(lambda a: math.prod(a.size()), ref_latents)) // 16])
+ return out
+
+class HunyuanImage21(BaseModel):
+ def __init__(self, model_config, model_type=ModelType.FLOW, device=None):
+ super().__init__(model_config, model_type, device=device, unet_model=comfy.ldm.hunyuan_video.model.HunyuanVideo)
+
+ def extra_conds(self, **kwargs):
+ out = super().extra_conds(**kwargs)
+ attention_mask = kwargs.get("attention_mask", None)
+ if attention_mask is not None:
+ if torch.numel(attention_mask) != attention_mask.sum():
+ out['attention_mask'] = comfy.conds.CONDRegular(attention_mask)
+ cross_attn = kwargs.get("cross_attn", None)
+ if cross_attn is not None:
+ out['c_crossattn'] = comfy.conds.CONDRegular(cross_attn)
+
+ conditioning_byt5small = kwargs.get("conditioning_byt5small", None)
+ if conditioning_byt5small is not None:
+ out['txt_byt5'] = comfy.conds.CONDRegular(conditioning_byt5small)
+
+ guidance = kwargs.get("guidance", 6.0)
+ if guidance is not None:
+ out['guidance'] = comfy.conds.CONDRegular(torch.FloatTensor([guidance]))
+
+ return out
+
+class HunyuanImage21Refiner(HunyuanImage21):
+ def concat_cond(self, **kwargs):
+ noise = kwargs.get("noise", None)
+ image = kwargs.get("concat_latent_image", None)
+ noise_augmentation = kwargs.get("noise_augmentation", 0.0)
+ device = kwargs["device"]
+
+ if image is None:
+ shape_image = list(noise.shape)
+ image = torch.zeros(shape_image, dtype=noise.dtype, layout=noise.layout, device=noise.device)
+ else:
+ image = utils.common_upscale(image.to(device), noise.shape[-1], noise.shape[-2], "bilinear", "center")
+ image = self.process_latent_in(image)
+ image = utils.resize_to_batch_size(image, noise.shape[0])
+ if noise_augmentation > 0:
+ generator = torch.Generator(device="cpu")
+ generator.manual_seed(kwargs.get("seed", 0) - 10)
+ noise = torch.randn(image.shape, generator=generator, dtype=image.dtype, device="cpu").to(image.device)
+ image = noise_augmentation * noise + min(1.0 - noise_augmentation, 0.75) * image
+ else:
+ image = 0.75 * image
+ return image
+
+ def extra_conds(self, **kwargs):
+ out = super().extra_conds(**kwargs)
+ out['disable_time_r'] = comfy.conds.CONDConstant(True)
+ return out
+
+class HunyuanVideo15(HunyuanVideo):
+ def __init__(self, model_config, model_type=ModelType.FLOW, device=None):
+ super().__init__(model_config, model_type, device=device)
+
+ def concat_cond(self, **kwargs):
+ noise = kwargs.get("noise", None)
+ extra_channels = self.diffusion_model.img_in.proj.weight.shape[1] - noise.shape[1] - 1 #noise 32 img cond 32 + mask 1
+ if extra_channels == 0:
+ return None
+
+ image = kwargs.get("concat_latent_image", None)
+ device = kwargs["device"]
+
+ if image is None:
+ shape_image = list(noise.shape)
+ shape_image[1] = extra_channels
+ image = torch.zeros(shape_image, dtype=noise.dtype, layout=noise.layout, device=noise.device)
+ else:
+ latent_dim = self.latent_format.latent_channels
+ image = utils.common_upscale(image.to(device), noise.shape[-1], noise.shape[-2], "bilinear", "center")
+ for i in range(0, image.shape[1], latent_dim):
+ image[:, i: i + latent_dim] = self.process_latent_in(image[:, i: i + latent_dim])
+ image = utils.resize_to_batch_size(image, noise.shape[0])
+
+ mask = kwargs.get("concat_mask", kwargs.get("denoise_mask", None))
+ if mask is None:
+ mask = torch.zeros_like(noise)[:, :1]
+ else:
+ mask = 1.0 - mask
+ mask = utils.common_upscale(mask.to(device), noise.shape[-1], noise.shape[-2], "bilinear", "center")
+ if mask.shape[-3] < noise.shape[-3]:
+ mask = torch.nn.functional.pad(mask, (0, 0, 0, 0, 0, noise.shape[-3] - mask.shape[-3]), mode='constant', value=0)
+ mask = utils.resize_to_batch_size(mask, noise.shape[0])
+
+ return torch.cat((image, mask), dim=1)
+
+ def extra_conds(self, **kwargs):
+ out = super().extra_conds(**kwargs)
+ attention_mask = kwargs.get("attention_mask", None)
+ if attention_mask is not None:
+ if torch.numel(attention_mask) != attention_mask.sum():
+ out['attention_mask'] = comfy.conds.CONDRegular(attention_mask)
+ cross_attn = kwargs.get("cross_attn", None)
+ if cross_attn is not None:
+ out['c_crossattn'] = comfy.conds.CONDRegular(cross_attn)
+
+ conditioning_byt5small = kwargs.get("conditioning_byt5small", None)
+ if conditioning_byt5small is not None:
+ out['txt_byt5'] = comfy.conds.CONDRegular(conditioning_byt5small)
+
+ guidance = kwargs.get("guidance", 6.0)
+ if guidance is not None:
+ out['guidance'] = comfy.conds.CONDRegular(torch.FloatTensor([guidance]))
+
+ clip_vision_output = kwargs.get("clip_vision_output", None)
+ if clip_vision_output is not None:
+ out['clip_fea'] = comfy.conds.CONDRegular(clip_vision_output.last_hidden_state)
+
+ return out
+
+class HunyuanVideo15_SR_Distilled(HunyuanVideo15):
+ def __init__(self, model_config, model_type=ModelType.FLOW, device=None):
+ super().__init__(model_config, model_type, device=device)
+
+ def concat_cond(self, **kwargs):
+ noise = kwargs.get("noise", None)
+ image = kwargs.get("concat_latent_image", None)
+ noise_augmentation = kwargs.get("noise_augmentation", 0.0)
+ device = kwargs["device"]
+
+ if image is None:
+ image = torch.zeros([noise.shape[0], noise.shape[1] * 2 + 2, noise.shape[-3], noise.shape[-2], noise.shape[-1]], device=comfy.model_management.intermediate_device())
+ else:
+ image = utils.common_upscale(image.to(device), noise.shape[-1], noise.shape[-2], "bilinear", "center")
+ #image = self.process_latent_in(image) # scaling wasn't applied in reference code
+ image = utils.resize_to_batch_size(image, noise.shape[0])
+ lq_image_slice = slice(noise.shape[1] + 1, 2 * noise.shape[1] + 1)
+ if noise_augmentation > 0:
+ generator = torch.Generator(device="cpu")
+ generator.manual_seed(kwargs.get("seed", 0) - 10)
+ noise = torch.randn(image[:, lq_image_slice].shape, generator=generator, dtype=image.dtype, device="cpu").to(image.device)
+ image[:, lq_image_slice] = noise_augmentation * noise + min(1.0 - noise_augmentation, 0.75) * image[:, lq_image_slice]
+ else:
+ image[:, lq_image_slice] = 0.75 * image[:, lq_image_slice]
+ return image
+
+ def extra_conds(self, **kwargs):
+ out = super().extra_conds(**kwargs)
+ out['disable_time_r'] = comfy.conds.CONDConstant(False)
+ return out
+
+class Kandinsky5(BaseModel):
+ def __init__(self, model_config, model_type=ModelType.FLOW, device=None):
+ super().__init__(model_config, model_type, device=device, unet_model=comfy.ldm.kandinsky5.model.Kandinsky5)
+
+ def encode_adm(self, **kwargs):
+ return kwargs["pooled_output"]
+
+ def concat_cond(self, **kwargs):
+ noise = kwargs.get("noise", None)
+ device = kwargs["device"]
+ image = torch.zeros_like(noise)
+
+ mask = kwargs.get("concat_mask", kwargs.get("denoise_mask", None))
+ if mask is None:
+ mask = torch.zeros_like(noise)[:, :1]
+ else:
+ mask = 1.0 - mask
+ mask = utils.common_upscale(mask.to(device), noise.shape[-1], noise.shape[-2], "bilinear", "center")
+ if mask.shape[-3] < noise.shape[-3]:
+ mask = torch.nn.functional.pad(mask, (0, 0, 0, 0, 0, noise.shape[-3] - mask.shape[-3]), mode='constant', value=0)
+ mask = utils.resize_to_batch_size(mask, noise.shape[0])
+
+ return torch.cat((image, mask), dim=1)
+
+ def extra_conds(self, **kwargs):
+ out = super().extra_conds(**kwargs)
+ attention_mask = kwargs.get("attention_mask", None)
+ if attention_mask is not None:
+ out['attention_mask'] = comfy.conds.CONDRegular(attention_mask)
+ cross_attn = kwargs.get("cross_attn", None)
+ if cross_attn is not None:
+ out['c_crossattn'] = comfy.conds.CONDRegular(cross_attn)
+
+ time_dim_replace = kwargs.get("time_dim_replace", None)
+ if time_dim_replace is not None:
+ out['time_dim_replace'] = comfy.conds.CONDRegular(self.process_latent_in(time_dim_replace))
+
+ return out
+
+class Kandinsky5Image(Kandinsky5):
+ def __init__(self, model_config, model_type=ModelType.FLOW, device=None):
+ super().__init__(model_config, model_type, device=device)
+
+ def concat_cond(self, **kwargs):
+ return None
+
+class RT_DETR_v4(BaseModel):
+ def __init__(self, model_config, model_type=ModelType.FLOW, device=None):
+ super().__init__(model_config, model_type, device=device, unet_model=comfy.ldm.rt_detr.rtdetr_v4.RTv4)
+
+
+class DepthAnything3(BaseModel):
+ def __init__(self, model_config, model_type=ModelType.FLOW, device=None):
+ super().__init__(model_config, model_type, device=device,
+ unet_model=comfy.ldm.depth_anything_3.model.DepthAnything3Net)
+
+class ErnieImage(BaseModel):
+ def __init__(self, model_config, model_type=ModelType.FLOW, device=None):
+ super().__init__(model_config, model_type, device=device, unet_model=comfy.ldm.ernie.model.ErnieImageModel)
+
+ def extra_conds(self, **kwargs):
+ out = super().extra_conds(**kwargs)
+ cross_attn = kwargs.get("cross_attn", None)
+ if cross_attn is not None:
+ out['c_crossattn'] = comfy.conds.CONDRegular(cross_attn)
+ return out
+
+class SAM3(BaseModel):
+ def __init__(self, model_config, model_type=ModelType.FLOW, device=None):
+ super().__init__(model_config, model_type, device=device, unet_model=comfy.ldm.sam3.detector.SAM3Model)
+
+class CogVideoX(BaseModel):
+ def __init__(self, model_config, model_type=ModelType.V_PREDICTION_DDPM, image_to_video=False, device=None):
+ super().__init__(model_config, model_type, device=device, unet_model=comfy.ldm.cogvideo.model.CogVideoXTransformer3DModel)
+ self.image_to_video = image_to_video
+
+ def concat_cond(self, **kwargs):
+ noise = kwargs.get("noise", None)
+ # Detect extra channels needed (e.g. 32 - 16 = 16 for ref latent)
+ extra_channels = self.diffusion_model.in_channels - noise.shape[1]
+ if extra_channels == 0:
+ return None
+
+ image = kwargs.get("concat_latent_image", None)
+ device = kwargs["device"]
+
+ if image is None:
+ shape = list(noise.shape)
+ shape[1] = extra_channels
+ return torch.zeros(shape, dtype=noise.dtype, layout=noise.layout, device=noise.device)
+
+ latent_dim = self.latent_format.latent_channels
+ image = utils.common_upscale(image.to(device), noise.shape[-1], noise.shape[-2], "bilinear", "center")
+
+ if noise.ndim == 5 and image.ndim == 5:
+ if image.shape[-3] < noise.shape[-3]:
+ image = torch.nn.functional.pad(image, (0, 0, 0, 0, 0, noise.shape[-3] - image.shape[-3]), "constant", 0)
+ elif image.shape[-3] > noise.shape[-3]:
+ image = image[:, :, :noise.shape[-3]]
+
+ for i in range(0, image.shape[1], latent_dim):
+ image[:, i:i + latent_dim] = self.process_latent_in(image[:, i:i + latent_dim])
+ image = utils.resize_to_batch_size(image, noise.shape[0])
+
+ if image.shape[1] > extra_channels:
+ image = image[:, :extra_channels]
+ elif image.shape[1] < extra_channels:
+ repeats = extra_channels // image.shape[1]
+ remainder = extra_channels % image.shape[1]
+ parts = [image] * repeats
+ if remainder > 0:
+ parts.append(image[:, :remainder])
+ image = torch.cat(parts, dim=1)
+
+ return image
+
+ def extra_conds(self, **kwargs):
+ out = super().extra_conds(**kwargs)
+ # OFS embedding (CogVideoX 1.5 I2V), default 2.0 as used by SparkVSR
+ if self.diffusion_model.ofs_proj_dim is not None:
+ ofs = kwargs.get("ofs", None)
+ if ofs is None:
+ noise = kwargs.get("noise", None)
+ ofs = torch.full((noise.shape[0],), 2.0, device=noise.device, dtype=noise.dtype)
+ out['ofs'] = comfy.conds.CONDRegular(ofs)
+ return out
diff --git a/ComfyUI/comfy/model_detection.py b/ComfyUI/comfy/model_detection.py
new file mode 100644
index 0000000000000000000000000000000000000000..103680fd12d39395ed49258c04e0bcf49bcb6c56
--- /dev/null
+++ b/ComfyUI/comfy/model_detection.py
@@ -0,0 +1,1558 @@
+import json
+import comfy.memory_management
+import comfy.supported_models
+import comfy.supported_models_base
+import comfy.utils
+import math
+import logging
+import torch
+
+def count_blocks(state_dict_keys, prefix_string):
+ count = 0
+ while True:
+ c = False
+ for k in state_dict_keys:
+ if k.startswith(prefix_string.format(count)):
+ c = True
+ break
+ if c == False:
+ break
+ count += 1
+ return count
+
+def any_suffix_in(keys, prefix, main, suffix_list=[]):
+ for x in suffix_list:
+ if "{}{}{}".format(prefix, main, x) in keys:
+ return True
+ return False
+
+def calculate_transformer_depth(prefix, state_dict_keys, state_dict):
+ context_dim = None
+ use_linear_in_transformer = False
+
+ transformer_prefix = prefix + "1.transformer_blocks."
+ transformer_keys = sorted(list(filter(lambda a: a.startswith(transformer_prefix), state_dict_keys)))
+ if len(transformer_keys) > 0:
+ last_transformer_depth = count_blocks(state_dict_keys, transformer_prefix + '{}')
+ context_dim = state_dict['{}0.attn2.to_k.weight'.format(transformer_prefix)].shape[1]
+ use_linear_in_transformer = len(state_dict['{}1.proj_in.weight'.format(prefix)].shape) == 2
+ time_stack = '{}1.time_stack.0.attn1.to_q.weight'.format(prefix) in state_dict or '{}1.time_mix_blocks.0.attn1.to_q.weight'.format(prefix) in state_dict
+ time_stack_cross = '{}1.time_stack.0.attn2.to_q.weight'.format(prefix) in state_dict or '{}1.time_mix_blocks.0.attn2.to_q.weight'.format(prefix) in state_dict
+ return last_transformer_depth, context_dim, use_linear_in_transformer, time_stack, time_stack_cross
+ return None
+
+def detect_unet_config(state_dict, key_prefix, metadata=None):
+ state_dict_keys = list(state_dict.keys())
+
+ if '{}joint_blocks.0.context_block.attn.qkv.weight'.format(key_prefix) in state_dict_keys: #mmdit model
+ unet_config = {}
+ unet_config["in_channels"] = state_dict['{}x_embedder.proj.weight'.format(key_prefix)].shape[1]
+ patch_size = state_dict['{}x_embedder.proj.weight'.format(key_prefix)].shape[2]
+ unet_config["patch_size"] = patch_size
+ final_layer = '{}final_layer.linear.weight'.format(key_prefix)
+ if final_layer in state_dict:
+ unet_config["out_channels"] = state_dict[final_layer].shape[0] // (patch_size * patch_size)
+
+ unet_config["depth"] = state_dict['{}x_embedder.proj.weight'.format(key_prefix)].shape[0] // 64
+ unet_config["input_size"] = None
+ y_key = '{}y_embedder.mlp.0.weight'.format(key_prefix)
+ if y_key in state_dict_keys:
+ unet_config["adm_in_channels"] = state_dict[y_key].shape[1]
+
+ context_key = '{}context_embedder.weight'.format(key_prefix)
+ if context_key in state_dict_keys:
+ in_features = state_dict[context_key].shape[1]
+ out_features = state_dict[context_key].shape[0]
+ unet_config["context_embedder_config"] = {"target": "torch.nn.Linear", "params": {"in_features": in_features, "out_features": out_features}}
+ num_patches_key = '{}pos_embed'.format(key_prefix)
+ if num_patches_key in state_dict_keys:
+ num_patches = state_dict[num_patches_key].shape[1]
+ unet_config["num_patches"] = num_patches
+ unet_config["pos_embed_max_size"] = round(math.sqrt(num_patches))
+
+ rms_qk = '{}joint_blocks.0.context_block.attn.ln_q.weight'.format(key_prefix)
+ if rms_qk in state_dict_keys:
+ unet_config["qk_norm"] = "rms"
+
+ unet_config["pos_embed_scaling_factor"] = None #unused for inference
+ context_processor = '{}context_processor.layers.0.attn.qkv.weight'.format(key_prefix)
+ if context_processor in state_dict_keys:
+ unet_config["context_processor_layers"] = count_blocks(state_dict_keys, '{}context_processor.layers.'.format(key_prefix) + '{}.')
+ unet_config["x_block_self_attn_layers"] = []
+ for key in state_dict_keys:
+ if key.startswith('{}joint_blocks.'.format(key_prefix)) and key.endswith('.x_block.attn2.qkv.weight'):
+ layer = key[len('{}joint_blocks.'.format(key_prefix)):-len('.x_block.attn2.qkv.weight')]
+ unet_config["x_block_self_attn_layers"].append(int(layer))
+ return unet_config
+
+ if '{}clf.1.weight'.format(key_prefix) in state_dict_keys: #stable cascade
+ unet_config = {}
+ text_mapper_name = '{}clip_txt_mapper.weight'.format(key_prefix)
+ if text_mapper_name in state_dict_keys:
+ unet_config['stable_cascade_stage'] = 'c'
+ w = state_dict[text_mapper_name]
+ if w.shape[0] == 1536: #stage c lite
+ unet_config['c_cond'] = 1536
+ unet_config['c_hidden'] = [1536, 1536]
+ unet_config['nhead'] = [24, 24]
+ unet_config['blocks'] = [[4, 12], [12, 4]]
+ elif w.shape[0] == 2048: #stage c full
+ unet_config['c_cond'] = 2048
+ elif '{}clip_mapper.weight'.format(key_prefix) in state_dict_keys:
+ unet_config['stable_cascade_stage'] = 'b'
+ w = state_dict['{}down_blocks.1.0.channelwise.0.weight'.format(key_prefix)]
+ if w.shape[-1] == 640:
+ unet_config['c_hidden'] = [320, 640, 1280, 1280]
+ unet_config['nhead'] = [-1, -1, 20, 20]
+ unet_config['blocks'] = [[2, 6, 28, 6], [6, 28, 6, 2]]
+ unet_config['block_repeat'] = [[1, 1, 1, 1], [3, 3, 2, 2]]
+ elif w.shape[-1] == 576: #stage b lite
+ unet_config['c_hidden'] = [320, 576, 1152, 1152]
+ unet_config['nhead'] = [-1, 9, 18, 18]
+ unet_config['blocks'] = [[2, 4, 14, 4], [4, 14, 4, 2]]
+ unet_config['block_repeat'] = [[1, 1, 1, 1], [2, 2, 2, 2]]
+ return unet_config
+
+ if '{}transformer.rotary_pos_emb.inv_freq'.format(key_prefix) in state_dict_keys: #stable audio dit
+ unet_config = {}
+ unet_config["audio_model"] = "dit1.0"
+ unet_config["global_cond_dim"] = state_dict['{}to_global_embed.0.weight'.format(key_prefix)].shape[1]
+ cond_embed = state_dict['{}to_cond_embed.0.weight'.format(key_prefix)]
+ unet_config["project_cond_tokens"] = cond_embed.shape[0] != cond_embed.shape[1]
+ unet_config["embed_dim"] = state_dict['{}to_timestep_embed.0.weight'.format(key_prefix)].shape[0]
+ mem_tokens = state_dict.get('{}transformer.memory_tokens'.format(key_prefix), None)
+ to_qkv = state_dict.get('{}transformer.layers.0.self_attn.to_qkv.weight'.format(key_prefix), None)
+ differential = False
+ if to_qkv is not None:
+ if to_qkv.shape[0] == to_qkv.shape[1] * 5:
+ differential = True
+ if mem_tokens is not None:
+ unet_config["num_memory_tokens"] = mem_tokens.shape[0]
+ if '{}transformer.layers.0.self_attn.q_norm.weight'.format(key_prefix) in state_dict:
+ unet_config["attn_kwargs"] = {"qk_norm": "ln", "feat_scale": True}
+ rms_norm = state_dict.get('{}transformer.layers.0.self_attn.q_norm.gamma'.format(key_prefix), None)
+ if rms_norm is not None:
+ unet_config["attn_kwargs"] = {"qk_norm": "rms", "differential": differential}
+ unet_config["norm_type"] = "rms_norm"
+ unet_config["num_heads"] = unet_config["embed_dim"] // rms_norm.shape[0]
+
+ if '{}timestep_features.weight'.format(key_prefix) in state_dict:
+ unet_config["timestep_features_type"] = "learned"
+ else:
+ unet_config["timestep_features_type"] = "expo"
+
+ io_channels = state_dict['{}postprocess_conv.weight'.format(key_prefix)].shape[0]
+ unet_config["io_channels"] = io_channels
+ unet_config["input_concat_dim"] = state_dict['{}transformer.project_in.weight'.format(key_prefix)].shape[1] - io_channels
+
+ local_add_cond = state_dict.get('{}transformer.layers.0.to_local_embed.0.weight'.format(key_prefix), None)
+ if local_add_cond is not None:
+ unet_config["local_add_cond_dim"] = local_add_cond.shape[1]
+
+ global_cond_embed = state_dict.get('{}transformer.global_cond_embedder.0.weight'.format(key_prefix), None)
+ if global_cond_embed is not None:
+ unet_config["global_cond_shared_embed"] = True
+ unet_config["global_cond_type"] = "adaLN"
+
+ unet_config["depth"] = count_blocks(state_dict_keys, '{}transformer.layers.'.format(key_prefix) + '{}.')
+ return unet_config
+
+ if '{}double_layers.0.attn.w1q.weight'.format(key_prefix) in state_dict_keys: #aura flow dit
+ unet_config = {}
+ unet_config["max_seq"] = state_dict['{}positional_encoding'.format(key_prefix)].shape[1]
+ unet_config["cond_seq_dim"] = state_dict['{}cond_seq_linear.weight'.format(key_prefix)].shape[1]
+ double_layers = count_blocks(state_dict_keys, '{}double_layers.'.format(key_prefix) + '{}.')
+ single_layers = count_blocks(state_dict_keys, '{}single_layers.'.format(key_prefix) + '{}.')
+ unet_config["n_double_layers"] = double_layers
+ unet_config["n_layers"] = double_layers + single_layers
+ return unet_config
+
+ if '{}mlp_t5.0.weight'.format(key_prefix) in state_dict_keys: #Hunyuan DiT
+ unet_config = {}
+ unet_config["image_model"] = "hydit"
+ unet_config["depth"] = count_blocks(state_dict_keys, '{}blocks.'.format(key_prefix) + '{}.')
+ unet_config["hidden_size"] = state_dict['{}x_embedder.proj.weight'.format(key_prefix)].shape[0]
+ if unet_config["hidden_size"] == 1408 and unet_config["depth"] == 40: #DiT-g/2
+ unet_config["mlp_ratio"] = 4.3637
+ if state_dict['{}extra_embedder.0.weight'.format(key_prefix)].shape[1] == 3968:
+ unet_config["size_cond"] = True
+ unet_config["use_style_cond"] = True
+ unet_config["image_model"] = "hydit1"
+ return unet_config
+
+ if '{}txt_in.individual_token_refiner.blocks.0.norm1.weight'.format(key_prefix) in state_dict_keys: #Hunyuan Video
+ dit_config = {}
+ in_w = state_dict['{}img_in.proj.weight'.format(key_prefix)]
+ out_w = state_dict['{}final_layer.linear.weight'.format(key_prefix)]
+ dit_config["image_model"] = "hunyuan_video"
+ dit_config["in_channels"] = in_w.shape[1] #SkyReels img2video has 32 input channels
+ dit_config["patch_size"] = list(in_w.shape[2:])
+ dit_config["out_channels"] = out_w.shape[0] // math.prod(dit_config["patch_size"])
+ if any(s.startswith('{}vector_in.'.format(key_prefix)) for s in state_dict_keys):
+ dit_config["vec_in_dim"] = 768
+ else:
+ dit_config["vec_in_dim"] = None
+
+ if len(dit_config["patch_size"]) == 2:
+ dit_config["axes_dim"] = [64, 64]
+ else:
+ dit_config["axes_dim"] = [16, 56, 56]
+
+ if any(s.startswith('{}time_r_in.'.format(key_prefix)) for s in state_dict_keys):
+ dit_config["meanflow"] = True
+ else:
+ dit_config["meanflow"] = False
+
+ dit_config["context_in_dim"] = state_dict['{}txt_in.input_embedder.weight'.format(key_prefix)].shape[1]
+ dit_config["hidden_size"] = in_w.shape[0]
+ dit_config["mlp_ratio"] = 4.0
+ dit_config["num_heads"] = in_w.shape[0] // 128
+ dit_config["depth"] = count_blocks(state_dict_keys, '{}double_blocks.'.format(key_prefix) + '{}.')
+ dit_config["depth_single_blocks"] = count_blocks(state_dict_keys, '{}single_blocks.'.format(key_prefix) + '{}.')
+ dit_config["theta"] = 256
+ dit_config["qkv_bias"] = True
+ if '{}byt5_in.fc1.weight'.format(key_prefix) in state_dict:
+ dit_config["byt5"] = True
+ else:
+ dit_config["byt5"] = False
+
+ guidance_keys = list(filter(lambda a: a.startswith("{}guidance_in.".format(key_prefix)), state_dict_keys))
+ dit_config["guidance_embed"] = len(guidance_keys) > 0
+
+ # HunyuanVideo 1.5
+ if '{}cond_type_embedding.weight'.format(key_prefix) in state_dict_keys:
+ dit_config["use_cond_type_embedding"] = True
+ else:
+ dit_config["use_cond_type_embedding"] = False
+ if '{}vision_in.proj.0.weight'.format(key_prefix) in state_dict_keys:
+ dit_config["vision_in_dim"] = state_dict['{}vision_in.proj.0.weight'.format(key_prefix)].shape[0]
+ dit_config["meanflow_sum"] = True
+ else:
+ dit_config["vision_in_dim"] = None
+ dit_config["meanflow_sum"] = False
+ return dit_config
+
+ if any_suffix_in(state_dict_keys, key_prefix, 'double_blocks.0.img_attn.norm.key_norm.', ["weight", "scale"]) and ('{}img_in.weight'.format(key_prefix) in state_dict_keys or any_suffix_in(state_dict_keys, key_prefix, 'distilled_guidance_layer.norms.0.', ["weight", "scale"])): #Flux, Chroma or Chroma Radiance (has no img_in.weight)
+ dit_config = {}
+ if '{}double_stream_modulation_img.lin.weight'.format(key_prefix) in state_dict_keys:
+ dit_config["image_model"] = "flux2"
+ dit_config["axes_dim"] = [32, 32, 32, 32]
+ dit_config["num_heads"] = 48
+ dit_config["mlp_ratio"] = 3.0
+ dit_config["theta"] = 2000
+ dit_config["out_channels"] = 128
+ dit_config["global_modulation"] = True
+ dit_config["mlp_silu_act"] = True
+ dit_config["qkv_bias"] = False
+ dit_config["ops_bias"] = False
+ dit_config["default_ref_method"] = "index"
+ dit_config["ref_index_scale"] = 10.0
+ dit_config["txt_ids_dims"] = [3]
+ patch_size = 1
+ else:
+ dit_config["image_model"] = "flux"
+ dit_config["axes_dim"] = [16, 56, 56]
+ dit_config["num_heads"] = 24
+ dit_config["mlp_ratio"] = 4.0
+ dit_config["theta"] = 10000
+ dit_config["out_channels"] = 16
+ dit_config["qkv_bias"] = True
+ dit_config["txt_ids_dims"] = []
+ patch_size = 2
+
+ dit_config["in_channels"] = 16
+ dit_config["hidden_size"] = 3072
+ dit_config["context_in_dim"] = 4096
+
+ dit_config["patch_size"] = patch_size
+ in_key = "{}img_in.weight".format(key_prefix)
+ if in_key in state_dict_keys:
+ w = state_dict[in_key]
+ dit_config["in_channels"] = w.shape[1] // (patch_size * patch_size)
+ dit_config["hidden_size"] = w.shape[0]
+
+ txt_in_key = "{}txt_in.weight".format(key_prefix)
+ if txt_in_key in state_dict_keys:
+ w = state_dict[txt_in_key]
+ dit_config["context_in_dim"] = w.shape[1]
+ dit_config["hidden_size"] = w.shape[0]
+
+ vec_in_key = '{}vector_in.in_layer.weight'.format(key_prefix)
+ if vec_in_key in state_dict_keys:
+ dit_config["vec_in_dim"] = state_dict[vec_in_key].shape[1]
+ else:
+ dit_config["vec_in_dim"] = None
+
+ dit_config["num_heads"] = dit_config["hidden_size"] // sum(dit_config["axes_dim"])
+
+ dit_config["depth"] = count_blocks(state_dict_keys, '{}double_blocks.'.format(key_prefix) + '{}.')
+ dit_config["depth_single_blocks"] = count_blocks(state_dict_keys, '{}single_blocks.'.format(key_prefix) + '{}.')
+
+ if any_suffix_in(state_dict_keys, key_prefix, 'distilled_guidance_layer.0.norms.0.', ["weight", "scale"]) or any_suffix_in(state_dict_keys, key_prefix, 'distilled_guidance_layer.norms.0.', ["weight", "scale"]): #Chroma
+ dit_config["image_model"] = "chroma"
+ dit_config["in_channels"] = 64
+ dit_config["out_channels"] = 64
+ dit_config["in_dim"] = 64
+ dit_config["out_dim"] = 3072
+ dit_config["hidden_dim"] = 5120
+ dit_config["n_layers"] = 5
+
+ if any_suffix_in(state_dict_keys, key_prefix, 'nerf_blocks.0.norm.', ["weight", "scale"]): #Chroma Radiance
+ dit_config["image_model"] = "chroma_radiance"
+ dit_config["in_channels"] = 3
+ dit_config["out_channels"] = 3
+ dit_config["patch_size"] = state_dict.get('{}img_in_patch.weight'.format(key_prefix)).size(dim=-1)
+ dit_config["nerf_hidden_size"] = 64
+ dit_config["nerf_mlp_ratio"] = 4
+ dit_config["nerf_depth"] = 4
+ dit_config["nerf_max_freqs"] = 8
+ dit_config["nerf_tile_size"] = 512
+ dit_config["nerf_final_head_type"] = "conv" if any_suffix_in(state_dict_keys, key_prefix, 'nerf_final_layer_conv.norm.', ["weight", "scale"]) else "linear"
+ dit_config["nerf_embedder_dtype"] = torch.float32
+ if "{}__x0__".format(key_prefix) in state_dict_keys: # x0 pred
+ dit_config["use_x0"] = True
+ else:
+ dit_config["use_x0"] = False
+ if "{}__sequential__".format(key_prefix) in state_dict_keys: # sequential txt_ids
+ dit_config["use_sequential_txt_ids"] = True
+ else:
+ dit_config["use_sequential_txt_ids"] = False
+ else:
+ dit_config["guidance_embed"] = "{}guidance_in.in_layer.weight".format(key_prefix) in state_dict_keys
+ dit_config["yak_mlp"] = '{}double_blocks.0.img_mlp.gate_proj.weight'.format(key_prefix) in state_dict_keys
+ dit_config["txt_norm"] = any_suffix_in(state_dict_keys, key_prefix, 'txt_norm.', ["weight", "scale"])
+ if dit_config["yak_mlp"] and dit_config["txt_norm"]: # Ovis model
+ dit_config["txt_ids_dims"] = [1, 2]
+ if dit_config.get("context_in_dim") == 3584 and dit_config["vec_in_dim"] is None: # LongCat-Image
+ dit_config["txt_ids_dims"] = [1, 2]
+
+ return dit_config
+
+ if '{}t5_yproj.weight'.format(key_prefix) in state_dict_keys: #Genmo mochi preview
+ dit_config = {}
+ dit_config["image_model"] = "mochi_preview"
+ dit_config["depth"] = 48
+ dit_config["patch_size"] = 2
+ dit_config["num_heads"] = 24
+ dit_config["hidden_size_x"] = 3072
+ dit_config["hidden_size_y"] = 1536
+ dit_config["mlp_ratio_x"] = 4.0
+ dit_config["mlp_ratio_y"] = 4.0
+ dit_config["learn_sigma"] = False
+ dit_config["in_channels"] = 12
+ dit_config["qk_norm"] = True
+ dit_config["qkv_bias"] = False
+ dit_config["out_bias"] = True
+ dit_config["attn_drop"] = 0.0
+ dit_config["patch_embed_bias"] = True
+ dit_config["posenc_preserve_area"] = True
+ dit_config["timestep_mlp_bias"] = True
+ dit_config["attend_to_padding"] = False
+ dit_config["timestep_scale"] = 1000.0
+ dit_config["use_t5"] = True
+ dit_config["t5_feat_dim"] = 4096
+ dit_config["t5_token_length"] = 256
+ dit_config["rope_theta"] = 10000.0
+ return dit_config
+
+ if '{}adaln_single.emb.timestep_embedder.linear_1.bias'.format(key_prefix) in state_dict_keys and '{}pos_embed.proj.bias'.format(key_prefix) in state_dict_keys:
+ # PixArt diffusers
+ return None
+
+ if '{}video_patch_proj.weight'.format(key_prefix) in state_dict_keys and '{}audio_patch_proj.weight'.format(key_prefix) in state_dict_keys: # MiniMax H3
+ dit_config = {}
+ dit_config["image_model"] = "minimax_h3"
+ dit_config["num_layers"] = count_blocks(state_dict_keys, '{}blocks.'.format(key_prefix) + '{}.')
+ dit_config["token_refiner_num_layers"] = count_blocks(state_dict_keys, '{}token_refiner.blocks.'.format(key_prefix) + '{}.')
+ dit_config["hidden_size"] = state_dict['{}video_patch_proj.weight'.format(key_prefix)].shape[0]
+ dit_config["latents_dim"] = state_dict['{}final_layer.video_out.weight'.format(key_prefix)].shape[0] // 4 # patch 1x2x2
+ dit_config["audio_latents_dim"] = state_dict['{}final_layer.audio_out.weight'.format(key_prefix)].shape[0]
+ dit_config["attention_head_dim"] = state_dict['{}blocks.0.attn.q_norm.weight'.format(key_prefix)].shape[0]
+ qkv = state_dict['{}blocks.0.attn.qkv_proj.weight'.format(key_prefix)]
+ dit_config["num_attention_heads"] = qkv.shape[0] // (3 * dit_config["attention_head_dim"])
+ dit_config["ffn_hidden_size"] = state_dict['{}blocks.0.mlp.fc1.weight'.format(key_prefix)].shape[0] // 2
+ dit_config["text_dim"] = state_dict['{}condition_proj.weight'.format(key_prefix)].shape[1]
+ table_key = '{}adaln_t_table'.format(key_prefix)
+ if table_key in state_dict_keys:
+ # adaln shipped over a precomputed curve basis: the adaln linears span a small shared basis of the time-embedding curve (no time embedder)
+ table = state_dict[table_key].shape # [grid, k]
+ dit_config["adaln_curve_grid"] = table[0]
+ dit_config["time_embed_dim"] = table[1]
+ else:
+ te = state_dict['{}time_embedder.proj_in.weight'.format(key_prefix)]
+ dit_config["timestep_input_dim"] = te.shape[1]
+ dit_config["time_embed_hidden_size"] = te.shape[0]
+ dit_config["time_embed_dim"] = state_dict['{}time_embedder.proj_out.weight'.format(key_prefix)].shape[0]
+ dit_config["rope_inv_freq_len"] = state_dict['{}rope.inv_freq'.format(key_prefix)].shape[0]
+ if metadata is not None and "config" in metadata:
+ dit_config.update(json.loads(metadata["config"]).get("transformer", {}))
+ return dit_config
+
+ if '{}adaln_single.emb.timestep_embedder.linear_1.bias'.format(key_prefix) in state_dict_keys: #Lightricks ltxv
+ dit_config = {}
+ dit_config["image_model"] = "ltxav" if f'{key_prefix}audio_adaln_single.linear.weight' in state_dict_keys else "ltxv"
+ dit_config["num_layers"] = count_blocks(state_dict_keys, '{}transformer_blocks.'.format(key_prefix) + '{}.')
+ shape = state_dict['{}transformer_blocks.0.attn2.to_k.weight'.format(key_prefix)].shape
+ dit_config["attention_head_dim"] = shape[0] // 32
+ dit_config["cross_attention_dim"] = shape[1]
+ if metadata is not None and "config" in metadata:
+ dit_config.update(json.loads(metadata["config"]).get("transformer", {}))
+ return dit_config
+
+ if '{}genre_embedder.weight'.format(key_prefix) in state_dict_keys: #ACE-Step model
+ dit_config = {}
+ dit_config["audio_model"] = "ace"
+ dit_config["attention_head_dim"] = 128
+ dit_config["in_channels"] = 8
+ dit_config["inner_dim"] = 2560
+ dit_config["max_height"] = 16
+ dit_config["max_position"] = 32768
+ dit_config["max_width"] = 32768
+ dit_config["mlp_ratio"] = 2.5
+ dit_config["num_attention_heads"] = 20
+ dit_config["num_layers"] = 24
+ dit_config["out_channels"] = 8
+ dit_config["patch_size"] = [16, 1]
+ dit_config["rope_theta"] = 1000000.0
+ dit_config["speaker_embedding_dim"] = 512
+ dit_config["text_embedding_dim"] = 768
+
+ dit_config["ssl_encoder_depths"] = [8, 8]
+ dit_config["ssl_latent_dims"] = [1024, 768]
+ dit_config["ssl_names"] = ["mert", "m-hubert"]
+ dit_config["lyric_encoder_vocab_size"] = 6693
+ dit_config["lyric_hidden_size"] = 1024
+ return dit_config
+
+ if '{}t_block.1.weight'.format(key_prefix) in state_dict_keys: # PixArt
+ patch_size = 2
+ dit_config = {}
+ dit_config["num_heads"] = 16
+ dit_config["patch_size"] = patch_size
+ dit_config["hidden_size"] = 1152
+ dit_config["in_channels"] = 4
+ dit_config["depth"] = count_blocks(state_dict_keys, '{}blocks.'.format(key_prefix) + '{}.')
+
+ y_key = "{}y_embedder.y_embedding".format(key_prefix)
+ if y_key in state_dict_keys:
+ dit_config["model_max_length"] = state_dict[y_key].shape[0]
+
+ pe_key = "{}pos_embed".format(key_prefix)
+ if pe_key in state_dict_keys:
+ dit_config["input_size"] = int(math.sqrt(state_dict[pe_key].shape[1])) * patch_size
+ dit_config["pe_interpolation"] = dit_config["input_size"] // (512//8) # guess
+
+ ar_key = "{}ar_embedder.mlp.0.weight".format(key_prefix)
+ if ar_key in state_dict_keys:
+ dit_config["image_model"] = "pixart_alpha"
+ dit_config["micro_condition"] = True
+ else:
+ dit_config["image_model"] = "pixart_sigma"
+ dit_config["micro_condition"] = False
+ return dit_config
+
+ if '{}blocks.block0.blocks.0.block.attn.to_q.0.weight'.format(key_prefix) in state_dict_keys: # Cosmos
+ dit_config = {}
+ dit_config["image_model"] = "cosmos"
+ dit_config["max_img_h"] = 240
+ dit_config["max_img_w"] = 240
+ dit_config["max_frames"] = 128
+ concat_padding_mask = True
+ dit_config["in_channels"] = (state_dict['{}x_embedder.proj.1.weight'.format(key_prefix)].shape[1] // 4) - int(concat_padding_mask)
+ dit_config["out_channels"] = 16
+ dit_config["patch_spatial"] = 2
+ dit_config["patch_temporal"] = 1
+ dit_config["model_channels"] = state_dict['{}blocks.block0.blocks.0.block.attn.to_q.0.weight'.format(key_prefix)].shape[0]
+ dit_config["block_config"] = "FA-CA-MLP"
+ dit_config["concat_padding_mask"] = concat_padding_mask
+ dit_config["pos_emb_cls"] = "rope3d"
+ dit_config["pos_emb_learnable"] = False
+ dit_config["pos_emb_interpolation"] = "crop"
+ dit_config["block_x_format"] = "THWBD"
+ dit_config["affline_emb_norm"] = True
+ dit_config["use_adaln_lora"] = True
+ dit_config["adaln_lora_dim"] = 256
+
+ if dit_config["model_channels"] == 4096:
+ # 7B
+ dit_config["num_blocks"] = 28
+ dit_config["num_heads"] = 32
+ dit_config["extra_per_block_abs_pos_emb"] = True
+ dit_config["rope_h_extrapolation_ratio"] = 1.0
+ dit_config["rope_w_extrapolation_ratio"] = 1.0
+ dit_config["rope_t_extrapolation_ratio"] = 2.0
+ dit_config["extra_per_block_abs_pos_emb_type"] = "learnable"
+ else: # 5120
+ # 14B
+ dit_config["num_blocks"] = 36
+ dit_config["num_heads"] = 40
+ dit_config["extra_per_block_abs_pos_emb"] = True
+ dit_config["rope_h_extrapolation_ratio"] = 2.0
+ dit_config["rope_w_extrapolation_ratio"] = 2.0
+ dit_config["rope_t_extrapolation_ratio"] = 2.0
+ dit_config["extra_h_extrapolation_ratio"] = 2.0
+ dit_config["extra_w_extrapolation_ratio"] = 2.0
+ dit_config["extra_t_extrapolation_ratio"] = 2.0
+ dit_config["extra_per_block_abs_pos_emb_type"] = "learnable"
+ return dit_config
+
+ # PiD (Pixel Diffusion Decoder). Must check BEFORE plain PixelDiT_T2I.
+ _lq_w_key = '{}lq_proj.latent_proj.0.weight'.format(key_prefix)
+ if _lq_w_key in state_dict_keys:
+ latent_proj_in_channels = int(state_dict[_lq_w_key].shape[1])
+ hidden_dim = int(state_dict[_lq_w_key].shape[0])
+ _gate_prefix = '{}lq_proj.gate_modules.'.format(key_prefix)
+ num_gates = len({k[len(_gate_prefix):].split('.')[0]
+ for k in state_dict_keys if k.startswith(_gate_prefix)})
+ pid_v1_5 = '{}lq_proj.pit_head.weight'.format(key_prefix) in state_dict_keys
+ dit_config = {"image_model": "pid",
+ "lq_hidden_dim": hidden_dim}
+ if num_gates > 0:
+ dit_config["lq_interval"] = (14 + num_gates - 1) // num_gates
+ if pid_v1_5:
+ pid_v1_5_variants = {
+ 16: { # Flux and QwenImage
+ "lq_latent_channels": 16,
+ "latent_spatial_down_factor": 8,
+ "lq_latent_unpatchify_factor": 1,
+ },
+ 32: { # Flux2 after 2x latent unpatchify
+ "lq_latent_channels": 128,
+ "latent_spatial_down_factor": 16,
+ "lq_latent_unpatchify_factor": 2,
+ },
+ }
+ variant = pid_v1_5_variants.get(latent_proj_in_channels)
+ if variant is None:
+ raise ValueError(f"Unsupported PiD v1.5 latent projection with {latent_proj_in_channels} input channels")
+ gate_weight = state_dict['{}lq_proj.gate_modules.0.content_proj.weight'.format(key_prefix)]
+ dit_config.update(variant)
+ dit_config.update({
+ "lq_conv_padding_mode": "replicate",
+ "lq_gate_per_token": gate_weight.shape[0] == 1,
+ "pit_lq_inject": True,
+ "rope_ref_h": 2048,
+ "rope_ref_w": 2048,
+ })
+ else:
+ dit_config.update({
+ "lq_latent_channels": latent_proj_in_channels,
+ "latent_spatial_down_factor": 16 if latent_proj_in_channels >= 64 else 8,
+ })
+ return dit_config
+
+ if '{}core.pixel_embedder.proj.weight'.format(key_prefix) in state_dict_keys: # PixelDiT T2I
+ return {"image_model": "pixeldit_t2i"}
+
+ if '{}cap_embedder.1.weight'.format(key_prefix) in state_dict_keys and '{}noise_refiner.0.attention.k_norm.weight'.format(key_prefix) in state_dict_keys: # Lumina 2
+ dit_config = {}
+ dit_config["image_model"] = "lumina2"
+ dit_config["patch_size"] = 2
+ dit_config["in_channels"] = 16
+ w = state_dict['{}cap_embedder.1.weight'.format(key_prefix)]
+ dit_config["dim"] = w.shape[0]
+ dit_config["cap_feat_dim"] = w.shape[1]
+ dit_config["n_layers"] = count_blocks(state_dict_keys, '{}layers.'.format(key_prefix) + '{}.')
+ dit_config["qk_norm"] = True
+
+ if dit_config["dim"] == 2304: # Original Lumina 2
+ dit_config["n_heads"] = 24
+ dit_config["n_kv_heads"] = 8
+ dit_config["axes_dims"] = [32, 32, 32]
+ dit_config["axes_lens"] = [300, 512, 512]
+ dit_config["rope_theta"] = 10000.0
+ dit_config["ffn_dim_multiplier"] = 4.0
+ ctd_weight = state_dict.get('{}clip_text_pooled_proj.0.weight'.format(key_prefix), None)
+ if ctd_weight is not None: # NewBie
+ dit_config["clip_text_dim"] = ctd_weight.shape[0]
+ # NewBie also sets axes_lens = [1024, 512, 512] but it's not used in ComfyUI
+ elif dit_config["dim"] == 3840: # Z image
+ dit_config["n_heads"] = 30
+ dit_config["n_kv_heads"] = 30
+ dit_config["axes_dims"] = [32, 48, 48]
+ dit_config["axes_lens"] = [1536, 512, 512]
+ dit_config["rope_theta"] = 256.0
+ dit_config["ffn_dim_multiplier"] = (8.0 / 3.0)
+ dit_config["z_image_modulation"] = True
+ dit_config["time_scale"] = 1000.0
+ try:
+ dit_config["allow_fp16"] = torch.std(state_dict['{}layers.{}.ffn_norm1.weight'.format(key_prefix, dit_config["n_layers"] - 2)], unbiased=False).item() < 0.42
+ except Exception:
+ pass
+ if '{}cap_pad_token'.format(key_prefix) in state_dict_keys:
+ dit_config["pad_tokens_multiple"] = 32
+ sig_weight = state_dict.get('{}siglip_embedder.0.weight'.format(key_prefix), None)
+ if sig_weight is not None:
+ dit_config["siglip_feat_dim"] = sig_weight.shape[0]
+
+ dec_cond_key = '{}dec_net.cond_embed.weight'.format(key_prefix)
+ if dec_cond_key in state_dict_keys: # pixel-space variant
+ dit_config["image_model"] = "zimage_pixel"
+ # patch_size and in_channels are derived from x_embedder:
+ # x_embedder: Linear(patch_size * patch_size * in_channels, dim)
+ # The decoder also receives the full flat patch, so decoder_in_channels = x_embedder input dim.
+ x_emb_in = state_dict['{}x_embedder.weight'.format(key_prefix)].shape[1]
+ dec_out = state_dict['{}dec_net.final_layer.linear.weight'.format(key_prefix)].shape[0]
+ # patch_size: infer from decoder final layer output matching x_embedder input
+ # in_channels: infer from dec_net input_embedder (in_features = dec_in_ch + max_freqs^2)
+ embedder_w = state_dict['{}dec_net.input_embedder.embedder.0.weight'.format(key_prefix)]
+ dec_in_ch = dec_out # decoder in == decoder out (same pixel space)
+ dit_config["patch_size"] = round((x_emb_in / 3) ** 0.5) # assume RGB (in_channels=3)
+ dit_config["in_channels"] = 3
+ dit_config["decoder_in_channels"] = dec_in_ch
+ dit_config["decoder_hidden_size"] = state_dict[dec_cond_key].shape[0]
+ dit_config["decoder_num_res_blocks"] = count_blocks(
+ state_dict_keys, '{}dec_net.res_blocks.'.format(key_prefix) + '{}.'
+ )
+ dit_config["decoder_max_freqs"] = int((embedder_w.shape[1] - dec_in_ch) ** 0.5)
+ if '{}__x0__'.format(key_prefix) in state_dict_keys:
+ dit_config["use_x0"] = True
+
+ return dit_config
+
+ if '{}blocks.0.norm1.linear.weight'.format(key_prefix) in state_dict_keys: # CogVideoX
+ dit_config = {}
+ dit_config["image_model"] = "cogvideox"
+
+ # Extract config from weight shapes
+ norm1_weight = state_dict['{}blocks.0.norm1.linear.weight'.format(key_prefix)]
+ time_embed_dim = norm1_weight.shape[1]
+ dim = norm1_weight.shape[0] // 6
+
+ dit_config["num_attention_heads"] = dim // 64
+ dit_config["attention_head_dim"] = 64
+ dit_config["time_embed_dim"] = time_embed_dim
+ dit_config["num_layers"] = count_blocks(state_dict_keys, '{}blocks.'.format(key_prefix) + '{}.')
+
+ # Detect in_channels from patch_embed
+ patch_proj_key = '{}patch_embed.proj.weight'.format(key_prefix)
+ if patch_proj_key in state_dict_keys:
+ w = state_dict[patch_proj_key]
+ if w.ndim == 4:
+ # Conv2d: [out, in, kh, kw] — CogVideoX 1.0
+ dit_config["in_channels"] = w.shape[1]
+ dit_config["patch_size"] = w.shape[2]
+ elif w.ndim == 2:
+ # Linear: [out, in_channels * patch_size * patch_size * patch_size_t] — CogVideoX 1.5
+ dit_config["patch_size"] = 2
+ dit_config["patch_size_t"] = 2
+ dit_config["in_channels"] = w.shape[1] // (2 * 2 * 2) # 256 // 8 = 32
+
+ text_proj_key = '{}patch_embed.text_proj.weight'.format(key_prefix)
+ if text_proj_key in state_dict_keys:
+ dit_config["text_embed_dim"] = state_dict[text_proj_key].shape[1]
+
+ # Detect OFS embedding
+ ofs_key = '{}ofs_embedding_linear_1.weight'.format(key_prefix)
+ if ofs_key in state_dict_keys:
+ dit_config["ofs_embed_dim"] = state_dict[ofs_key].shape[1]
+
+ # Detect positional embedding type
+ pos_key = '{}patch_embed.pos_embedding'.format(key_prefix)
+ if pos_key in state_dict_keys:
+ dit_config["use_learned_positional_embeddings"] = True
+ dit_config["use_rotary_positional_embeddings"] = False
+ else:
+ dit_config["use_learned_positional_embeddings"] = False
+ dit_config["use_rotary_positional_embeddings"] = True
+
+ return dit_config
+
+ seedvr2_7b_separate_key = "{}blocks.35.mlp.vid.proj_out.weight".format(key_prefix)
+ if seedvr2_7b_separate_key in state_dict_keys and state_dict[seedvr2_7b_separate_key].shape[0] == 3072: # seedvr2 7b
+ dit_config = {}
+ dit_config["image_model"] = "seedvr2"
+ dit_config["vid_dim"] = 3072
+ dit_config["heads"] = 24
+ dit_config["num_layers"] = 36
+ # This checkpoint uses separate vid/txt MMModule keys in every block.
+ dit_config["mm_layers"] = 36
+ dit_config["norm_eps"] = 1e-5
+ dit_config["rope_type"] = "rope3d"
+ dit_config["rope_dim"] = 64
+ dit_config["mlp_type"] = "normal"
+ return dit_config
+ if "{}blocks.35.mlp.all.proj_in_gate.weight".format(key_prefix) in state_dict_keys: # seedvr2 7b
+ dit_config = {}
+ dit_config["image_model"] = "seedvr2"
+ dit_config["vid_dim"] = 3072
+ dit_config["heads"] = 24
+ dit_config["num_layers"] = 36
+ # This checkpoint uses shared all.* MMModule keys after the initial blocks.
+ dit_config["mm_layers"] = 10
+ dit_config["norm_eps"] = 1e-5
+ dit_config["rope_type"] = "rope3d"
+ dit_config["rope_dim"] = 64
+ dit_config["mlp_type"] = "swiglu"
+ return dit_config
+ if "{}blocks.31.mlp.all.proj_in_gate.weight".format(key_prefix) in state_dict_keys: # seedvr2 3b
+ dit_config = {}
+ dit_config["image_model"] = "seedvr2"
+ dit_config["vid_dim"] = 2560
+ dit_config["heads"] = 20
+ dit_config["num_layers"] = 32
+ dit_config["norm_eps"] = 1.0e-05
+ dit_config["mlp_type"] = "swiglu"
+ dit_config["vid_out_norm"] = True
+ return dit_config
+
+ if '{}head.modulation'.format(key_prefix) in state_dict_keys: # Wan 2.1
+ dit_config = {}
+ dit_config["image_model"] = "wan2.1"
+ dim = state_dict['{}head.modulation'.format(key_prefix)].shape[-1]
+ out_dim = state_dict['{}head.head.weight'.format(key_prefix)].shape[0] // 4
+ dit_config["dim"] = dim
+ dit_config["out_dim"] = out_dim
+ dit_config["num_heads"] = dim // 128
+ dit_config["ffn_dim"] = state_dict['{}blocks.0.ffn.0.weight'.format(key_prefix)].shape[0]
+ dit_config["num_layers"] = count_blocks(state_dict_keys, '{}blocks.'.format(key_prefix) + '{}.')
+ dit_config["patch_size"] = (1, 2, 2)
+ dit_config["freq_dim"] = 256
+ dit_config["window_size"] = (-1, -1)
+ dit_config["qk_norm"] = True
+ dit_config["cross_attn_norm"] = True
+ dit_config["eps"] = 1e-6
+ dit_config["in_dim"] = state_dict['{}patch_embedding.weight'.format(key_prefix)].shape[1]
+ if '{}vace_patch_embedding.weight'.format(key_prefix) in state_dict_keys:
+ dit_config["model_type"] = "vace"
+ dit_config["vace_in_dim"] = state_dict['{}vace_patch_embedding.weight'.format(key_prefix)].shape[1]
+ dit_config["vace_layers"] = count_blocks(state_dict_keys, '{}vace_blocks.'.format(key_prefix) + '{}.')
+ elif '{}control_adapter.conv.weight'.format(key_prefix) in state_dict_keys:
+ if '{}img_emb.proj.0.bias'.format(key_prefix) in state_dict_keys:
+ dit_config["model_type"] = "camera"
+ else:
+ dit_config["model_type"] = "camera_2.2"
+ elif '{}casual_audio_encoder.encoder.final_linear.weight'.format(key_prefix) in state_dict_keys:
+ dit_config["model_type"] = "s2v"
+ elif '{}audio_proj.audio_proj_glob_1.layer.bias'.format(key_prefix) in state_dict_keys:
+ dit_config["model_type"] = "humo"
+ elif '{}face_adapter.fuser_blocks.0.k_norm.weight'.format(key_prefix) in state_dict_keys:
+ dit_config["model_type"] = "animate"
+ elif '{}patch_embedding_mask.weight'.format(key_prefix) in state_dict_keys:
+ dit_config["model_type"] = "scail2"
+ elif '{}patch_embedding_pose.weight'.format(key_prefix) in state_dict_keys:
+ dit_config["model_type"] = "scail"
+ elif '{}patch_embedding_global.weight'.format(key_prefix) in state_dict_keys:
+ dit_config["model_type"] = "wandancer"
+ else:
+ if '{}img_emb.proj.0.bias'.format(key_prefix) in state_dict_keys:
+ dit_config["model_type"] = "i2v"
+ else:
+ dit_config["model_type"] = "t2v"
+ flf_weight = state_dict.get('{}img_emb.emb_pos'.format(key_prefix))
+ if flf_weight is not None:
+ dit_config["flf_pos_embed_token_number"] = flf_weight.shape[1]
+
+ ref_conv_weight = state_dict.get('{}ref_conv.weight'.format(key_prefix))
+ if ref_conv_weight is not None:
+ dit_config["in_dim_ref_conv"] = ref_conv_weight.shape[1]
+
+ if metadata is not None and "config" in metadata:
+ dit_config.update(json.loads(metadata["config"]).get("transformer", {}))
+
+ return dit_config
+
+ if '{}latent_in.weight'.format(key_prefix) in state_dict_keys: # Hunyuan 3D
+ in_shape = state_dict['{}latent_in.weight'.format(key_prefix)].shape
+ dit_config = {}
+ dit_config["image_model"] = "hunyuan3d2"
+ dit_config["in_channels"] = in_shape[1]
+ dit_config["context_in_dim"] = state_dict['{}cond_in.weight'.format(key_prefix)].shape[1]
+ dit_config["hidden_size"] = in_shape[0]
+ dit_config["mlp_ratio"] = 4.0
+ dit_config["num_heads"] = 16
+ dit_config["depth"] = count_blocks(state_dict_keys, '{}double_blocks.'.format(key_prefix) + '{}.')
+ dit_config["depth_single_blocks"] = count_blocks(state_dict_keys, '{}single_blocks.'.format(key_prefix) + '{}.')
+ dit_config["qkv_bias"] = True
+ dit_config["guidance_embed"] = "{}guidance_in.in_layer.weight".format(key_prefix) in state_dict_keys
+ return dit_config
+
+ if f"{key_prefix}t_embedder.mlp.2.weight" in state_dict_keys and f"{key_prefix}blocks.0.attn1.k_norm.weight" in state_dict_keys: # Hunyuan 3D 2.1
+ dit_config = {}
+ dit_config["image_model"] = "hunyuan3d2_1"
+ dit_config["in_channels"] = state_dict[f"{key_prefix}x_embedder.weight"].shape[1]
+ dit_config["context_dim"] = 1024
+ dit_config["hidden_size"] = state_dict[f"{key_prefix}x_embedder.weight"].shape[0]
+ dit_config["mlp_ratio"] = 4.0
+ dit_config["num_heads"] = 16
+ dit_config["depth"] = count_blocks(state_dict_keys, f"{key_prefix}blocks.{{}}")
+ dit_config["qkv_bias"] = False
+ dit_config["guidance_cond_proj_dim"] = None#f"{key_prefix}t_embedder.cond_proj.weight" in state_dict_keys
+ return dit_config
+
+ if '{}cam_out_layer.weight'.format(key_prefix) in state_dict_keys and '{}repo_layers.0.final_map.weight'.format(key_prefix) in state_dict_keys: # TripoSplat
+ return {"image_model": "triposplat"}
+
+ if '{}t_embedder1.mlp.0.weight'.format(key_prefix) in state_dict_keys and '{}x_embedder.proj1.weight'.format(key_prefix) in state_dict_keys: # HiDream-O1
+ return {"image_model": "hidream_o1"}
+
+ if '{}caption_projection.0.linear.weight'.format(key_prefix) in state_dict_keys: # HiDream
+ dit_config = {}
+ dit_config["image_model"] = "hidream"
+ dit_config["attention_head_dim"] = 128
+ dit_config["axes_dims_rope"] = [64, 32, 32]
+ dit_config["caption_channels"] = [4096, 4096]
+ dit_config["max_resolution"] = [128, 128]
+ dit_config["in_channels"] = 16
+ dit_config["llama_layers"] = [0, 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, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31, 31]
+ dit_config["num_attention_heads"] = 20
+ dit_config["num_routed_experts"] = 4
+ dit_config["num_activated_experts"] = 2
+ dit_config["num_layers"] = 16
+ dit_config["num_single_layers"] = 32
+ dit_config["out_channels"] = 16
+ dit_config["patch_size"] = 2
+ dit_config["text_emb_dim"] = 2048
+ return dit_config
+
+ if '{}blocks.0.mlp.layer1.weight'.format(key_prefix) in state_dict_keys: # Cosmos predict2
+ dit_config = {}
+ dit_config["image_model"] = "cosmos_predict2"
+ if "{}llm_adapter.blocks.0.cross_attn.q_proj.weight".format(key_prefix) in state_dict_keys:
+ dit_config["image_model"] = "anima"
+ dit_config["max_img_h"] = 240
+ dit_config["max_img_w"] = 240
+ dit_config["max_frames"] = 128
+ concat_padding_mask = True
+ dit_config["in_channels"] = (state_dict['{}x_embedder.proj.1.weight'.format(key_prefix)].shape[1] // 4) - int(concat_padding_mask)
+ dit_config["out_channels"] = 16
+ dit_config["patch_spatial"] = 2
+ dit_config["patch_temporal"] = 1
+ dit_config["model_channels"] = state_dict['{}x_embedder.proj.1.weight'.format(key_prefix)].shape[0]
+ dit_config["concat_padding_mask"] = concat_padding_mask
+ dit_config["crossattn_emb_channels"] = 1024
+ dit_config["pos_emb_cls"] = "rope3d"
+ dit_config["pos_emb_learnable"] = True
+ dit_config["pos_emb_interpolation"] = "crop"
+ dit_config["min_fps"] = 1
+ dit_config["max_fps"] = 30
+
+ dit_config["use_adaln_lora"] = True
+ dit_config["adaln_lora_dim"] = 256
+ if dit_config["model_channels"] == 2048:
+ dit_config["num_blocks"] = 28
+ dit_config["num_heads"] = 16
+ elif dit_config["model_channels"] == 5120:
+ dit_config["num_blocks"] = 36
+ dit_config["num_heads"] = 40
+
+ if dit_config["in_channels"] == 16:
+ dit_config["extra_per_block_abs_pos_emb"] = False
+ dit_config["rope_h_extrapolation_ratio"] = 4.0
+ dit_config["rope_w_extrapolation_ratio"] = 4.0
+ dit_config["rope_t_extrapolation_ratio"] = 1.0
+ elif dit_config["in_channels"] == 17: # img to video
+ if dit_config["model_channels"] == 2048:
+ dit_config["extra_per_block_abs_pos_emb"] = False
+ dit_config["rope_h_extrapolation_ratio"] = 3.0
+ dit_config["rope_w_extrapolation_ratio"] = 3.0
+ dit_config["rope_t_extrapolation_ratio"] = 1.0
+ elif dit_config["model_channels"] == 5120:
+ dit_config["rope_h_extrapolation_ratio"] = 2.0
+ dit_config["rope_w_extrapolation_ratio"] = 2.0
+ dit_config["rope_t_extrapolation_ratio"] = 0.8333333333333334
+
+ dit_config["extra_h_extrapolation_ratio"] = 1.0
+ dit_config["extra_w_extrapolation_ratio"] = 1.0
+ dit_config["extra_t_extrapolation_ratio"] = 1.0
+ dit_config["rope_enable_fps_modulation"] = False
+
+ return dit_config
+
+ if '{}double_stream_layers.0.img_instruct_attn.processor.img_to_q.weight'.format(key_prefix) in state_dict_keys: # Boogu-Image (OmniGen2 derivative + dual-stream stage)
+ dit_config = {}
+ dit_config["image_model"] = "boogu"
+ dit_config["hidden_size"] = state_dict['{}x_embedder.weight'.format(key_prefix)].shape[0]
+ dit_config["num_layers"] = count_blocks(state_dict_keys, '{}single_stream_layers.'.format(key_prefix) + '{}.')
+ dit_config["num_double_stream_layers"] = count_blocks(state_dict_keys, '{}double_stream_layers.'.format(key_prefix) + '{}.')
+ dit_config["num_refiner_layers"] = count_blocks(state_dict_keys, '{}noise_refiner.'.format(key_prefix) + '{}.')
+ dit_config["instruction_feat_dim"] = state_dict['{}time_caption_embed.caption_embedder.0.weight'.format(key_prefix)].shape[0]
+ return dit_config
+
+ if '{}time_caption_embed.timestep_embedder.linear_1.bias'.format(key_prefix) in state_dict_keys: # Omnigen2
+ dit_config = {}
+ dit_config["image_model"] = "omnigen2"
+ dit_config["axes_dim_rope"] = [40, 40, 40]
+ dit_config["axes_lens"] = [1024, 1664, 1664]
+ dit_config["ffn_dim_multiplier"] = None
+ dit_config["hidden_size"] = 2520
+ dit_config["in_channels"] = 16
+ dit_config["multiple_of"] = 256
+ dit_config["norm_eps"] = 1e-05
+ dit_config["num_attention_heads"] = 21
+ dit_config["num_kv_heads"] = 7
+ dit_config["num_layers"] = 32
+ dit_config["num_refiner_layers"] = 2
+ dit_config["out_channels"] = None
+ dit_config["patch_size"] = 2
+ dit_config["text_feat_dim"] = 2048
+ dit_config["timestep_scale"] = 1000.0
+ return dit_config
+
+ if '{}transformer_blocks.0.attn.norm_added_q.weight'.format(key_prefix) in state_dict_keys \
+ and '{}transformer_blocks.0.img_mlp.w1.weight'.format(key_prefix) in state_dict_keys: # Lens
+ img_in_w = state_dict['{}img_in.weight'.format(key_prefix)]
+ proj_out_w = state_dict['{}proj_out.weight'.format(key_prefix)]
+ multi_layer = '{}txt_norm.0.weight'.format(key_prefix) in state_dict_keys
+ if multi_layer:
+ enc_hidden_dim = state_dict['{}txt_norm.0.weight'.format(key_prefix)].shape[0]
+ # Indices are TE-side; the DiT just consumes L layers in order.
+ selected_layer_index = tuple(range(count_blocks(state_dict_keys, '{}txt_norm.'.format(key_prefix) + '{}.')))
+ else:
+ enc_hidden_dim = state_dict['{}txt_norm.weight'.format(key_prefix)].shape[0]
+ selected_layer_index = (0,)
+
+ return {
+ "image_model": "lens",
+ "in_channels": img_in_w.shape[1],
+ "out_channels": proj_out_w.shape[0] // 4, # patch_size ** 2 (=2² default)
+ "num_layers": count_blocks(state_dict_keys, '{}transformer_blocks.'.format(key_prefix) + '{}.'),
+ "num_attention_heads": img_in_w.shape[0] // 64, # // attention_head_dim default
+ "enc_hidden_dim": enc_hidden_dim,
+ "multi_layer_encoder_feature": multi_layer,
+ "selected_layer_index": selected_layer_index,
+ }
+
+ if '{}txt_norm.weight'.format(key_prefix) in state_dict_keys and '{}proj_out.weight'.format(key_prefix) in state_dict_keys and state_dict['{}txt_norm.weight'.format(key_prefix)].shape[0] == 2560 and state_dict['{}proj_out.weight'.format(key_prefix)].shape[0] == 128: # Mage-Flow (Qwen Image txt_norm/proj_out are 3584/64)
+ dit_config = {}
+ dit_config["image_model"] = "mage_flow"
+ dit_config["in_channels"] = 128
+ dit_config["num_layers"] = count_blocks(state_dict_keys, '{}transformer_blocks.'.format(key_prefix) + '{}.')
+ return dit_config
+
+ if '{}txt_norm.weight'.format(key_prefix) in state_dict_keys: # Qwen Image
+ dit_config = {}
+ dit_config["image_model"] = "qwen_image"
+ dit_config["in_channels"] = state_dict['{}img_in.weight'.format(key_prefix)].shape[1]
+ dit_config["num_layers"] = count_blocks(state_dict_keys, '{}transformer_blocks.'.format(key_prefix) + '{}.')
+ if "{}__index_timestep_zero__".format(key_prefix) in state_dict_keys: # 2511
+ dit_config["default_ref_method"] = "index_timestep_zero"
+ if "{}time_text_embed.addition_t_embedding.weight".format(key_prefix) in state_dict_keys: # Layered
+ dit_config["use_additional_t_cond"] = True
+ dit_config["default_ref_method"] = "negative_index"
+ return dit_config
+
+ if '{}embed_image_indicator.weight'.format(key_prefix) in state_dict_keys: # Ideogram 4
+ dit_config = {}
+ dit_config["image_model"] = "ideogram4"
+ dit_config["in_channels"] = state_dict['{}input_proj.weight'.format(key_prefix)].shape[1]
+ dit_config["num_layers"] = count_blocks(state_dict_keys, '{}layers.'.format(key_prefix) + '{}.')
+ return dit_config
+
+ if '{}txtfusion.projector.weight'.format(key_prefix) in state_dict_keys: # Krea 2 (K2)
+ dit_config = {}
+ dit_config["image_model"] = "krea2"
+ head_dim = 128
+ first_w = state_dict['{}first.weight'.format(key_prefix)] # (features, channels*patch^2)
+ dit_config["features"] = first_w.shape[0]
+ dit_config["channels"] = first_w.shape[1] // (2 * 2) # patch=2
+ dit_config["patch"] = 2
+ dit_config["layers"] = count_blocks(state_dict_keys, '{}blocks.'.format(key_prefix) + '{}.')
+ dit_config["heads"] = state_dict['{}blocks.0.attn.wq.weight'.format(key_prefix)].shape[0] // head_dim
+ dit_config["kvheads"] = state_dict['{}blocks.0.attn.wk.weight'.format(key_prefix)].shape[0] // head_dim
+ dit_config["txtlayers"] = state_dict['{}txtfusion.projector.weight'.format(key_prefix)].shape[1]
+ dit_config["txtdim"] = state_dict['{}txtfusion.layerwise_blocks.0.prenorm.scale'.format(key_prefix)].shape[0]
+ return dit_config
+
+ if '{}visual_transformer_blocks.0.cross_attention.key_norm.weight'.format(key_prefix) in state_dict_keys: # Kandinsky 5
+ dit_config = {}
+ model_dim = state_dict['{}visual_embeddings.in_layer.bias'.format(key_prefix)].shape[0]
+ dit_config["model_dim"] = model_dim
+ if model_dim in [4096, 2560]: # pro video and lite image
+ dit_config["axes_dims"] = (32, 48, 48)
+ if model_dim == 2560: # lite image
+ dit_config["rope_scale_factor"] = (1.0, 1.0, 1.0)
+ elif model_dim == 1792: # lite video
+ dit_config["axes_dims"] = (16, 24, 24)
+ dit_config["time_dim"] = state_dict['{}time_embeddings.in_layer.bias'.format(key_prefix)].shape[0]
+ dit_config["image_model"] = "kandinsky5"
+ dit_config["ff_dim"] = state_dict['{}visual_transformer_blocks.0.feed_forward.in_layer.weight'.format(key_prefix)].shape[0]
+ dit_config["visual_embed_dim"] = state_dict['{}visual_embeddings.in_layer.weight'.format(key_prefix)].shape[1]
+ dit_config["num_text_blocks"] = count_blocks(state_dict_keys, '{}text_transformer_blocks.'.format(key_prefix) + '{}.')
+ dit_config["num_visual_blocks"] = count_blocks(state_dict_keys, '{}visual_transformer_blocks.'.format(key_prefix) + '{}.')
+ return dit_config
+
+ if '{}encoder.lyric_encoder.layers.0.input_layernorm.weight'.format(key_prefix) in state_dict_keys:
+ dit_config = {}
+ dit_config["audio_model"] = "ace1.5"
+ head_dim = 128
+ dit_config["hidden_size"] = state_dict['{}decoder.layers.0.self_attn_norm.weight'.format(key_prefix)].shape[0]
+ dit_config["intermediate_size"] = state_dict['{}decoder.layers.0.mlp.gate_proj.weight'.format(key_prefix)].shape[0]
+ dit_config["num_heads"] = state_dict['{}decoder.layers.0.self_attn.q_proj.weight'.format(key_prefix)].shape[0] // head_dim
+
+ dit_config["encoder_hidden_size"] = state_dict['{}encoder.lyric_encoder.layers.0.input_layernorm.weight'.format(key_prefix)].shape[0]
+ dit_config["encoder_num_heads"] = state_dict['{}encoder.lyric_encoder.layers.0.self_attn.q_proj.weight'.format(key_prefix)].shape[0] // head_dim
+ dit_config["encoder_intermediate_size"] = state_dict['{}encoder.lyric_encoder.layers.0.mlp.gate_proj.weight'.format(key_prefix)].shape[0]
+ dit_config["num_dit_layers"] = count_blocks(state_dict_keys, '{}decoder.layers.'.format(key_prefix) + '{}.')
+ return dit_config
+
+ if '{}encoder.pan_blocks.1.cv4.conv.weight'.format(key_prefix) in state_dict_keys: # RT-DETR_v4
+ dit_config = {}
+ dit_config["image_model"] = "RT_DETR_v4"
+ dit_config["enc_h"] = state_dict['{}encoder.pan_blocks.1.cv4.conv.weight'.format(key_prefix)].shape[0]
+ return dit_config
+
+ # Depth Anything 3 (repackaged to ComfyUI's native Dinov2Model layout via scripts/convert_da3.py)
+ if '{}backbone.embeddings.patch_embeddings.projection.weight'.format(key_prefix) in state_dict_keys:
+ dit_config = {}
+ dit_config["image_model"] = "DepthAnything3"
+
+ patch_w = state_dict['{}backbone.embeddings.patch_embeddings.projection.weight'.format(key_prefix)]
+ embed_dim = patch_w.shape[0]
+ depth = count_blocks(state_dict_keys, '{}backbone.encoder.layer.'.format(key_prefix) + '{}.')
+
+ # Backbone preset is determined by embed_dim (matches vits/vitb/vitl/vitg).
+ backbone_name = {384: "vits", 768: "vitb", 1024: "vitl", 1536: "vitg"}.get(embed_dim)
+ if backbone_name is None:
+ return None
+ dit_config["backbone_name"] = backbone_name
+
+ # Detect DA3 extensions on top of vanilla DINOv2.
+ has_camera_token = '{}backbone.embeddings.camera_token'.format(key_prefix) in state_dict_keys
+ # qk-norm shows up as `attention.q_norm.weight` on enabled blocks.
+ qknorm_indices = [
+ i for i in range(depth)
+ if '{}backbone.encoder.layer.{}.attention.q_norm.weight'.format(key_prefix, i) in state_dict_keys
+ ]
+ qknorm_start = qknorm_indices[0] if qknorm_indices else -1
+
+ # The DA3 main-series configs always set alt_start == qknorm_start == rope_start.
+ # cat_token=True is implied by the presence of camera_token.
+ if has_camera_token:
+ dit_config["alt_start"] = qknorm_start
+ dit_config["rope_start"] = qknorm_start
+ dit_config["qknorm_start"] = qknorm_start
+ dit_config["cat_token"] = True
+ else:
+ dit_config["alt_start"] = -1
+ dit_config["rope_start"] = -1
+ dit_config["qknorm_start"] = -1
+ dit_config["cat_token"] = False
+
+ # Detect head type and config.
+ has_aux = '{}head.scratch.refinenet1_aux.out_conv.weight'.format(key_prefix) in state_dict_keys
+ dit_config["head_dim_in"] = state_dict['{}head.projects.0.weight'.format(key_prefix)].shape[1]
+ dit_config["head_features"] = state_dict['{}head.scratch.refinenet1.out_conv.weight'.format(key_prefix)].shape[0]
+ dit_config["head_out_channels"] = [
+ state_dict['{}head.projects.{}.weight'.format(key_prefix, i)].shape[0]
+ for i in range(4)
+ ]
+ if has_aux:
+ # DualDPT: dim_in = 2 * embed_dim (because cat_token doubles token width).
+ dit_config["head_type"] = "dualdpt"
+ dit_config["head_output_dim"] = 2
+ dit_config["head_use_sky_head"] = False
+ else:
+ dit_config["head_type"] = "dpt"
+ dit_config["head_output_dim"] = state_dict[
+ '{}head.scratch.output_conv2.2.weight'.format(key_prefix)
+ ].shape[0]
+ dit_config["head_use_sky_head"] = (
+ '{}head.scratch.sky_output_conv2.0.weight'.format(key_prefix) in state_dict_keys
+ )
+
+ # out_layers: hard-coded per upstream YAML config (depth-aware default).
+ if depth >= 24:
+ # vitl: depths used vary between DA3-Large (DualDPT) and Mono/Metric (DPT).
+ if has_aux:
+ dit_config["out_layers"] = [11, 15, 19, 23]
+ else:
+ dit_config["out_layers"] = [4, 11, 17, 23]
+ else:
+ # vits/vitb: 12 blocks
+ dit_config["out_layers"] = [5, 7, 9, 11]
+
+ # Camera encoder/decoder presence (multi-view + pose path).
+ has_cam_enc = '{}cam_enc.token_norm.weight'.format(key_prefix) in state_dict_keys
+ has_cam_dec = '{}cam_dec.fc_t.weight'.format(key_prefix) in state_dict_keys
+ dit_config["has_cam_enc"] = has_cam_enc
+ dit_config["has_cam_dec"] = has_cam_dec
+ if has_cam_enc:
+ cam_enc_w = state_dict.get(
+ '{}cam_enc.pose_branch.fc2.weight'.format(key_prefix)
+ )
+ if cam_enc_w is not None:
+ dit_config["cam_dim_out"] = cam_enc_w.shape[0]
+ if has_cam_dec:
+ cam_dec_w = state_dict.get(
+ '{}cam_dec.fc_t.weight'.format(key_prefix)
+ )
+ if cam_dec_w is not None:
+ dit_config["cam_dec_dim_in"] = cam_dec_w.shape[1]
+ return dit_config
+
+ if '{}layers.0.mlp.linear_fc2.weight'.format(key_prefix) in state_dict_keys: # Ernie Image
+ dit_config = {}
+ dit_config["image_model"] = "ernie"
+ return dit_config
+
+ if 'detector.backbone.vision_backbone.trunk.blocks.0.attn.qkv.weight' in state_dict_keys: # SAM3 / SAM3.1
+ if 'detector.transformer.decoder.query_embed.weight' in state_dict_keys:
+ dit_config = {}
+ dit_config["image_model"] = "SAM3"
+ if 'detector.backbone.vision_backbone.propagation_convs.0.conv_1x1.weight' in state_dict_keys:
+ dit_config["image_model"] = "SAM31"
+ return dit_config
+
+ if (
+ '{}double_blocks.0.attn.img_attn_qkv.weight'.format(key_prefix) in state_dict_keys
+ and '{}double_blocks.0.attn.img_attn_q_norm.weight'.format(key_prefix) in state_dict_keys
+ and '{}condition_embedder.time_embedder.linear_1.weight'.format(key_prefix) in state_dict_keys
+ and '{}img_in.weight'.format(key_prefix) in state_dict_keys
+ and len(state_dict['{}img_in.weight'.format(key_prefix)].shape) == 5
+ ):
+ img_in = state_dict['{}img_in.weight'.format(key_prefix)]
+ head_dim = state_dict['{}double_blocks.0.attn.img_attn_q_norm.weight'.format(key_prefix)].shape[0]
+ return {
+ "image_model": "joyimage",
+ "in_channels": img_in.shape[1],
+ "hidden_size": img_in.shape[0],
+ "patch_size": list(img_in.shape[2:]),
+ "num_layers": count_blocks(state_dict_keys, '{}double_blocks.'.format(key_prefix) + '{}.'),
+ "num_attention_heads": img_in.shape[0] // head_dim,
+ "text_dim": 4096,
+ }
+
+ if '{}input_blocks.0.0.weight'.format(key_prefix) not in state_dict_keys:
+ return None
+
+ unet_config = {
+ "use_checkpoint": False,
+ "image_size": 32,
+ "use_spatial_transformer": True,
+ "legacy": False
+ }
+
+ y_input = '{}label_emb.0.0.weight'.format(key_prefix)
+ if y_input in state_dict_keys:
+ unet_config["num_classes"] = "sequential"
+ unet_config["adm_in_channels"] = state_dict[y_input].shape[1]
+ else:
+ unet_config["adm_in_channels"] = None
+
+ model_channels = state_dict['{}input_blocks.0.0.weight'.format(key_prefix)].shape[0]
+ in_channels = state_dict['{}input_blocks.0.0.weight'.format(key_prefix)].shape[1]
+
+ out_key = '{}out.2.weight'.format(key_prefix)
+ if out_key in state_dict:
+ out_channels = state_dict[out_key].shape[0]
+ else:
+ out_channels = 4
+
+ num_res_blocks = []
+ channel_mult = []
+ transformer_depth = []
+ transformer_depth_output = []
+ context_dim = None
+ use_linear_in_transformer = False
+
+ video_model = False
+ video_model_cross = False
+
+ current_res = 1
+ count = 0
+
+ last_res_blocks = 0
+ last_channel_mult = 0
+
+ input_block_count = count_blocks(state_dict_keys, '{}input_blocks'.format(key_prefix) + '.{}.')
+ for count in range(input_block_count):
+ prefix = '{}input_blocks.{}.'.format(key_prefix, count)
+ prefix_output = '{}output_blocks.{}.'.format(key_prefix, input_block_count - count - 1)
+
+ block_keys = sorted(list(filter(lambda a: a.startswith(prefix), state_dict_keys)))
+ if len(block_keys) == 0:
+ break
+
+ block_keys_output = sorted(list(filter(lambda a: a.startswith(prefix_output), state_dict_keys)))
+
+ if "{}0.op.weight".format(prefix) in block_keys: #new layer
+ num_res_blocks.append(last_res_blocks)
+ channel_mult.append(last_channel_mult)
+
+ current_res *= 2
+ last_res_blocks = 0
+ last_channel_mult = 0
+ out = calculate_transformer_depth(prefix_output, state_dict_keys, state_dict)
+ if out is not None:
+ transformer_depth_output.append(out[0])
+ else:
+ transformer_depth_output.append(0)
+ else:
+ res_block_prefix = "{}0.in_layers.0.weight".format(prefix)
+ if res_block_prefix in block_keys:
+ last_res_blocks += 1
+ last_channel_mult = state_dict["{}0.out_layers.3.weight".format(prefix)].shape[0] // model_channels
+
+ out = calculate_transformer_depth(prefix, state_dict_keys, state_dict)
+ if out is not None:
+ transformer_depth.append(out[0])
+ if context_dim is None:
+ context_dim = out[1]
+ use_linear_in_transformer = out[2]
+ video_model = out[3]
+ video_model_cross = out[4]
+ else:
+ transformer_depth.append(0)
+
+ res_block_prefix = "{}0.in_layers.0.weight".format(prefix_output)
+ if res_block_prefix in block_keys_output:
+ out = calculate_transformer_depth(prefix_output, state_dict_keys, state_dict)
+ if out is not None:
+ transformer_depth_output.append(out[0])
+ else:
+ transformer_depth_output.append(0)
+
+
+ num_res_blocks.append(last_res_blocks)
+ channel_mult.append(last_channel_mult)
+ if "{}middle_block.1.proj_in.weight".format(key_prefix) in state_dict_keys:
+ transformer_depth_middle = count_blocks(state_dict_keys, '{}middle_block.1.transformer_blocks.'.format(key_prefix) + '{}')
+ elif "{}middle_block.0.in_layers.0.weight".format(key_prefix) in state_dict_keys:
+ transformer_depth_middle = -1
+ else:
+ transformer_depth_middle = -2
+
+ unet_config["in_channels"] = in_channels
+ unet_config["out_channels"] = out_channels
+ unet_config["model_channels"] = model_channels
+ unet_config["num_res_blocks"] = num_res_blocks
+ unet_config["transformer_depth"] = transformer_depth
+ unet_config["transformer_depth_output"] = transformer_depth_output
+ unet_config["channel_mult"] = channel_mult
+ unet_config["transformer_depth_middle"] = transformer_depth_middle
+ unet_config['use_linear_in_transformer'] = use_linear_in_transformer
+ unet_config["context_dim"] = context_dim
+
+ if video_model:
+ unet_config["extra_ff_mix_layer"] = True
+ unet_config["use_spatial_context"] = True
+ unet_config["merge_strategy"] = "learned_with_images"
+ unet_config["merge_factor"] = 0.0
+ unet_config["video_kernel_size"] = [3, 1, 1]
+ unet_config["use_temporal_resblock"] = True
+ unet_config["use_temporal_attention"] = True
+ unet_config["disable_temporal_crossattention"] = not video_model_cross
+ else:
+ unet_config["use_temporal_resblock"] = False
+ unet_config["use_temporal_attention"] = False
+
+ heatmap_key = '{}heatmap_head.conv_layers.0.weight'.format(key_prefix)
+ if heatmap_key in state_dict_keys:
+ unet_config["heatmap_head"] = True
+
+ return unet_config
+
+
+def model_config_from_unet_config(unet_config, state_dict=None, unet_key_prefix=""):
+ for model_config in comfy.supported_models.models:
+ if model_config.matches(unet_config, state_dict, unet_key_prefix=unet_key_prefix):
+ return model_config(unet_config)
+
+ logging.error("no match {}".format(unet_config))
+ return None
+
+def model_config_from_unet(state_dict, unet_key_prefix, use_base_if_no_match=False, metadata=None):
+ unet_config = detect_unet_config(state_dict, unet_key_prefix, metadata=metadata)
+ if unet_config is None:
+ return None
+ model_config = model_config_from_unet_config(unet_config, state_dict, unet_key_prefix)
+ if model_config is None and use_base_if_no_match:
+ model_config = comfy.supported_models_base.BASE(unet_config)
+
+ # Detect per-layer quantization (mixed precision)
+ quant_config = comfy.utils.detect_layer_quantization(state_dict, unet_key_prefix)
+ if quant_config:
+ model_config.quant_config = quant_config
+ logging.info("Detected mixed precision quantization")
+
+ return model_config
+
+def unet_prefix_from_state_dict(state_dict):
+ # SAM3: detector.* and tracker.* at top level, no common prefix
+ if any(k.startswith("detector.") for k in state_dict) and any(k.startswith("tracker.") for k in state_dict):
+ return ""
+
+ candidates = ["model.diffusion_model.", #ldm/sgm models
+ "model.model.", #audio models
+ "net.", #cosmos
+ ]
+ counts = {k: 0 for k in candidates}
+ for k in state_dict:
+ for c in candidates:
+ if k.startswith(c):
+ counts[c] += 1
+ break
+
+ top = max(counts, key=counts.get)
+ if counts[top] > 5:
+ return top
+ else:
+ return "model." #aura flow and others
+
+
+def convert_config(unet_config):
+ new_config = unet_config.copy()
+ num_res_blocks = new_config.get("num_res_blocks", None)
+ channel_mult = new_config.get("channel_mult", None)
+
+ if isinstance(num_res_blocks, int):
+ num_res_blocks = len(channel_mult) * [num_res_blocks]
+
+ if "attention_resolutions" in new_config:
+ attention_resolutions = new_config.pop("attention_resolutions")
+ transformer_depth = new_config.get("transformer_depth", None)
+ transformer_depth_middle = new_config.get("transformer_depth_middle", None)
+
+ if isinstance(transformer_depth, int):
+ transformer_depth = len(channel_mult) * [transformer_depth]
+ if transformer_depth_middle is None:
+ transformer_depth_middle = transformer_depth[-1]
+ t_in = []
+ t_out = []
+ s = 1
+ for i in range(len(num_res_blocks)):
+ res = num_res_blocks[i]
+ d = 0
+ if s in attention_resolutions:
+ d = transformer_depth[i]
+
+ t_in += [d] * res
+ t_out += [d] * (res + 1)
+ s *= 2
+ transformer_depth = t_in
+ new_config["transformer_depth"] = t_in
+ new_config["transformer_depth_output"] = t_out
+ new_config["transformer_depth_middle"] = transformer_depth_middle
+
+ new_config["num_res_blocks"] = num_res_blocks
+ return new_config
+
+
+def unet_config_from_diffusers_unet(state_dict, dtype=None):
+ if "conv_in.weight" not in state_dict:
+ return None
+
+ match = {}
+ transformer_depth = []
+
+ attn_res = 1
+ down_blocks = count_blocks(state_dict, "down_blocks.{}")
+ for i in range(down_blocks):
+ attn_blocks = count_blocks(state_dict, "down_blocks.{}.attentions.".format(i) + '{}')
+ res_blocks = count_blocks(state_dict, "down_blocks.{}.resnets.".format(i) + '{}')
+ for ab in range(attn_blocks):
+ transformer_count = count_blocks(state_dict, "down_blocks.{}.attentions.{}.transformer_blocks.".format(i, ab) + '{}')
+ transformer_depth.append(transformer_count)
+ if transformer_count > 0:
+ match["context_dim"] = state_dict["down_blocks.{}.attentions.{}.transformer_blocks.0.attn2.to_k.weight".format(i, ab)].shape[1]
+
+ attn_res *= 2
+ if attn_blocks == 0:
+ for i in range(res_blocks):
+ transformer_depth.append(0)
+
+ match["transformer_depth"] = transformer_depth
+
+ match["model_channels"] = state_dict["conv_in.weight"].shape[0]
+ match["in_channels"] = state_dict["conv_in.weight"].shape[1]
+ match["adm_in_channels"] = None
+ if "class_embedding.linear_1.weight" in state_dict:
+ match["adm_in_channels"] = state_dict["class_embedding.linear_1.weight"].shape[1]
+ elif "add_embedding.linear_1.weight" in state_dict:
+ match["adm_in_channels"] = state_dict["add_embedding.linear_1.weight"].shape[1]
+
+ SDXL = {'use_checkpoint': False, 'image_size': 32, 'out_channels': 4, 'use_spatial_transformer': True, 'legacy': False,
+ 'num_classes': 'sequential', 'adm_in_channels': 2816, 'dtype': dtype, 'in_channels': 4, 'model_channels': 320,
+ 'num_res_blocks': [2, 2, 2], 'transformer_depth': [0, 0, 2, 2, 10, 10], 'channel_mult': [1, 2, 4], 'transformer_depth_middle': 10,
+ 'use_linear_in_transformer': True, 'context_dim': 2048, 'num_head_channels': 64, 'transformer_depth_output': [0, 0, 0, 2, 2, 2, 10, 10, 10],
+ 'use_temporal_attention': False, 'use_temporal_resblock': False}
+
+ SDXL_refiner = {'use_checkpoint': False, 'image_size': 32, 'out_channels': 4, 'use_spatial_transformer': True, 'legacy': False,
+ 'num_classes': 'sequential', 'adm_in_channels': 2560, 'dtype': dtype, 'in_channels': 4, 'model_channels': 384,
+ 'num_res_blocks': [2, 2, 2, 2], 'transformer_depth': [0, 0, 4, 4, 4, 4, 0, 0], 'channel_mult': [1, 2, 4, 4], 'transformer_depth_middle': 4,
+ 'use_linear_in_transformer': True, 'context_dim': 1280, 'num_head_channels': 64, 'transformer_depth_output': [0, 0, 0, 4, 4, 4, 4, 4, 4, 0, 0, 0],
+ 'use_temporal_attention': False, 'use_temporal_resblock': False}
+
+ SD21 = {'use_checkpoint': False, 'image_size': 32, 'out_channels': 4, 'use_spatial_transformer': True, 'legacy': False,
+ 'adm_in_channels': None, 'dtype': dtype, 'in_channels': 4, 'model_channels': 320, 'num_res_blocks': [2, 2, 2, 2],
+ 'transformer_depth': [1, 1, 1, 1, 1, 1, 0, 0], 'channel_mult': [1, 2, 4, 4], 'transformer_depth_middle': 1, 'use_linear_in_transformer': True,
+ 'context_dim': 1024, 'num_head_channels': 64, 'transformer_depth_output': [1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
+ 'use_temporal_attention': False, 'use_temporal_resblock': False}
+
+ SD21_uncliph = {'use_checkpoint': False, 'image_size': 32, 'out_channels': 4, 'use_spatial_transformer': True, 'legacy': False,
+ 'num_classes': 'sequential', 'adm_in_channels': 2048, 'dtype': dtype, 'in_channels': 4, 'model_channels': 320,
+ 'num_res_blocks': [2, 2, 2, 2], 'transformer_depth': [1, 1, 1, 1, 1, 1, 0, 0], 'channel_mult': [1, 2, 4, 4], 'transformer_depth_middle': 1,
+ 'use_linear_in_transformer': True, 'context_dim': 1024, 'num_head_channels': 64, 'transformer_depth_output': [1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
+ 'use_temporal_attention': False, 'use_temporal_resblock': False}
+
+ SD21_unclipl = {'use_checkpoint': False, 'image_size': 32, 'out_channels': 4, 'use_spatial_transformer': True, 'legacy': False,
+ 'num_classes': 'sequential', 'adm_in_channels': 1536, 'dtype': dtype, 'in_channels': 4, 'model_channels': 320,
+ 'num_res_blocks': [2, 2, 2, 2], 'transformer_depth': [1, 1, 1, 1, 1, 1, 0, 0], 'channel_mult': [1, 2, 4, 4], 'transformer_depth_middle': 1,
+ 'use_linear_in_transformer': True, 'context_dim': 1024, 'num_head_channels': 64, 'transformer_depth_output': [1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
+ 'use_temporal_attention': False, 'use_temporal_resblock': False}
+
+ SD15 = {'use_checkpoint': False, 'image_size': 32, 'out_channels': 4, 'use_spatial_transformer': True, 'legacy': False, 'adm_in_channels': None,
+ 'dtype': dtype, 'in_channels': 4, 'model_channels': 320, 'num_res_blocks': [2, 2, 2, 2], 'transformer_depth': [1, 1, 1, 1, 1, 1, 0, 0],
+ 'channel_mult': [1, 2, 4, 4], 'transformer_depth_middle': 1, 'use_linear_in_transformer': False, 'context_dim': 768, 'num_heads': 8,
+ 'transformer_depth_output': [1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
+ 'use_temporal_attention': False, 'use_temporal_resblock': False}
+
+ SDXL_mid_cnet = {'use_checkpoint': False, 'image_size': 32, 'out_channels': 4, 'use_spatial_transformer': True, 'legacy': False,
+ 'num_classes': 'sequential', 'adm_in_channels': 2816, 'dtype': dtype, 'in_channels': 4, 'model_channels': 320,
+ 'num_res_blocks': [2, 2, 2], 'transformer_depth': [0, 0, 0, 0, 1, 1], 'channel_mult': [1, 2, 4], 'transformer_depth_middle': 1,
+ 'use_linear_in_transformer': True, 'context_dim': 2048, 'num_head_channels': 64, 'transformer_depth_output': [0, 0, 0, 0, 0, 0, 1, 1, 1],
+ 'use_temporal_attention': False, 'use_temporal_resblock': False}
+
+ SDXL_small_cnet = {'use_checkpoint': False, 'image_size': 32, 'out_channels': 4, 'use_spatial_transformer': True, 'legacy': False,
+ 'num_classes': 'sequential', 'adm_in_channels': 2816, 'dtype': dtype, 'in_channels': 4, 'model_channels': 320,
+ 'num_res_blocks': [2, 2, 2], 'transformer_depth': [0, 0, 0, 0, 0, 0], 'channel_mult': [1, 2, 4], 'transformer_depth_middle': 0,
+ 'use_linear_in_transformer': True, 'num_head_channels': 64, 'context_dim': 1, 'transformer_depth_output': [0, 0, 0, 0, 0, 0, 0, 0, 0],
+ 'use_temporal_attention': False, 'use_temporal_resblock': False}
+
+ SDXL_diffusers_inpaint = {'use_checkpoint': False, 'image_size': 32, 'out_channels': 4, 'use_spatial_transformer': True, 'legacy': False,
+ 'num_classes': 'sequential', 'adm_in_channels': 2816, 'dtype': dtype, 'in_channels': 9, 'model_channels': 320,
+ 'num_res_blocks': [2, 2, 2], 'transformer_depth': [0, 0, 2, 2, 10, 10], 'channel_mult': [1, 2, 4], 'transformer_depth_middle': 10,
+ 'use_linear_in_transformer': True, 'context_dim': 2048, 'num_head_channels': 64, 'transformer_depth_output': [0, 0, 0, 2, 2, 2, 10, 10, 10],
+ 'use_temporal_attention': False, 'use_temporal_resblock': False}
+
+ SDXL_diffusers_ip2p = {'use_checkpoint': False, 'image_size': 32, 'out_channels': 4, 'use_spatial_transformer': True, 'legacy': False,
+ 'num_classes': 'sequential', 'adm_in_channels': 2816, 'dtype': dtype, 'in_channels': 8, 'model_channels': 320,
+ 'num_res_blocks': [2, 2, 2], 'transformer_depth': [0, 0, 2, 2, 10, 10], 'channel_mult': [1, 2, 4], 'transformer_depth_middle': 10,
+ 'use_linear_in_transformer': True, 'context_dim': 2048, 'num_head_channels': 64, 'transformer_depth_output': [0, 0, 0, 2, 2, 2, 10, 10, 10],
+ 'use_temporal_attention': False, 'use_temporal_resblock': False}
+
+ SSD_1B = {'use_checkpoint': False, 'image_size': 32, 'out_channels': 4, 'use_spatial_transformer': True, 'legacy': False,
+ 'num_classes': 'sequential', 'adm_in_channels': 2816, 'dtype': dtype, 'in_channels': 4, 'model_channels': 320,
+ 'num_res_blocks': [2, 2, 2], 'transformer_depth': [0, 0, 2, 2, 4, 4], 'transformer_depth_output': [0, 0, 0, 1, 1, 2, 10, 4, 4],
+ 'channel_mult': [1, 2, 4], 'transformer_depth_middle': -1, 'use_linear_in_transformer': True, 'context_dim': 2048, 'num_head_channels': 64,
+ 'use_temporal_attention': False, 'use_temporal_resblock': False}
+
+ Segmind_Vega = {'use_checkpoint': False, 'image_size': 32, 'out_channels': 4, 'use_spatial_transformer': True, 'legacy': False,
+ 'num_classes': 'sequential', 'adm_in_channels': 2816, 'dtype': dtype, 'in_channels': 4, 'model_channels': 320,
+ 'num_res_blocks': [2, 2, 2], 'transformer_depth': [0, 0, 1, 1, 2, 2], 'transformer_depth_output': [0, 0, 0, 1, 1, 1, 2, 2, 2],
+ 'channel_mult': [1, 2, 4], 'transformer_depth_middle': -1, 'use_linear_in_transformer': True, 'context_dim': 2048, 'num_head_channels': 64,
+ 'use_temporal_attention': False, 'use_temporal_resblock': False}
+
+ KOALA_700M = {'use_checkpoint': False, 'image_size': 32, 'out_channels': 4, 'use_spatial_transformer': True, 'legacy': False,
+ 'num_classes': 'sequential', 'adm_in_channels': 2816, 'dtype': dtype, 'in_channels': 4, 'model_channels': 320,
+ 'num_res_blocks': [1, 1, 1], 'transformer_depth': [0, 2, 5], 'transformer_depth_output': [0, 0, 2, 2, 5, 5],
+ 'channel_mult': [1, 2, 4], 'transformer_depth_middle': -2, 'use_linear_in_transformer': True, 'context_dim': 2048, 'num_head_channels': 64,
+ 'use_temporal_attention': False, 'use_temporal_resblock': False}
+
+ KOALA_1B = {'use_checkpoint': False, 'image_size': 32, 'out_channels': 4, 'use_spatial_transformer': True, 'legacy': False,
+ 'num_classes': 'sequential', 'adm_in_channels': 2816, 'dtype': dtype, 'in_channels': 4, 'model_channels': 320,
+ 'num_res_blocks': [1, 1, 1], 'transformer_depth': [0, 2, 6], 'transformer_depth_output': [0, 0, 2, 2, 6, 6],
+ 'channel_mult': [1, 2, 4], 'transformer_depth_middle': 6, 'use_linear_in_transformer': True, 'context_dim': 2048, 'num_head_channels': 64,
+ 'use_temporal_attention': False, 'use_temporal_resblock': False}
+
+ SD09_XS = {'use_checkpoint': False, 'image_size': 32, 'out_channels': 4, 'use_spatial_transformer': True, 'legacy': False,
+ 'adm_in_channels': None, 'dtype': dtype, 'in_channels': 4, 'model_channels': 320, 'num_res_blocks': [1, 1, 1],
+ 'transformer_depth': [1, 1, 1], 'channel_mult': [1, 2, 4], 'transformer_depth_middle': -2, 'use_linear_in_transformer': True,
+ 'context_dim': 1024, 'num_head_channels': 64, 'transformer_depth_output': [1, 1, 1, 1, 1, 1],
+ 'use_temporal_attention': False, 'use_temporal_resblock': False, 'disable_self_attentions': [True, False, False]}
+
+ SD_XS = {'use_checkpoint': False, 'image_size': 32, 'out_channels': 4, 'use_spatial_transformer': True, 'legacy': False,
+ 'adm_in_channels': None, 'dtype': dtype, 'in_channels': 4, 'model_channels': 320, 'num_res_blocks': [1, 1, 1],
+ 'transformer_depth': [0, 1, 1], 'channel_mult': [1, 2, 4], 'transformer_depth_middle': -2, 'use_linear_in_transformer': False,
+ 'context_dim': 768, 'num_head_channels': 64, 'transformer_depth_output': [0, 0, 1, 1, 1, 1],
+ 'use_temporal_attention': False, 'use_temporal_resblock': False}
+
+ SD15_diffusers_inpaint = {'use_checkpoint': False, 'image_size': 32, 'out_channels': 4, 'use_spatial_transformer': True, 'legacy': False, 'adm_in_channels': None,
+ 'dtype': dtype, 'in_channels': 9, 'model_channels': 320, 'num_res_blocks': [2, 2, 2, 2], 'transformer_depth': [1, 1, 1, 1, 1, 1, 0, 0],
+ 'channel_mult': [1, 2, 4, 4], 'transformer_depth_middle': 1, 'use_linear_in_transformer': False, 'context_dim': 768, 'num_heads': 8,
+ 'transformer_depth_output': [1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
+ 'use_temporal_attention': False, 'use_temporal_resblock': False}
+
+ LotusD = {'use_checkpoint': False, 'image_size': 32, 'out_channels': 4, 'use_spatial_transformer': True, 'legacy': False, 'adm_in_channels': 4,
+ 'dtype': dtype, 'in_channels': 4, 'model_channels': 320, 'num_res_blocks': [2, 2, 2, 2], 'transformer_depth': [1, 1, 1, 1, 1, 1, 0, 0],
+ 'channel_mult': [1, 2, 4, 4], 'transformer_depth_middle': 1, 'use_linear_in_transformer': True, 'context_dim': 1024, 'num_head_channels': 64,
+ 'transformer_depth_output': [1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0],
+ 'use_temporal_attention': False, 'use_temporal_resblock': False}
+
+ supported_models = [LotusD, SDXL, SDXL_refiner, SD21, SD15, SD21_uncliph, SD21_unclipl, SDXL_mid_cnet, SDXL_small_cnet, SDXL_diffusers_inpaint, SSD_1B, Segmind_Vega, KOALA_700M, KOALA_1B, SD09_XS, SD_XS, SDXL_diffusers_ip2p, SD15_diffusers_inpaint]
+
+ for unet_config in supported_models:
+ matches = True
+ for k in match:
+ if match[k] != unet_config[k]:
+ matches = False
+ break
+ if matches:
+ return convert_config(unet_config)
+ return None
+
+def model_config_from_diffusers_unet(state_dict):
+ unet_config = unet_config_from_diffusers_unet(state_dict)
+ if unet_config is not None:
+ return model_config_from_unet_config(unet_config)
+ return None
+
+def convert_diffusers_mmdit(state_dict, output_prefix=""):
+ out_sd = {}
+
+ if 'joint_transformer_blocks.0.attn.add_k_proj.weight' in state_dict: #AuraFlow
+ num_joint = count_blocks(state_dict, 'joint_transformer_blocks.{}.')
+ num_single = count_blocks(state_dict, 'single_transformer_blocks.{}.')
+ sd_map = comfy.utils.auraflow_to_diffusers({"n_double_layers": num_joint, "n_layers": num_joint + num_single}, output_prefix=output_prefix)
+ elif 'adaln_single.emb.timestep_embedder.linear_1.bias' in state_dict and 'pos_embed.proj.bias' in state_dict: # PixArt
+ num_blocks = count_blocks(state_dict, 'transformer_blocks.{}.')
+ sd_map = comfy.utils.pixart_to_diffusers({"depth": num_blocks}, output_prefix=output_prefix)
+ elif 'noise_refiner.0.attention.norm_k.weight' in state_dict:
+ n_layers = count_blocks(state_dict, 'layers.{}.')
+ dim = state_dict['noise_refiner.0.attention.to_k.weight'].shape[0]
+ sd_map = comfy.utils.z_image_to_diffusers({"n_layers": n_layers, "dim": dim}, output_prefix=output_prefix)
+ for k in state_dict: # For zeta chroma
+ if k not in sd_map:
+ sd_map[k] = k
+ elif 'x_embedder.weight' in state_dict: #Flux
+ depth = count_blocks(state_dict, 'transformer_blocks.{}.')
+ depth_single_blocks = count_blocks(state_dict, 'single_transformer_blocks.{}.')
+ hidden_size = state_dict["x_embedder.bias"].shape[0]
+ sd_map = comfy.utils.flux_to_diffusers({"depth": depth, "depth_single_blocks": depth_single_blocks, "hidden_size": hidden_size}, output_prefix=output_prefix)
+ elif 'transformer_blocks.0.attn.add_q_proj.weight' in state_dict and 'pos_embed.proj.weight' in state_dict: #SD3
+ num_blocks = count_blocks(state_dict, 'transformer_blocks.{}.')
+ depth = state_dict["pos_embed.proj.weight"].shape[0] // 64
+ sd_map = comfy.utils.mmdit_to_diffusers({"depth": depth, "num_blocks": num_blocks}, output_prefix=output_prefix)
+ else:
+ return None
+
+ for k in sd_map:
+ weight = state_dict.get(k, None)
+ if weight is not None:
+ t = sd_map[k]
+
+ if not isinstance(t, str):
+ if len(t) > 2:
+ fun = t[2]
+ else:
+ fun = lambda a: a
+ offset = t[1]
+ if offset is not None:
+ old_weight = out_sd.get(t[0], None)
+ if old_weight is None:
+ old_weight = torch.empty_like(weight)
+ if old_weight.shape[offset[0]] < offset[1] + offset[2]:
+ exp = list(weight.shape)
+ exp[offset[0]] = offset[1] + offset[2]
+ new = torch.empty(exp, device=weight.device, dtype=weight.dtype)
+ new[:old_weight.shape[0]] = old_weight
+ old_weight = new
+
+ if old_weight is out_sd.get(t[0], None) and comfy.memory_management.aimdo_enabled:
+ old_weight = old_weight.clone()
+
+ w = old_weight.narrow(offset[0], offset[1], offset[2])
+ else:
+ if comfy.memory_management.aimdo_enabled:
+ weight = weight.clone()
+ old_weight = weight
+ w = weight
+ w[:] = fun(weight)
+ t = t[0]
+ out_sd[t] = old_weight
+ else:
+ out_sd[t] = weight
+ state_dict.pop(k)
+
+ return out_sd
diff --git a/ComfyUI/comfy/model_management.py b/ComfyUI/comfy/model_management.py
new file mode 100644
index 0000000000000000000000000000000000000000..9f8e7f07b18161549d52b28f356152ce217121b8
--- /dev/null
+++ b/ComfyUI/comfy/model_management.py
@@ -0,0 +1,2102 @@
+"""
+ This file is part of ComfyUI.
+ Copyright (C) 2024 Comfy
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+"""
+from __future__ import annotations
+
+import psutil
+import logging
+from enum import Enum
+from comfy.cli_args import args, PerformanceFeature
+import threading
+import torch
+import sys
+import platform
+import weakref
+import gc
+import os
+from contextlib import contextmanager, nullcontext
+import comfy.memory_management
+import comfy.utils
+import comfy.quant_ops
+import comfy_aimdo.host_buffer
+import comfy_aimdo.vram_buffer
+from comfy.internal_logging import detail
+
+from typing import TYPE_CHECKING
+if TYPE_CHECKING:
+ from comfy.model_patcher import ModelPatcher
+
+
+class VRAMState(Enum):
+ DISABLED = 0 #No vram present: no need to move models to vram
+ NO_VRAM = 1 #Very low vram: enable all the options to save vram
+ LOW_VRAM = 2
+ NORMAL_VRAM = 3
+ HIGH_VRAM = 4
+ SHARED = 5 #No dedicated vram: memory shared between CPU and GPU but models still need to be moved between both.
+
+class CPUState(Enum):
+ GPU = 0
+ CPU = 1
+ MPS = 2
+
+# Determine VRAM State
+vram_state = VRAMState.NORMAL_VRAM
+set_vram_to = VRAMState.NORMAL_VRAM
+cpu_state = CPUState.GPU
+
+total_vram = 0
+
+
+# Training Related State
+in_training = False
+training_fp8_bwd = False
+
+
+def get_supported_float8_types():
+ float8_types = []
+ try:
+ float8_types.append(torch.float8_e4m3fn)
+ except:
+ pass
+ try:
+ float8_types.append(torch.float8_e4m3fnuz)
+ except:
+ pass
+ try:
+ float8_types.append(torch.float8_e5m2)
+ except:
+ pass
+ try:
+ float8_types.append(torch.float8_e5m2fnuz)
+ except:
+ pass
+ try:
+ float8_types.append(torch.float8_e8m0fnu)
+ except:
+ pass
+ return float8_types
+
+FLOAT8_TYPES = get_supported_float8_types()
+
+xpu_available = False
+torch_version = ""
+try:
+ torch_version = torch.version.__version__
+ temp = torch_version.split(".")
+ torch_version_numeric = (int(temp[0]), int(temp[1]))
+except:
+ pass
+
+lowvram_available = True
+if args.deterministic:
+ logging.info("Using deterministic algorithms for pytorch")
+ torch.use_deterministic_algorithms(True, warn_only=True)
+
+directml_enabled = False
+if args.directml is not None:
+ logging.warning("WARNING: torch-directml barely works, is very slow, has not been updated in over 1 year and might be removed soon, please don't use it, there are better options.")
+ import torch_directml
+ directml_enabled = True
+ device_index = args.directml
+ if device_index < 0:
+ directml_device = torch_directml.device()
+ else:
+ directml_device = torch_directml.device(device_index)
+ logging.info("Using directml with device: {}".format(torch_directml.device_name(device_index)))
+ # torch_directml.disable_tiled_resources(True)
+ lowvram_available = False #TODO: need to find a way to get free memory in directml before this can be enabled by default.
+
+
+try:
+ _ = torch.xpu.device_count()
+ xpu_available = torch.xpu.is_available()
+except:
+ xpu_available = False
+
+try:
+ if torch.backends.mps.is_available():
+ cpu_state = CPUState.MPS
+ import torch.mps
+except:
+ pass
+
+try:
+ import torch_npu # noqa: F401
+ _ = torch.npu.device_count()
+ npu_available = torch.npu.is_available()
+except:
+ npu_available = False
+
+try:
+ import torch_mlu # noqa: F401
+ _ = torch.mlu.device_count()
+ mlu_available = torch.mlu.is_available()
+except:
+ mlu_available = False
+
+try:
+ ixuca_available = hasattr(torch, "corex")
+except:
+ ixuca_available = False
+
+if args.cpu:
+ cpu_state = CPUState.CPU
+
+def is_intel_xpu():
+ global cpu_state
+ global xpu_available
+ if cpu_state == CPUState.GPU:
+ if xpu_available:
+ return True
+ return False
+
+def is_ascend_npu():
+ global npu_available
+ if npu_available:
+ return True
+ return False
+
+def is_mlu():
+ global mlu_available
+ if mlu_available:
+ return True
+ return False
+
+def is_ixuca():
+ global ixuca_available
+ if ixuca_available:
+ return True
+ return False
+
+def is_wsl():
+ version = platform.uname().release
+ if version.endswith("-Microsoft"):
+ return True
+ elif version.endswith("microsoft-standard-WSL2"):
+ return True
+ return False
+
+def get_torch_device():
+ global directml_enabled
+ global cpu_state
+ if directml_enabled:
+ global directml_device
+ return directml_device
+ if cpu_state == CPUState.MPS:
+ return torch.device("mps")
+ if cpu_state == CPUState.CPU:
+ return torch.device("cpu")
+ else:
+ if is_intel_xpu():
+ return torch.device("xpu", torch.xpu.current_device())
+ elif is_ascend_npu():
+ return torch.device("npu", torch.npu.current_device())
+ elif is_mlu():
+ return torch.device("mlu", torch.mlu.current_device())
+ else:
+ return torch.device(torch.cuda.current_device())
+
+def get_all_torch_devices(exclude_current=False):
+ global cpu_state
+ devices = []
+ if cpu_state == CPUState.GPU:
+ # NVIDIA + AMD/ROCm both expose their GPUs through torch.cuda.*;
+ # without the AMD arm, single-GPU ROCm users get an empty list
+ # which silently turns unload_all_models() into a no-op.
+ if is_nvidia() or is_amd():
+ for i in range(torch.cuda.device_count()):
+ devices.append(torch.device("cuda", i))
+ elif is_intel_xpu():
+ for i in range(torch.xpu.device_count()):
+ devices.append(torch.device("xpu", i))
+ elif is_ascend_npu():
+ for i in range(torch.npu.device_count()):
+ devices.append(torch.device("npu", i))
+ elif is_mlu():
+ for i in range(torch.mlu.device_count()):
+ devices.append(torch.device("mlu", i))
+ else:
+ # Fallback for unhandled GPU backends (e.g. DirectML): at least
+ # report the current device so callers like unload_all_models()
+ # do not silently no-op.
+ devices.append(get_torch_device())
+ else:
+ devices.append(get_torch_device())
+ if exclude_current:
+ current = get_torch_device()
+ if current in devices:
+ devices.remove(current)
+ return devices
+
+def get_gpu_device_options():
+ """Return list of device option strings for node widgets.
+
+ Always includes "default" and "cpu". When multiple GPUs are present,
+ adds "gpu:0", "gpu:1", etc. (vendor-agnostic labels).
+ """
+ options = ["default", "cpu"]
+ devices = get_all_torch_devices()
+ if len(devices) > 1:
+ for i in range(len(devices)):
+ options.append(f"gpu:{i}")
+ return options
+
+def get_gpu_device_options_no_cpu():
+ """Variant of get_gpu_device_options that omits "cpu".
+
+ Intended for components like the VAE selector where running on CPU
+ is impractical and should not be offered as a choice.
+ """
+ return [o for o in get_gpu_device_options() if o != "cpu"]
+
+def resolve_gpu_device_option(option: str):
+ """Resolve a device option string to a torch.device.
+
+ Returns None for "default" (let the caller use its normal default).
+ Returns torch.device("cpu") for "cpu".
+ For "gpu:N", returns the Nth torch device. Returns None if the
+ index is out of range, the option string is malformed, or
+ unrecognized (callers are expected to log their own context-rich
+ message before falling back to the default device).
+ """
+ if option is None or option == "default":
+ return None
+ if option == "cpu":
+ return torch.device("cpu")
+ if option.startswith("gpu:"):
+ try:
+ idx = int(option[4:])
+ except ValueError:
+ return None
+ devices = get_all_torch_devices()
+ if 0 <= idx < len(devices):
+ return devices[idx]
+ return None
+
+@contextmanager
+def cuda_device_context(device):
+ """Context manager that sets torch.cuda.current_device to match *device*.
+
+ Used when running operations on a non-default CUDA device so that custom
+ CUDA kernels (e.g. comfy_kitchen fp8 quantization) pick up the correct
+ device index. The previous device is restored on exit.
+
+ No-op when *device* is not CUDA, has no explicit index, or already matches
+ the current device.
+ """
+ prev = None
+ if device.type == "cuda" and device.index is not None:
+ prev = torch.cuda.current_device()
+ if prev != device.index:
+ torch.cuda.set_device(device)
+ else:
+ prev = None
+ try:
+ yield
+ finally:
+ if prev is not None:
+ torch.cuda.set_device(prev)
+
+def get_total_memory(dev=None, torch_total_too=False):
+ global directml_enabled
+ if dev is None:
+ dev = get_torch_device()
+
+ if hasattr(dev, 'type') and (dev.type == 'cpu' or dev.type == 'mps'):
+ mem_total = psutil.virtual_memory().total
+ mem_total_torch = mem_total
+ else:
+ if directml_enabled:
+ mem_total = 1024 * 1024 * 1024 #TODO
+ mem_total_torch = mem_total
+ elif is_intel_xpu():
+ stats = torch.xpu.memory_stats(dev)
+ mem_reserved = stats['reserved_bytes.all.current']
+ mem_total_xpu = torch.xpu.get_device_properties(dev).total_memory
+ mem_total_torch = mem_reserved
+ mem_total = mem_total_xpu
+ elif is_ascend_npu():
+ stats = torch.npu.memory_stats(dev)
+ mem_reserved = stats['reserved_bytes.all.current']
+ _, mem_total_npu = torch.npu.mem_get_info(dev)
+ mem_total_torch = mem_reserved
+ mem_total = mem_total_npu
+ elif is_mlu():
+ stats = torch.mlu.memory_stats(dev)
+ mem_reserved = stats['reserved_bytes.all.current']
+ _, mem_total_mlu = torch.mlu.mem_get_info(dev)
+ mem_total_torch = mem_reserved
+ mem_total = mem_total_mlu
+ else:
+ stats = torch.cuda.memory_stats(dev)
+ mem_reserved = stats['reserved_bytes.all.current']
+ _, mem_total_cuda = torch.cuda.mem_get_info(dev)
+ mem_total_torch = mem_reserved
+ mem_total = mem_total_cuda
+
+ if torch_total_too:
+ return (mem_total, mem_total_torch)
+ else:
+ return mem_total
+
+def mac_version():
+ try:
+ return tuple(int(n) for n in platform.mac_ver()[0].split("."))
+ except:
+ return None
+
+total_vram = get_total_memory(get_torch_device()) / (1024 * 1024)
+total_ram = psutil.virtual_memory().total / (1024 * 1024)
+logging.info("Total VRAM {:0.0f} MB, total RAM {:0.0f} MB".format(total_vram, total_ram))
+
+try:
+ logging.info("pytorch version: {}".format(torch_version))
+ mac_ver = mac_version()
+ if mac_ver is not None:
+ logging.info("Mac Version {}".format(mac_ver))
+except:
+ pass
+
+try:
+ OOM_EXCEPTION = torch.cuda.OutOfMemoryError
+except:
+ OOM_EXCEPTION = Exception
+
+try:
+ ACCELERATOR_ERROR = torch.AcceleratorError
+except AttributeError:
+ ACCELERATOR_ERROR = RuntimeError
+
+def is_oom(e):
+ if isinstance(e, OOM_EXCEPTION):
+ return True
+ if isinstance(e, ACCELERATOR_ERROR) and (getattr(e, 'error_code', None) == 2 or "out of memory" in str(e).lower()):
+ discard_cuda_async_error()
+ return True
+ return False
+
+def raise_non_oom(e):
+ if not is_oom(e):
+ raise e
+
+XFORMERS_VERSION = ""
+XFORMERS_ENABLED_VAE = True
+if args.disable_xformers:
+ XFORMERS_IS_AVAILABLE = False
+else:
+ try:
+ import xformers
+ import xformers.ops
+ XFORMERS_IS_AVAILABLE = True
+ try:
+ XFORMERS_IS_AVAILABLE = xformers._has_cpp_library
+ except:
+ pass
+ try:
+ XFORMERS_VERSION = xformers.version.__version__
+ logging.info("xformers version: {}".format(XFORMERS_VERSION))
+ if XFORMERS_VERSION.startswith("0.0.18"):
+ logging.warning("\nWARNING: This version of xformers has a major bug where you will get black images when generating high resolution images.")
+ logging.warning("Please downgrade or upgrade xformers to a different version.\n")
+ XFORMERS_ENABLED_VAE = False
+ except:
+ pass
+ except:
+ XFORMERS_IS_AVAILABLE = False
+
+def is_nvidia():
+ global cpu_state
+ if cpu_state == CPUState.GPU:
+ if torch.version.cuda:
+ return True
+ return False
+
+def is_amd():
+ global cpu_state
+ if cpu_state == CPUState.GPU:
+ if torch.version.hip:
+ return True
+ return False
+
+def amd_min_version(device=None, min_rdna_version=0):
+ if not is_amd():
+ return False
+
+ if is_device_cpu(device):
+ return False
+
+ arch = torch.cuda.get_device_properties(device).gcnArchName
+ if arch.startswith('gfx') and len(arch) == 7:
+ try:
+ cmp_rdna_version = int(arch[4]) + 2
+ except:
+ cmp_rdna_version = 0
+ if cmp_rdna_version >= min_rdna_version:
+ return True
+
+ return False
+
+MIN_WEIGHT_MEMORY_RATIO = 0.4
+if is_nvidia():
+ MIN_WEIGHT_MEMORY_RATIO = 0.0
+
+ENABLE_PYTORCH_ATTENTION = False
+if args.use_pytorch_cross_attention:
+ ENABLE_PYTORCH_ATTENTION = True
+ XFORMERS_IS_AVAILABLE = False
+
+try:
+ if is_nvidia():
+ if torch_version_numeric[0] >= 2:
+ if ENABLE_PYTORCH_ATTENTION == False and args.use_split_cross_attention == False and args.use_quad_cross_attention == False:
+ ENABLE_PYTORCH_ATTENTION = True
+ if is_intel_xpu() or is_ascend_npu() or is_mlu() or is_ixuca():
+ if args.use_split_cross_attention == False and args.use_quad_cross_attention == False:
+ ENABLE_PYTORCH_ATTENTION = True
+except:
+ pass
+
+
+SUPPORT_FP8_OPS = args.supports_fp8_compute
+
+AMD_RDNA2_AND_OLDER_ARCH = ["gfx1030", "gfx1031", "gfx1035", "gfx1010", "gfx1011", "gfx1012", "gfx906", "gfx900", "gfx803"]
+AMD_ENABLE_MIOPEN_ENV = 'COMFYUI_ENABLE_MIOPEN'
+
+try:
+ if is_amd():
+ arch = torch.cuda.get_device_properties(get_torch_device()).gcnArchName.split(':')[0]
+ if not (any((a in arch) for a in AMD_RDNA2_AND_OLDER_ARCH)):
+ if os.getenv(AMD_ENABLE_MIOPEN_ENV) != '1':
+ torch.backends.cudnn.enabled = False # Seems to improve things a lot on AMD
+ logging.info("Set: torch.backends.cudnn.enabled = False for better AMD performance.")
+
+ try:
+ rocm_version = tuple(map(int, str(torch.version.hip).split(".")[:2]))
+ except:
+ rocm_version = (6, -1)
+
+ def aotriton_supported(gpu_arch):
+ path = torch.__path__[0]
+ path = os.path.join(os.path.join(path, "lib"), "aotriton.images")
+ gfx = set(map(lambda a: a[4:], filter(lambda a: a.startswith("amd-gfx"), os.listdir(path))))
+ if gpu_arch in gfx:
+ return True
+ if "{}x".format(gpu_arch[:-1]) in gfx:
+ return True
+ if "{}xx".format(gpu_arch[:-2]) in gfx:
+ return True
+ return False
+
+ logging.info("AMD arch: {}".format(arch))
+ logging.info("ROCm version: {}".format(rocm_version))
+ if args.use_split_cross_attention == False and args.use_quad_cross_attention == False:
+ if aotriton_supported(arch): # AMD efficient attention implementation depends on aotriton.
+ if torch_version_numeric >= (2, 7): # works on 2.6 but doesn't actually seem to improve much
+ if any((a in arch) for a in ["gfx90a", "gfx942", "gfx950", "gfx1100", "gfx1101", "gfx1150", "gfx1151"]): # TODO: more arches, TODO: gfx950
+ ENABLE_PYTORCH_ATTENTION = True
+ if rocm_version >= (7, 0):
+ if any((a in arch) for a in ["gfx1200", "gfx1201"]):
+ ENABLE_PYTORCH_ATTENTION = True
+ if torch_version_numeric >= (2, 7) and rocm_version >= (6, 4):
+ if any((a in arch) for a in ["gfx1200", "gfx1201", "gfx950"]): # TODO: more arches, "gfx942" gives error on pytorch nightly 2.10 1013 rocm7.0
+ SUPPORT_FP8_OPS = True
+
+except:
+ pass
+
+
+if ENABLE_PYTORCH_ATTENTION:
+ torch.backends.cuda.enable_math_sdp(True)
+ torch.backends.cuda.enable_flash_sdp(True)
+ torch.backends.cuda.enable_mem_efficient_sdp(True)
+
+
+PRIORITIZE_FP16 = False # TODO: remove and replace with something that shows exactly which dtype is faster than the other
+try:
+ if (is_nvidia() or is_amd()) and PerformanceFeature.Fp16Accumulation in args.fast:
+ torch.backends.cuda.matmul.allow_fp16_accumulation = True
+ PRIORITIZE_FP16 = True # TODO: limit to cards where it actually boosts performance
+ logging.info("Enabled fp16 accumulation.")
+except:
+ pass
+
+
+def set_cudnn_benchmark():
+ if torch.cuda.is_available() and torch.backends.cudnn.is_available():
+ torch.backends.cudnn.benchmark = PerformanceFeature.AutoTune in args.fast
+
+try:
+ if torch_version_numeric >= (2, 5):
+ torch.backends.cuda.allow_fp16_bf16_reduction_math_sdp(True)
+except:
+ logging.warning("Warning, could not set allow_fp16_bf16_reduction_math_sdp")
+
+if args.lowvram:
+ set_vram_to = VRAMState.LOW_VRAM
+ lowvram_available = True
+elif args.novram:
+ set_vram_to = VRAMState.NO_VRAM
+elif args.highvram or args.gpu_only:
+ vram_state = VRAMState.HIGH_VRAM
+
+FORCE_FP32 = False
+if args.force_fp32:
+ logging.info("Forcing FP32, if this improves things please report it.")
+ FORCE_FP32 = True
+
+if lowvram_available:
+ if set_vram_to in (VRAMState.LOW_VRAM, VRAMState.NO_VRAM):
+ vram_state = set_vram_to
+
+
+if cpu_state != CPUState.GPU:
+ vram_state = VRAMState.DISABLED
+
+if cpu_state == CPUState.MPS:
+ vram_state = VRAMState.SHARED
+
+logging.info(f"Set vram state to: {vram_state.name}")
+
+DISABLE_SMART_MEMORY = args.disable_smart_memory
+
+if DISABLE_SMART_MEMORY:
+ logging.info("Disabling smart memory management")
+
+def get_torch_device_name(device):
+ if hasattr(device, 'type'):
+ if device.type == "cuda":
+ try:
+ allocator_backend = torch.cuda.get_allocator_backend()
+ except:
+ allocator_backend = ""
+ return "{} {} : {}".format(device, torch.cuda.get_device_name(device), allocator_backend)
+ elif device.type == "xpu":
+ return "{} {}".format(device, torch.xpu.get_device_name(device))
+ else:
+ return "{}".format(device.type)
+ elif is_intel_xpu():
+ return "{} {}".format(device, torch.xpu.get_device_name(device))
+ elif is_ascend_npu():
+ return "{} {}".format(device, torch.npu.get_device_name(device))
+ elif is_mlu():
+ return "{} {}".format(device, torch.mlu.get_device_name(device))
+ else:
+ return "CUDA {}: {}".format(device, torch.cuda.get_device_name(device))
+
+try:
+ logging.info("Device: {}".format(get_torch_device_name(get_torch_device())))
+except:
+ logging.warning("Could not pick default device.")
+try:
+ for device in get_all_torch_devices(exclude_current=True):
+ logging.info("Device: {}".format(get_torch_device_name(device)))
+except:
+ pass
+
+current_loaded_models: list[LoadedModel] = []
+
+DIRTY_MMAPS = set()
+
+PIN_PRESSURE_HYSTERESIS = 256 * 1024 * 1024
+
+#Freeing registerables on pressure does imply a GPU sync, so go big on
+#the hysteresis so each expensive sync gives us back a good chunk.
+REGISTERABLE_PIN_HYSTERESIS = 2048 * 1024 * 1024
+WINDOWS_PIN_EVICTION_SWAP_PERCENT = 5.0
+WINDOWS_PIN_EVICTION_EMERGENCY_AVAILABLE = 512 * 1024 ** 2
+
+def module_size(module):
+ module_mem = 0
+ sd = module.state_dict()
+ for k in sd:
+ t = sd[k]
+ module_mem += t.nbytes
+ return module_mem
+
+def mark_mmap_dirty(storage):
+ mmap_refs = getattr(storage, "_comfy_tensor_mmap_refs", None)
+ if mmap_refs is not None:
+ DIRTY_MMAPS.add(mmap_refs[0])
+
+PIN_SUBSETS = [ "weights", "patches" ]
+LOADED_PIN_SUBSETS = [ "weights-loaded", "patches-loaded" ]
+
+def models_for_pin_eviction(active, current_prompt=None):
+ for loaded_model in current_loaded_models:
+ model = loaded_model.model
+ if model is None or not model.is_dynamic():
+ continue
+ pin_state = model.model.dynamic_pins[model.load_device]
+ if ((active is None or pin_state["active"] == active) and
+ (current_prompt is None or pin_state["current_prompt"] == current_prompt)):
+ yield model
+
+def free_model_pins(size, subsets, current_prompt, active, registrations=False):
+ freed_total = 0
+ for model in models_for_pin_eviction(active, current_prompt=current_prompt):
+ if size <= 0:
+ return freed_total
+ if registrations:
+ freed = model.unregister_inactive_pins(size, subsets=subsets)
+ else:
+ freed = model.partially_unload_ram(size, subsets=subsets)
+ freed_total += freed
+ size -= freed
+ return freed_total
+
+def pin_eviction_tiers(loaded, evict_active):
+ tiers = [
+ (PIN_SUBSETS, False, None),
+ (LOADED_PIN_SUBSETS, False, None),
+ (LOADED_PIN_SUBSETS, True, None),
+ ]
+ if not loaded:
+ tiers.append((PIN_SUBSETS, True, False))
+ if evict_active:
+ tiers.append((PIN_SUBSETS, True, True))
+ return tiers
+
+def registration_eviction_tiers(evict_active):
+ subsets = PIN_SUBSETS + LOADED_PIN_SUBSETS
+ tiers = [
+ (subsets, False, False),
+ (subsets, True, False),
+ ]
+ if evict_active:
+ tiers.extend([
+ (subsets, False, True),
+ (subsets, True, True),
+ ])
+ return tiers
+
+def free_pins(size, evict_active=False, loaded=False):
+ freed = 0
+ for subsets, current_prompt, active in pin_eviction_tiers(loaded, evict_active):
+ freed += free_model_pins(size - freed, subsets, current_prompt, active)
+ return freed
+
+def should_free_pins_for_ram_pressure(shortfall):
+ if shortfall <= 0:
+ return False
+ if not WINDOWS:
+ return True
+ if psutil.virtual_memory().available < WINDOWS_PIN_EVICTION_EMERGENCY_AVAILABLE:
+ return True
+ try:
+ return psutil.swap_memory().percent >= WINDOWS_PIN_EVICTION_SWAP_PERCENT
+ except RuntimeError as err:
+ logging.warning("Could not read Windows swap usage; falling back to RAM-pressure pin eviction: %s", err)
+ return True
+
+def ensure_pin_budget(size, evict_active=False, loaded=False):
+ if args.high_ram:
+ return True
+ if args.fast_disk:
+ shortfall = TOTAL_PINNED_MEMORY + size - MAX_PINNED_MEMORY
+ else:
+ shortfall = size + max(comfy.memory_management.RAM_CACHE_HEADROOM / 2, 2048 * 1024 ** 2) - psutil.virtual_memory().available
+ if shortfall <= 0:
+ return True
+
+ to_free = shortfall + PIN_PRESSURE_HYSTERESIS
+ return free_pins(to_free, evict_active=evict_active, loaded=loaded) >= shortfall
+
+def free_registrations(shortfall, evict_active=True):
+ if MAX_PINNED_MEMORY <= 0:
+ return False
+ if shortfall <= 0:
+ return True
+
+ shortfall += REGISTERABLE_PIN_HYSTERESIS
+ for subsets, current_prompt, active in registration_eviction_tiers(evict_active):
+ shortfall -= free_model_pins(shortfall, subsets, current_prompt, active, registrations=True)
+ return shortfall <= REGISTERABLE_PIN_HYSTERESIS
+
+def ensure_pin_registerable(size, evict_active=True):
+ return free_registrations(TOTAL_PINNED_MEMORY + size - MAX_PINNED_MEMORY, evict_active=evict_active)
+
+class LoadedModel:
+ def __init__(self, model: ModelPatcher):
+ self._set_model(model)
+ self.device = model.load_device
+ self.real_model = None
+ self.currently_used = True
+ self.model_finalizer = None
+ self._patcher_finalizer = None
+
+ def _set_model(self, model: ModelPatcher):
+ self._model = weakref.ref(model)
+ if model.parent is not None:
+ self._parent_model = weakref.ref(model.parent)
+ self._patcher_finalizer = weakref.finalize(model, self._switch_parent)
+ self._patcher_finalizer.atexit = False
+
+ def _switch_parent(self):
+ model = self._parent_model()
+ if model is not None:
+ self._set_model(model)
+ self.device = model.load_device
+
+ @property
+ def model(self):
+ return self._model()
+
+ def model_memory(self):
+ return self.model.model_size()
+
+ def model_loaded_memory(self):
+ return self.model.loaded_size()
+
+ def model_offloaded_memory(self):
+ return self.model.model_size() - self.model.loaded_size()
+
+ def model_memory_required(self, device):
+ if device == self.model.current_loaded_device():
+ return self.model_offloaded_memory()
+ else:
+ return self.model_memory()
+
+ def model_load(self, lowvram_model_memory=0, force_patch_weights=False):
+ self.model.model_patches_to(self.device)
+ self.model.model_patches_to(self.model.model_dtype())
+
+ # if self.model.loaded_size() > 0:
+ use_more_vram = lowvram_model_memory
+ if use_more_vram == 0:
+ use_more_vram = 1e32
+ self.model_use_more_vram(use_more_vram, force_patch_weights=force_patch_weights)
+
+ real_model = self.model.model
+
+
+ self.real_model = weakref.ref(real_model)
+ self.model_finalizer = weakref.finalize(real_model, cleanup_models)
+ self.model_finalizer.atexit = False
+ return real_model
+
+ def should_reload_model(self, force_patch_weights=False):
+ if force_patch_weights and self.model.lowvram_patch_counter() > 0:
+ return True
+ return False
+
+ def model_unload(self, memory_to_free=None, unpatch_weights=True):
+ if memory_to_free is not None:
+ if memory_to_free < self.model.loaded_size():
+ freed = self.model.partially_unload(self.model.offload_device, memory_to_free)
+ if freed >= memory_to_free:
+ return False
+ self.model.detach(unpatch_weights)
+ self.model_finalizer.detach()
+ self.model_finalizer = None
+ self.real_model = None
+ return True
+
+ def model_use_more_vram(self, extra_memory, force_patch_weights=False):
+ return self.model.partially_load(self.device, extra_memory, force_patch_weights=force_patch_weights)
+
+ def __eq__(self, other):
+ return self.model is other.model
+
+ def __del__(self):
+ if self._patcher_finalizer is not None:
+ self._patcher_finalizer.detach()
+
+ def is_dead(self):
+ return self.real_model() is not None and self.model is None
+
+
+def use_more_memory(extra_memory, loaded_models, device):
+ for m in loaded_models:
+ if m.device == device:
+ extra_memory -= m.model_use_more_vram(extra_memory)
+ if extra_memory <= 0:
+ break
+
+def offloaded_memory(loaded_models, device):
+ offloaded_mem = 0
+ for m in loaded_models:
+ if m.device == device:
+ offloaded_mem += m.model_offloaded_memory()
+ return offloaded_mem
+
+WINDOWS = any(platform.win32_ver())
+
+EXTRA_RESERVED_VRAM = 400 * 1024 * 1024
+if WINDOWS:
+ EXTRA_RESERVED_VRAM = 600 * 1024 * 1024 #Windows is higher because of the shared vram issue
+ if total_vram > (15 * 1024): # more extra reserved vram on 16GB+ cards
+ EXTRA_RESERVED_VRAM += 100 * 1024 * 1024
+
+if args.reserve_vram is not None:
+ EXTRA_RESERVED_VRAM = args.reserve_vram * 1024 * 1024 * 1024
+ logging.debug("Reserving {}MB vram for other applications.".format(EXTRA_RESERVED_VRAM / (1024 * 1024)))
+
+def extra_reserved_memory():
+ return EXTRA_RESERVED_VRAM
+
+def minimum_inference_memory():
+ return (1024 * 1024 * 1024) * 0.8 + extra_reserved_memory()
+
+def free_memory(memory_required, device, keep_loaded=[], for_dynamic=False, pins_required=0, ram_required=0):
+ cleanup_models_gc()
+ if not for_dynamic:
+ detail("Non dynamic memory free called! memory_required=%s pins_required=%s ram_required=%s", memory_required, pins_required, ram_required)
+ unloaded_model = []
+ can_unload = []
+ unloaded_models = []
+
+ for i in range(len(current_loaded_models) -1, -1, -1):
+ shift_model = current_loaded_models[i]
+ if device is None or shift_model.device == device:
+ if shift_model not in keep_loaded and not shift_model.is_dead():
+ can_unload.append((-shift_model.model_offloaded_memory(), sys.getrefcount(shift_model.model), shift_model.model_memory(), i))
+ shift_model.currently_used = False
+
+ can_unload_sorted = sorted(can_unload)
+ for x in can_unload_sorted:
+ i = x[-1]
+ memory_to_free = 1e32
+ if not DISABLE_SMART_MEMORY or device is None:
+ memory_to_free = 0 if device is None else memory_required - get_free_memory(device)
+ if current_loaded_models[i].model.is_dynamic() and for_dynamic:
+ #don't actually unload dynamic models for the sake of other dynamic models
+ #as that works on-demand.
+ memory_required -= current_loaded_models[i].model.loaded_size()
+ memory_to_free = 0
+ if memory_to_free > 0 and current_loaded_models[i].model_unload(memory_to_free):
+ logging.debug(f"Unloading {current_loaded_models[i].model.model.__class__.__name__}")
+ unloaded_model.append(i)
+
+ for i in sorted(unloaded_model, reverse=True):
+ unloaded_models.append(current_loaded_models.pop(i))
+
+ if not for_dynamic and pins_required > 0:
+ ensure_pin_budget(pins_required)
+ ensure_pin_registerable(pins_required)
+
+ if len(unloaded_model) > 0:
+ soft_empty_cache()
+ elif device is not None:
+ if vram_state != VRAMState.HIGH_VRAM:
+ mem_free_total, mem_free_torch = get_free_memory(device, torch_free_too=True)
+ if mem_free_torch > mem_free_total * 0.25:
+ soft_empty_cache()
+ return unloaded_models
+
+def load_models_gpu(models, memory_required=0, force_patch_weights=False, minimum_memory_required=None, force_full_load=False):
+ cleanup_models_gc()
+ global vram_state
+
+ inference_memory = minimum_inference_memory()
+ extra_mem = max(inference_memory, memory_required + extra_reserved_memory())
+ if minimum_memory_required is None:
+ minimum_memory_required = extra_mem
+ else:
+ minimum_memory_required = max(inference_memory, minimum_memory_required + extra_reserved_memory())
+
+ # Order-preserving dedup. A plain set() would randomize iteration order across runs
+ models_temp = {}
+ for m in models:
+ models_temp[m] = None
+ for mm in m.model_patches_models():
+ models_temp[mm] = None
+
+ models = list(models_temp)
+ models.reverse()
+
+ models_to_load = []
+
+ free_for_dynamic=True
+ for x in models:
+ if not x.is_dynamic():
+ free_for_dynamic = False
+ loaded_model = LoadedModel(x)
+ try:
+ loaded_model_index = current_loaded_models.index(loaded_model)
+ except:
+ loaded_model_index = None
+
+ if loaded_model_index is not None:
+ loaded = current_loaded_models[loaded_model_index]
+ loaded.currently_used = True
+ models_to_load.append(loaded)
+ else:
+ if hasattr(x, "model"):
+ logging.info(f"Requested to load {x.model.__class__.__name__}")
+ models_to_load.append(loaded_model)
+
+ for loaded_model in models_to_load:
+ to_unload = []
+ for i in range(len(current_loaded_models)):
+ if loaded_model.model.is_clone(current_loaded_models[i].model):
+ to_unload = [i] + to_unload
+ for i in to_unload:
+ model_to_unload = current_loaded_models.pop(i)
+ model_to_unload.model.detach(unpatch_all=False)
+ model_to_unload.model_finalizer.detach()
+
+ total_memory_required = {}
+ total_pins_required = {}
+ for loaded_model in models_to_load:
+ device = loaded_model.device
+ total_memory_required[device] = total_memory_required.get(device, 0) + loaded_model.model_memory_required(device)
+ if not loaded_model.model.is_dynamic():
+ total_pins_required[device] = total_pins_required.get(device, 0) + loaded_model.model_memory()
+
+ for device in total_memory_required:
+ if device != torch.device("cpu"):
+ free_memory(total_memory_required[device] * 1.1 + extra_mem,
+ device,
+ for_dynamic=free_for_dynamic,
+ pins_required=total_pins_required.get(device, 0))
+
+ for device in total_memory_required:
+ if device != torch.device("cpu"):
+ free_mem = get_free_memory(device)
+ if free_mem < minimum_memory_required:
+ models_l = free_memory(minimum_memory_required, device, for_dynamic=free_for_dynamic)
+ logging.info("{} models unloaded.".format(len(models_l)))
+
+ for loaded_model in models_to_load:
+ model = loaded_model.model
+ torch_dev = model.load_device
+ if is_device_cpu(torch_dev):
+ vram_set_state = VRAMState.DISABLED
+ else:
+ vram_set_state = vram_state
+ lowvram_model_memory = 0
+ if lowvram_available and (vram_set_state == VRAMState.LOW_VRAM or vram_set_state == VRAMState.NORMAL_VRAM) and not force_full_load:
+ loaded_memory = loaded_model.model_loaded_memory()
+ current_free_mem = get_free_memory(torch_dev) + loaded_memory
+
+ lowvram_model_memory = max(0, (current_free_mem - minimum_memory_required), min(current_free_mem * MIN_WEIGHT_MEMORY_RATIO, current_free_mem - minimum_inference_memory()))
+ lowvram_model_memory = lowvram_model_memory - loaded_memory
+
+ if lowvram_model_memory == 0:
+ lowvram_model_memory = 0.1
+
+ if vram_set_state == VRAMState.NO_VRAM:
+ lowvram_model_memory = 0.1
+
+ loaded_model.model_load(lowvram_model_memory, force_patch_weights=force_patch_weights)
+ vram_used = 0 if is_device_cpu(torch_dev) else loaded_model.model_loaded_memory()
+ ram_used = model.loaded_ram_size() if model.is_dynamic() else loaded_model.model_memory() - vram_used
+ detail("Model loaded: patcher=%s model=%s ram_mb=%.1f vram_mb=%.1f", model.__class__.__name__, model.model.__class__.__name__, ram_used / (1024 ** 2), vram_used / (1024 ** 2))
+ current_loaded_models.insert(0, loaded_model)
+ return
+
+def load_model_gpu(model):
+ return load_models_gpu([model])
+
+def loaded_models(only_currently_used=False):
+ output = []
+ for m in current_loaded_models:
+ if only_currently_used:
+ if not m.currently_used:
+ continue
+
+ output.append(m.model)
+ return output
+
+
+def cleanup_models_gc():
+ do_gc = False
+
+ for i in range(len(current_loaded_models)):
+ cur = current_loaded_models[i]
+ if cur.is_dead():
+ logging.info("Potential memory leak detected with model {}, doing a full garbage collect, for maximum performance avoid circular references in the model code.".format(cur.real_model().__class__.__name__))
+ do_gc = True
+ break
+
+ if do_gc:
+ gc.collect()
+ soft_empty_cache()
+
+ for i in range(len(current_loaded_models)):
+ cur = current_loaded_models[i]
+ if cur.is_dead():
+ logging.warning("WARNING, memory leak with model {}. Please make sure it is not being referenced from somewhere.".format(cur.real_model().__class__.__name__))
+
+
+def archive_model_dtypes(model):
+ for name, module in model.named_modules():
+ for param_name, param in module.named_parameters(recurse=False):
+ setattr(module, f"{param_name}_comfy_model_dtype", param.dtype)
+ for buf_name, buf in module.named_buffers(recurse=False):
+ setattr(module, f"{buf_name}_comfy_model_dtype", buf.dtype)
+
+
+def cleanup_models():
+ to_delete = []
+ for i in range(len(current_loaded_models)):
+ if current_loaded_models[i].real_model() is None:
+ to_delete = [i] + to_delete
+
+ for i in to_delete:
+ x = current_loaded_models.pop(i)
+ del x
+
+def dtype_size(dtype):
+ dtype_size = 4
+ if dtype == torch.float16 or dtype == torch.bfloat16:
+ dtype_size = 2
+ elif dtype == torch.float32:
+ dtype_size = 4
+ else:
+ try:
+ dtype_size = dtype.itemsize
+ except: #Old pytorch doesn't have .itemsize
+ pass
+ return dtype_size
+
+def unet_offload_device():
+ if vram_state == VRAMState.HIGH_VRAM:
+ return get_torch_device()
+ else:
+ return torch.device("cpu")
+
+def unet_inital_load_device(parameters, dtype):
+ cpu_dev = torch.device("cpu")
+ if comfy.memory_management.aimdo_enabled:
+ return cpu_dev
+
+ torch_dev = get_torch_device()
+ if vram_state == VRAMState.HIGH_VRAM or vram_state == VRAMState.SHARED:
+ return torch_dev
+
+ if DISABLE_SMART_MEMORY or vram_state == VRAMState.NO_VRAM:
+ return cpu_dev
+
+ model_size = dtype_size(dtype) * parameters
+
+ mem_dev = get_free_memory(torch_dev)
+ mem_cpu = get_free_memory(cpu_dev)
+ if mem_dev > mem_cpu and model_size < mem_dev:
+ return torch_dev
+ else:
+ return cpu_dev
+
+def maximum_vram_for_weights(device=None):
+ return (get_total_memory(device) * 0.88 - minimum_inference_memory())
+
+def unet_dtype(device=None, model_params=0, supported_dtypes=[torch.float16, torch.bfloat16, torch.float32], weight_dtype=None):
+ if model_params < 0:
+ model_params = 1000000000000000000000
+ if args.fp32_unet:
+ return torch.float32
+ if args.fp64_unet:
+ return torch.float64
+ if args.bf16_unet:
+ return torch.bfloat16
+ if args.fp16_unet:
+ return torch.float16
+ if args.fp8_e4m3fn_unet:
+ return torch.float8_e4m3fn
+ if args.fp8_e5m2_unet:
+ return torch.float8_e5m2
+ if args.fp8_e8m0fnu_unet:
+ return torch.float8_e8m0fnu
+
+ fp8_dtype = None
+ if weight_dtype in FLOAT8_TYPES:
+ fp8_dtype = weight_dtype
+
+ if fp8_dtype is not None:
+ if supports_fp8_compute(device): #if fp8 compute is supported the casting is most likely not expensive
+ return fp8_dtype
+
+ free_model_memory = maximum_vram_for_weights(device)
+ if model_params * 2 > free_model_memory:
+ return fp8_dtype
+
+ if PRIORITIZE_FP16 or weight_dtype == torch.float16:
+ if torch.float16 in supported_dtypes and should_use_fp16(device=device, model_params=model_params):
+ return torch.float16
+
+ for dt in supported_dtypes:
+ if dt == torch.float16 and should_use_fp16(device=device, model_params=model_params):
+ if torch.float16 in supported_dtypes:
+ return torch.float16
+ if dt == torch.bfloat16 and should_use_bf16(device, model_params=model_params):
+ if torch.bfloat16 in supported_dtypes:
+ return torch.bfloat16
+
+ for dt in supported_dtypes:
+ if dt == torch.float16 and should_use_fp16(device=device, model_params=model_params, manual_cast=True):
+ if torch.float16 in supported_dtypes:
+ return torch.float16
+ if dt == torch.bfloat16 and should_use_bf16(device, model_params=model_params, manual_cast=True):
+ if torch.bfloat16 in supported_dtypes:
+ return torch.bfloat16
+
+ return torch.float32
+
+# None means no manual cast
+def unet_manual_cast(weight_dtype, inference_device, supported_dtypes=[torch.float16, torch.bfloat16, torch.float32]):
+ if weight_dtype == torch.float32 or weight_dtype == torch.float64:
+ return None
+
+ fp16_supported = should_use_fp16(inference_device, prioritize_performance=False)
+ if fp16_supported and weight_dtype == torch.float16:
+ return None
+
+ bf16_supported = should_use_bf16(inference_device)
+ if bf16_supported and weight_dtype == torch.bfloat16:
+ return None
+
+ fp16_supported = should_use_fp16(inference_device, prioritize_performance=True)
+ if PRIORITIZE_FP16 and fp16_supported and torch.float16 in supported_dtypes:
+ return torch.float16
+
+ for dt in supported_dtypes:
+ if dt == torch.float16 and fp16_supported:
+ return torch.float16
+ if dt == torch.bfloat16 and bf16_supported:
+ return torch.bfloat16
+
+ return torch.float32
+
+def text_encoder_offload_device():
+ if args.gpu_only:
+ return get_torch_device()
+ else:
+ return torch.device("cpu")
+
+def text_encoder_device():
+ if args.gpu_only:
+ return get_torch_device()
+ elif vram_state in (VRAMState.HIGH_VRAM, VRAMState.NORMAL_VRAM) or comfy.memory_management.aimdo_enabled:
+ if should_use_fp16(prioritize_performance=False):
+ return get_torch_device()
+ else:
+ return torch.device("cpu")
+ else:
+ return torch.device("cpu")
+
+def text_encoder_initial_device(load_device, offload_device, model_size=0):
+ if comfy.memory_management.aimdo_enabled:
+ return offload_device
+
+ if load_device == offload_device or model_size <= 1024 * 1024 * 1024:
+ return offload_device
+
+ if is_device_mps(load_device):
+ return load_device
+
+ mem_l = get_free_memory(load_device)
+ mem_o = get_free_memory(offload_device)
+ if mem_l > (mem_o * 0.5) and model_size * 1.2 < mem_l:
+ return load_device
+ else:
+ return offload_device
+
+def text_encoder_dtype(device=None):
+ if args.fp8_e4m3fn_text_enc:
+ return torch.float8_e4m3fn
+ elif args.fp8_e5m2_text_enc:
+ return torch.float8_e5m2
+ elif args.fp16_text_enc:
+ return torch.float16
+ elif args.bf16_text_enc:
+ return torch.bfloat16
+ elif args.fp32_text_enc:
+ return torch.float32
+
+ if is_device_cpu(device):
+ return torch.float16
+
+ return torch.float16
+
+
+def intermediate_device():
+ if args.gpu_only:
+ return get_torch_device()
+ else:
+ return torch.device("cpu")
+
+def intermediate_dtype():
+ if args.fp16_intermediates:
+ return torch.float16
+ else:
+ return torch.float32
+
+def vae_device():
+ if args.cpu_vae:
+ return torch.device("cpu")
+ return get_torch_device()
+
+def vae_offload_device():
+ if args.gpu_only:
+ return get_torch_device()
+ else:
+ return torch.device("cpu")
+
+def vae_dtype(device=None, allowed_dtypes=[]):
+ if args.fp16_vae:
+ return torch.float16
+ elif args.bf16_vae:
+ return torch.bfloat16
+ elif args.fp32_vae:
+ return torch.float32
+
+ for d in allowed_dtypes:
+ if d == torch.float16 and should_use_fp16(device):
+ return d
+
+ if d == torch.bfloat16 and should_use_bf16(device):
+ return d
+
+ return torch.float32
+
+def get_autocast_device(dev):
+ if hasattr(dev, 'type'):
+ return dev.type
+ return "cuda"
+
+def supports_dtype(device, dtype): #TODO
+ if dtype == torch.float32:
+ return True
+ if is_device_cpu(device):
+ return False
+ if dtype == torch.float16:
+ return True
+ if dtype == torch.bfloat16:
+ return True
+ return False
+
+def supports_cast(device, dtype): #TODO
+ if dtype == torch.float32:
+ return True
+ if dtype == torch.float16:
+ return True
+ if directml_enabled: #TODO: test this
+ return False
+ if dtype == torch.bfloat16:
+ return True
+ if is_device_mps(device):
+ return False
+ if dtype == torch.float8_e4m3fn:
+ return True
+ if dtype == torch.float8_e5m2:
+ return True
+ return False
+
+def pick_weight_dtype(dtype, fallback_dtype, device=None):
+ if dtype is None:
+ dtype = fallback_dtype
+ elif dtype_size(dtype) > dtype_size(fallback_dtype):
+ dtype = fallback_dtype
+
+ if not supports_cast(device, dtype):
+ dtype = fallback_dtype
+
+ return dtype
+
+def device_supports_non_blocking(device):
+ if args.force_non_blocking:
+ return True
+ if is_device_mps(device):
+ return False #pytorch bug? mps doesn't support non blocking
+ if is_intel_xpu(): #xpu does support non blocking but it is slower on iGPUs for some reason so disable by default until situation changes
+ return False
+ if args.deterministic: #TODO: figure out why deterministic breaks non blocking from gpu to cpu (previews)
+ return False
+ if directml_enabled:
+ return False
+ return True
+
+def force_channels_last():
+ if args.force_channels_last:
+ return True
+
+ #TODO
+ return False
+
+
+STREAMS = {}
+NUM_STREAMS = 0
+if args.async_offload is not None:
+ NUM_STREAMS = args.async_offload
+else:
+ # Enable by default on Nvidia and AMD
+ if is_nvidia() or is_amd():
+ NUM_STREAMS = 2
+
+if args.disable_async_offload:
+ NUM_STREAMS = 0
+
+if NUM_STREAMS > 0:
+ logging.info("Using async weight offloading with {} streams".format(NUM_STREAMS))
+
+def current_stream(device):
+ if device is None:
+ return None
+ if is_device_cuda(device):
+ return torch.cuda.current_stream()
+ elif is_device_xpu(device):
+ return torch.xpu.current_stream()
+ else:
+ return None
+
+stream_counters = {}
+
+STREAM_CAST_BUFFERS = {}
+LARGEST_CASTED_WEIGHT = (None, 0)
+STREAM_AIMDO_CAST_BUFFERS = {}
+LARGEST_AIMDO_CASTED_WEIGHT = (None, 0)
+
+DEFAULT_AIMDO_CAST_BUFFER_RESERVATION_SIZE = 16 * 1024 ** 3
+
+def get_cast_buffer(offload_stream, device, size, ref):
+ global LARGEST_CASTED_WEIGHT
+
+ if offload_stream is not None:
+ wf_context = offload_stream
+ if hasattr(wf_context, "as_context"):
+ wf_context = wf_context.as_context(offload_stream)
+ else:
+ wf_context = nullcontext()
+
+ cast_buffer = STREAM_CAST_BUFFERS.get(offload_stream, None)
+ if cast_buffer is None or cast_buffer.numel() < size:
+ if ref is LARGEST_CASTED_WEIGHT[0]:
+ #If there is one giant weight we do not want both streams to
+ #allocate a buffer for it. It's up to the caster to get the other
+ #offload stream in this corner case
+ return None
+ if cast_buffer is not None and cast_buffer.numel() > 50 * (1024 ** 2):
+ #I want my wrongly sized 50MB+ of VRAM back from the caching allocator right now
+ synchronize()
+ del STREAM_CAST_BUFFERS[offload_stream]
+ del cast_buffer
+ soft_empty_cache()
+ with wf_context:
+ cast_buffer = torch.empty((size), dtype=torch.int8, device=device)
+ STREAM_CAST_BUFFERS[offload_stream] = cast_buffer
+
+ if size > LARGEST_CASTED_WEIGHT[1]:
+ LARGEST_CASTED_WEIGHT = (ref, size)
+
+ return cast_buffer
+
+def get_aimdo_cast_buffer(offload_stream, device):
+ cast_buffer = STREAM_AIMDO_CAST_BUFFERS.get(offload_stream, None)
+ if cast_buffer is None:
+ cast_buffer = comfy_aimdo.vram_buffer.VRAMBuffer(DEFAULT_AIMDO_CAST_BUFFER_RESERVATION_SIZE, device.index)
+ STREAM_AIMDO_CAST_BUFFERS[offload_stream] = cast_buffer
+ return cast_buffer
+
+def reset_cast_buffers():
+ global LARGEST_CASTED_WEIGHT
+ global LARGEST_AIMDO_CASTED_WEIGHT
+
+ LARGEST_CASTED_WEIGHT = (None, 0)
+ LARGEST_AIMDO_CASTED_WEIGHT = (None, 0)
+ for offload_stream in set(STREAM_CAST_BUFFERS) | set(STREAM_AIMDO_CAST_BUFFERS):
+ if offload_stream is not None:
+ offload_stream.synchronize()
+ synchronize()
+
+ for mmap_obj in DIRTY_MMAPS:
+ mmap_obj.bounce()
+ DIRTY_MMAPS.clear()
+
+ for loaded_model in current_loaded_models:
+ model = loaded_model.model
+ if model is not None and model.is_dynamic():
+ pin_state = model.model.dynamic_pins[model.load_device]
+
+ if pin_state["active"]:
+ for subset in ("weights", "weights-loaded"):
+ *_, buckets = pin_state[subset]
+ for size, bucket in list(buckets.items()):
+ bucket[:] = [ entry for entry in bucket if entry[-1] is not None ]
+ if not bucket:
+ del buckets[size]
+
+ pin_state["active"] = False
+ model.partially_unload_ram(1e30, subsets=[ "patches", "patches-loaded" ])
+ for subset in ("patches", "patches-loaded"):
+ pin_state[subset] = (comfy_aimdo.host_buffer.HostBuffer(0, 8 * 1024 * 1024, pinned_hostbuf_size(model.model_size())), [], [-1], [0], [0], {})
+
+ STREAM_CAST_BUFFERS.clear()
+ STREAM_AIMDO_CAST_BUFFERS.clear()
+ soft_empty_cache()
+
+def get_offload_stream(device):
+ stream_counter = stream_counters.get(device, 0)
+ if NUM_STREAMS == 0:
+ return None
+
+ if torch.compiler.is_compiling():
+ return None
+
+ if device in STREAMS:
+ ss = STREAMS[device]
+ #Sync the oldest stream in the queue with the current
+ ss[stream_counter].wait_stream(current_stream(device))
+ stream_counter = (stream_counter + 1) % len(ss)
+ stream_counters[device] = stream_counter
+ return ss[stream_counter]
+ elif is_device_cuda(device):
+ ss = []
+ for k in range(NUM_STREAMS):
+ s1 = torch.cuda.Stream(device=device, priority=0)
+ s1.as_context = torch.cuda.stream
+ ss.append(s1)
+ STREAMS[device] = ss
+ s = ss[stream_counter]
+ stream_counters[device] = stream_counter
+ return s
+ elif is_device_xpu(device):
+ ss = []
+ for k in range(NUM_STREAMS):
+ s1 = torch.xpu.Stream(device=device, priority=0)
+ s1.as_context = torch.xpu.stream
+ ss.append(s1)
+ STREAMS[device] = ss
+ s = ss[stream_counter]
+ stream_counters[device] = stream_counter
+ return s
+ return None
+
+def sync_stream(device, stream):
+ if stream is None or current_stream(device) is None:
+ return
+ current_stream(device).wait_stream(stream)
+
+
+def cast_to_gathered(tensors, r, non_blocking=False, stream=None, r2=None):
+ wf_context = nullcontext()
+ if stream is not None:
+ wf_context = stream
+ if hasattr(wf_context, "as_context"):
+ wf_context = wf_context.as_context(stream)
+
+ dest_views = comfy.memory_management.interpret_gathered_like(tensors, r) if r is not None else [None] * len(tensors)
+ dest2_views = comfy.memory_management.interpret_gathered_like(tensors, r2) if r2 is not None else None
+ with wf_context:
+ for tensor in tensors:
+ dest_view = dest_views.pop(0)
+ dest2_view = dest2_views.pop(0) if dest2_views is not None else None
+ if tensor is None:
+ continue
+ if comfy.memory_management.read_tensor_file_slice_into(tensor, dest_view, stream=stream, destination2=dest2_view):
+ continue
+ storage = tensor._qdata.untyped_storage() if isinstance(tensor, comfy.quant_ops.QuantizedTensor) else tensor.untyped_storage()
+ mark_mmap_dirty(storage)
+ if dest_view is not None:
+ dest_view.copy_(tensor, non_blocking=non_blocking)
+ if dest2_view is not None:
+ dest2_view.copy_(tensor if dest_view is None else dest_view, non_blocking=non_blocking)
+
+
+def cast_to(weight, dtype=None, device=None, non_blocking=False, copy=False, stream=None, r=None):
+ if device is None or weight.device == device:
+ if not copy:
+ if dtype is None or weight.dtype == dtype:
+ return weight
+ if stream is not None:
+ wf_context = stream
+ if hasattr(wf_context, "as_context"):
+ wf_context = wf_context.as_context(stream)
+ with wf_context:
+ return weight.to(dtype=dtype, copy=copy)
+ return weight.to(dtype=dtype, copy=copy)
+
+
+ if stream is not None:
+ wf_context = stream
+ if hasattr(wf_context, "as_context"):
+ wf_context = wf_context.as_context(stream)
+ with wf_context:
+ if r is None:
+ r = torch.empty_like(weight, dtype=dtype, device=device)
+ r.copy_(weight, non_blocking=non_blocking)
+ else:
+ if r is None:
+ r = torch.empty_like(weight, dtype=dtype, device=device)
+ r.copy_(weight, non_blocking=non_blocking)
+ return r
+
+def cast_to_device(tensor, device, dtype, copy=False):
+ non_blocking = device_supports_non_blocking(device)
+ return cast_to(tensor, dtype=dtype, device=device, non_blocking=non_blocking, copy=copy)
+
+
+PINNED_MEMORY = {}
+TOTAL_PINNED_MEMORY = 0
+MAX_PINNED_MEMORY = -1
+
+def get_disk_swap_total():
+ if not os.path.exists("/proc/swaps"):
+ return 0
+
+ total = 0
+ try:
+ with open("/proc/swaps", encoding="utf-8") as swaps:
+ next(swaps, None)
+ for line in swaps:
+ filename, _, size, _, _ = line.rsplit(maxsplit=4)
+ if os.path.basename(os.path.realpath(filename)).startswith("zram"):
+ continue
+ total += int(size) * 1024
+ except:
+ logging.warning("Could not get amount of swap memory on system.")
+ return total
+
+if not args.disable_pinned_memory:
+ if is_nvidia() or is_amd():
+ ram = get_total_memory(torch.device("cpu"))
+ if WINDOWS:
+ MAX_PINNED_MEMORY = ram * 0.40 # Windows limit is apparently 50%
+ else:
+ MAX_PINNED_MEMORY = max(ram * 0.40, min(ram * 0.90, ram - 4 * 1024 ** 3, ram + get_disk_swap_total() - 16 * 1024 ** 3))
+ logging.info("Enabled pinned memory {}".format(MAX_PINNED_MEMORY // (1024 * 1024)))
+
+PINNING_ALLOWED_TYPES = set(["Tensor", "Parameter", "QuantizedTensor"])
+
+def pinned_hostbuf_size(size):
+ if args.high_ram:
+ return max(0, int(size * 2))
+ return max(0, int(min(size, MAX_PINNED_MEMORY) * 2))
+
+def discard_cuda_async_error():
+ try:
+ a = torch.tensor([1], dtype=torch.uint8, device=get_torch_device())
+ b = torch.tensor([1], dtype=torch.uint8, device=get_torch_device())
+ _ = a + b
+ synchronize()
+ except RuntimeError:
+ #Dump it! We already know about it from the synchronous return
+ pass
+
+def pin_memory(tensor):
+ global TOTAL_PINNED_MEMORY
+ if MAX_PINNED_MEMORY <= 0:
+ return False
+
+ if type(tensor).__name__ not in PINNING_ALLOWED_TYPES:
+ return False
+
+ if not is_device_cpu(tensor.device):
+ return False
+
+ if tensor.is_pinned():
+ #NOTE: Cuda does detect when a tensor is already pinned and would
+ #error below, but there are proven cases where this also queues an error
+ #on the GPU async. So dont trust the CUDA API and guard here
+ return False
+
+ if not tensor.is_contiguous():
+ return False
+
+ size = tensor.nbytes
+ comfy.memory_management.extra_ram_release(comfy.memory_management.RAM_CACHE_HEADROOM)
+ ensure_pin_registerable(size)
+
+ ptr = tensor.data_ptr()
+ if ptr == 0:
+ return False
+
+ if torch.cuda.cudart().cudaHostRegister(ptr, size, 1) == 0:
+ PINNED_MEMORY[ptr] = size
+ TOTAL_PINNED_MEMORY += size
+ return True
+ else:
+ logging.warning("Pin error.")
+ discard_cuda_async_error()
+
+ return False
+
+def unpin_memory(tensor):
+ global TOTAL_PINNED_MEMORY
+ if MAX_PINNED_MEMORY <= 0:
+ return False
+
+ if not is_device_cpu(tensor.device):
+ return False
+
+ ptr = tensor.data_ptr()
+ size = tensor.nbytes
+
+ size_stored = PINNED_MEMORY.get(ptr, None)
+ if size_stored is None:
+ logging.warning("Tried to unpin tensor not pinned by ComfyUI")
+ return False
+
+ if size != size_stored:
+ logging.warning("Size of pinned tensor changed")
+ return False
+
+ if torch.cuda.cudart().cudaHostUnregister(ptr) == 0:
+ size = PINNED_MEMORY.pop(ptr)
+ TOTAL_PINNED_MEMORY -= size
+ return True
+ else:
+ logging.warning("Unpin error.")
+ discard_cuda_async_error()
+
+ return False
+
+def sage_attention_enabled():
+ return args.use_sage_attention
+
+def flash_attention_enabled():
+ return args.use_flash_attention
+
+def xformers_enabled():
+ global directml_enabled
+ global cpu_state
+ if cpu_state != CPUState.GPU:
+ return False
+ if is_intel_xpu():
+ return False
+ if is_ascend_npu():
+ return False
+ if is_mlu():
+ return False
+ if is_ixuca():
+ return False
+ if directml_enabled:
+ return False
+ return XFORMERS_IS_AVAILABLE
+
+
+def xformers_enabled_vae():
+ enabled = xformers_enabled()
+ if not enabled:
+ return False
+
+ return XFORMERS_ENABLED_VAE
+
+def pytorch_attention_enabled():
+ global ENABLE_PYTORCH_ATTENTION
+ return ENABLE_PYTORCH_ATTENTION
+
+def pytorch_attention_enabled_vae():
+ if is_amd():
+ return False # enabling pytorch attention on AMD currently causes crash when doing high res
+ return pytorch_attention_enabled()
+
+def pytorch_attention_flash_attention():
+ global ENABLE_PYTORCH_ATTENTION
+ if ENABLE_PYTORCH_ATTENTION:
+ #TODO: more reliable way of checking for flash attention?
+ if is_nvidia():
+ return True
+ if is_intel_xpu():
+ return True
+ if is_ascend_npu():
+ return True
+ if is_mlu():
+ return True
+ if is_amd():
+ return True #if you have pytorch attention enabled on AMD it probably supports at least mem efficient attention
+ if is_ixuca():
+ return True
+ return False
+
+def force_upcast_attention_dtype():
+ upcast = args.force_upcast_attention
+
+ macos_version = mac_version()
+ if macos_version is not None and ((14, 5) <= macos_version): # black image bug on recent versions of macOS, I don't think it's ever getting fixed
+ upcast = True
+
+ if upcast:
+ return {torch.float16: torch.float32}
+ else:
+ return None
+
+def get_free_memory(dev=None, torch_free_too=False):
+ global directml_enabled
+ if dev is None:
+ dev = get_torch_device()
+
+ if hasattr(dev, 'type') and (dev.type == 'cpu' or dev.type == 'mps'):
+ mem_free_total = psutil.virtual_memory().available
+ mem_free_torch = mem_free_total
+ else:
+ if directml_enabled:
+ mem_free_total = 1024 * 1024 * 1024 #TODO
+ mem_free_torch = mem_free_total
+ elif is_intel_xpu():
+ stats = torch.xpu.memory_stats(dev)
+ mem_active = stats['active_bytes.all.current']
+ mem_reserved = stats['reserved_bytes.all.current']
+ mem_free_xpu = torch.xpu.get_device_properties(dev).total_memory - mem_reserved
+ mem_free_torch = mem_reserved - mem_active
+ mem_free_total = mem_free_xpu + mem_free_torch
+ elif is_ascend_npu():
+ stats = torch.npu.memory_stats(dev)
+ mem_active = stats['active_bytes.all.current']
+ mem_reserved = stats['reserved_bytes.all.current']
+ mem_free_npu, _ = torch.npu.mem_get_info(dev)
+ mem_free_torch = mem_reserved - mem_active
+ mem_free_total = mem_free_npu + mem_free_torch
+ elif is_mlu():
+ stats = torch.mlu.memory_stats(dev)
+ mem_active = stats['active_bytes.all.current']
+ mem_reserved = stats['reserved_bytes.all.current']
+ mem_free_mlu, _ = torch.mlu.mem_get_info(dev)
+ mem_free_torch = mem_reserved - mem_active
+ mem_free_total = mem_free_mlu + mem_free_torch
+ else:
+ stats = torch.cuda.memory_stats(dev)
+ mem_active = stats['active_bytes.all.current']
+ mem_reserved = stats['reserved_bytes.all.current']
+ mem_free_cuda, _ = torch.cuda.mem_get_info(dev)
+ mem_free_torch = mem_reserved - mem_active
+ mem_free_total = mem_free_cuda + mem_free_torch
+
+ if torch_free_too:
+ return (mem_free_total, mem_free_torch)
+ else:
+ return mem_free_total
+
+def cpu_mode():
+ global cpu_state
+ return cpu_state == CPUState.CPU
+
+def mps_mode():
+ global cpu_state
+ return cpu_state == CPUState.MPS
+
+def is_device_type(device, type):
+ if hasattr(device, 'type'):
+ if (device.type == type):
+ return True
+ return False
+
+def is_device_cpu(device):
+ return is_device_type(device, 'cpu')
+
+def is_device_mps(device):
+ return is_device_type(device, 'mps')
+
+def is_device_xpu(device):
+ return is_device_type(device, 'xpu')
+
+def is_device_cuda(device):
+ return is_device_type(device, 'cuda')
+
+def set_torch_device(device):
+ """Set the current device for the given torch device. Supports CUDA and XPU."""
+ if is_device_cuda(device):
+ torch.cuda.set_device(device)
+ elif is_device_xpu(device):
+ torch.xpu.set_device(device)
+
+def is_directml_enabled():
+ global directml_enabled
+ if directml_enabled:
+ return True
+
+ return False
+
+def should_use_fp16(device=None, model_params=0, prioritize_performance=True, manual_cast=False):
+ if device is not None:
+ if is_device_cpu(device):
+ return False
+
+ if args.force_fp16:
+ return True
+
+ if FORCE_FP32:
+ return False
+
+ if is_directml_enabled():
+ return True
+
+ if (device is not None and is_device_mps(device)) or mps_mode():
+ return True
+
+ if cpu_mode():
+ return False
+
+ if is_intel_xpu():
+ return torch.xpu.get_device_properties(device).has_fp16
+
+ if is_ascend_npu():
+ return True
+
+ if is_mlu():
+ return True
+
+ if is_ixuca():
+ return True
+
+ if torch.version.hip:
+ return True
+
+ props = torch.cuda.get_device_properties(device)
+ if props.major >= 8:
+ return True
+
+ if props.major < 6:
+ return False
+
+ #FP16 is confirmed working on a 1080 (GP104) and on latest pytorch actually seems faster than fp32
+ nvidia_10_series = ["1080", "1070", "titan x", "p3000", "p3200", "p4000", "p4200", "p5000", "p5200", "p6000", "1060", "1050", "p40", "p100", "p6", "p4"]
+ for x in nvidia_10_series:
+ if x in props.name.lower():
+ if WINDOWS or manual_cast:
+ return True
+ else:
+ return False #weird linux behavior where fp32 is faster
+
+ if manual_cast:
+ free_model_memory = maximum_vram_for_weights(device)
+ if (not prioritize_performance) or model_params * 4 > free_model_memory:
+ return True
+
+ if props.major < 7:
+ return False
+
+ #FP16 is just broken on these cards
+ nvidia_16_series = ["1660", "1650", "1630", "T500", "T550", "T600", "MX550", "MX450", "CMP 30HX", "T2000", "T1000", "T1200"]
+ for x in nvidia_16_series:
+ if x in props.name:
+ return False
+
+ return True
+
+def should_use_bf16(device=None, model_params=0, prioritize_performance=True, manual_cast=False):
+ if device is not None:
+ if is_device_cpu(device): #TODO ? bf16 works on CPU but is extremely slow
+ return False
+
+ if FORCE_FP32:
+ return False
+
+ if directml_enabled:
+ return False
+
+ if (device is not None and is_device_mps(device)) or mps_mode():
+ if mac_version() < (14,):
+ return False
+ return True
+
+ if cpu_mode():
+ return False
+
+ if is_intel_xpu():
+ return torch.xpu.is_bf16_supported()
+
+ if is_ascend_npu():
+ return True
+
+ if is_ixuca():
+ return True
+
+ if is_amd():
+ arch = torch.cuda.get_device_properties(device).gcnArchName
+ if any((a in arch) for a in AMD_RDNA2_AND_OLDER_ARCH): # RDNA2 and older don't support bf16
+ if manual_cast:
+ return True
+ return False
+
+ props = torch.cuda.get_device_properties(device)
+
+ if is_mlu():
+ if props.major > 3:
+ return True
+
+ if props.major >= 8:
+ return True
+
+ bf16_works = torch.cuda.is_bf16_supported()
+
+ if bf16_works and manual_cast:
+ free_model_memory = maximum_vram_for_weights(device)
+ if (not prioritize_performance) or model_params * 4 > free_model_memory:
+ return True
+
+ return False
+
+def supports_fp8_compute(device=None):
+ if SUPPORT_FP8_OPS:
+ return True
+
+ if not is_nvidia():
+ return False
+
+ props = torch.cuda.get_device_properties(device)
+ if props.major >= 9:
+ return True
+ if props.major < 8:
+ return False
+ if props.minor < 9:
+ return False
+
+ if torch_version_numeric < (2, 3):
+ return False
+
+ if WINDOWS:
+ if torch_version_numeric < (2, 4):
+ return False
+
+ return True
+
+def supports_nvfp4_compute(device=None):
+ if not is_nvidia():
+ return False
+
+ props = torch.cuda.get_device_properties(device)
+ if props.major < 10:
+ return False
+
+ return True
+
+def supports_mxfp8_compute(device=None):
+ if not is_nvidia():
+ return False
+
+ if torch_version_numeric < (2, 10):
+ return False
+
+ props = torch.cuda.get_device_properties(device)
+ if props.major < 10:
+ return False
+
+ return True
+
+def supports_fp64(device=None):
+ if is_device_mps(device):
+ return False
+
+ if is_intel_xpu():
+ return False
+
+ if is_directml_enabled():
+ return False
+
+ if is_ixuca():
+ return False
+
+ return True
+
+def extended_fp16_support():
+ # TODO: check why some models work with fp16 on newer torch versions but not on older
+ if torch_version_numeric < (2, 7):
+ return False
+
+ return True
+
+LORA_COMPUTE_DTYPES = {}
+def lora_compute_dtype(device):
+ dtype = LORA_COMPUTE_DTYPES.get(device, None)
+ if dtype is not None:
+ return dtype
+
+ if should_use_fp16(device):
+ dtype = torch.float16
+ else:
+ dtype = torch.float32
+
+ LORA_COMPUTE_DTYPES[device] = dtype
+ return dtype
+
+def synchronize():
+ if cpu_mode():
+ return
+ if is_intel_xpu():
+ torch.xpu.synchronize()
+ elif torch.cuda.is_available():
+ torch.cuda.synchronize()
+
+def soft_empty_cache(force=False):
+ if cpu_mode():
+ return
+ global cpu_state
+ if cpu_state == CPUState.MPS:
+ torch.mps.empty_cache()
+ elif is_intel_xpu():
+ torch.xpu.synchronize()
+ torch.xpu.empty_cache()
+ elif is_ascend_npu():
+ torch.npu.empty_cache()
+ elif is_mlu():
+ torch.mlu.empty_cache()
+ elif torch.cuda.is_available():
+ torch.cuda.synchronize()
+ torch.cuda.empty_cache()
+ torch.cuda.ipc_collect()
+
+def unload_all_models():
+ for device in get_all_torch_devices():
+ free_memory(1e30, device)
+
+def unload_model_and_clones(model: ModelPatcher, unload_additional_models=True, all_devices=False):
+ 'Unload only model and its clones - primarily for multigpu cloning purposes.'
+ initial_keep_loaded: list[LoadedModel] = current_loaded_models.copy()
+ additional_models = []
+ if unload_additional_models:
+ additional_models = model.get_nested_additional_models()
+ keep_loaded = []
+ for loaded_model in initial_keep_loaded:
+ if loaded_model.model is not None:
+ if model.clone_base_uuid == loaded_model.model.clone_base_uuid:
+ continue
+ # check additional models if they are a match
+ skip = False
+ for add_model in additional_models:
+ if add_model.clone_base_uuid == loaded_model.model.clone_base_uuid:
+ skip = True
+ break
+ if skip:
+ continue
+ keep_loaded.append(loaded_model)
+ if not all_devices:
+ free_memory(1e30, get_torch_device(), keep_loaded)
+ else:
+ for device in get_all_torch_devices():
+ free_memory(1e30, device, keep_loaded)
+
+def debug_memory_summary():
+ if is_amd() or is_nvidia():
+ return torch.cuda.memory.memory_summary()
+ return ""
+
+class InterruptProcessingException(BaseException):
+ pass
+
+interrupt_processing_mutex = threading.RLock()
+
+interrupt_processing = False
+def interrupt_current_processing(value=True):
+ global interrupt_processing
+ global interrupt_processing_mutex
+ with interrupt_processing_mutex:
+ interrupt_processing = value
+
+def processing_interrupted():
+ global interrupt_processing
+ global interrupt_processing_mutex
+ with interrupt_processing_mutex:
+ return interrupt_processing
+
+def throw_exception_if_processing_interrupted():
+ global interrupt_processing
+ global interrupt_processing_mutex
+ with interrupt_processing_mutex:
+ if interrupt_processing:
+ interrupt_processing = False
+ raise InterruptProcessingException()
diff --git a/ComfyUI/comfy/model_patcher.py b/ComfyUI/comfy/model_patcher.py
new file mode 100644
index 0000000000000000000000000000000000000000..ae3f0191d04b15ffc0abc9b970554ee2696c8c2e
--- /dev/null
+++ b/ComfyUI/comfy/model_patcher.py
@@ -0,0 +1,2142 @@
+"""
+ This file is part of ComfyUI.
+ Copyright (C) 2024 Comfy
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+"""
+
+from __future__ import annotations
+
+import collections
+import inspect
+import logging
+import math
+import time
+import uuid
+from typing import Callable, Optional
+
+import torch
+import tqdm
+
+import comfy.float
+import comfy.hooks
+import comfy.lora
+import comfy.model_management
+import comfy.ops
+import comfy.patcher_extension
+import comfy.utils
+import comfy_aimdo.host_buffer
+from comfy.comfy_types import UnetWrapperFunction
+from comfy.internal_logging import detail
+from comfy.quant_ops import QuantizedTensor
+from comfy.patcher_extension import CallbacksMP, PatcherInjection, WrappersMP
+
+import comfy_aimdo.model_vbar
+
+def is_model_patcher_output(output):
+ return isinstance(output, ModelPatcher) or isinstance(getattr(output, "patcher", None), ModelPatcher)
+
+class PromptModelTracker:
+ def __init__(self):
+ self.models = {}
+
+ def start(self):
+ self.end()
+
+ def add(self, outputs):
+ if isinstance(outputs, collections.abc.Mapping):
+ outputs = outputs.values()
+ elif not isinstance(outputs, (list, tuple)):
+ outputs = (outputs,)
+
+ for output in outputs:
+ if isinstance(output, (collections.abc.Mapping, list, tuple)):
+ self.add(output)
+ continue
+
+ models = []
+ if isinstance(output, ModelPatcher):
+ models.append(output)
+ models.extend(output.model_patches_models())
+ models.extend(output.get_nested_additional_models())
+ else:
+ patcher = getattr(output, "patcher", None)
+ if isinstance(patcher, ModelPatcher):
+ models.append(patcher)
+ get_models = getattr(output, "get_models", None)
+ if callable(get_models):
+ models.extend(get_models())
+
+ for model in models:
+ if not isinstance(model, ModelPatcher) or not model.is_dynamic():
+ continue
+ key = (id(model.model), model.load_device)
+ self.models[key] = model
+ model.set_in_use_by_current_prompt(True)
+
+ def end(self):
+ for model in self.models.values():
+ model.set_in_use_by_current_prompt(False)
+ self.models.clear()
+
+def set_model_options_patch_replace(model_options, patch, name, block_name, number, transformer_index=None):
+ to = model_options["transformer_options"].copy()
+
+ if "patches_replace" not in to:
+ to["patches_replace"] = {}
+ else:
+ to["patches_replace"] = to["patches_replace"].copy()
+
+ if name not in to["patches_replace"]:
+ to["patches_replace"][name] = {}
+ else:
+ to["patches_replace"][name] = to["patches_replace"][name].copy()
+
+ if transformer_index is not None:
+ block = (block_name, number, transformer_index)
+ else:
+ block = (block_name, number)
+ to["patches_replace"][name][block] = patch
+ model_options["transformer_options"] = to
+ return model_options
+
+def set_model_options_post_cfg_function(model_options, post_cfg_function, disable_cfg1_optimization=False):
+ model_options["sampler_post_cfg_function"] = model_options.get("sampler_post_cfg_function", []) + [post_cfg_function]
+ if disable_cfg1_optimization:
+ model_options["disable_cfg1_optimization"] = True
+ return model_options
+
+def set_model_options_pre_cfg_function(model_options, pre_cfg_function, disable_cfg1_optimization=False):
+ model_options["sampler_pre_cfg_function"] = model_options.get("sampler_pre_cfg_function", []) + [pre_cfg_function]
+ if disable_cfg1_optimization:
+ model_options["disable_cfg1_optimization"] = True
+ return model_options
+
+def create_model_options_clone(orig_model_options: dict):
+ return comfy.patcher_extension.copy_nested_dicts(orig_model_options)
+
+def create_hook_patches_clone(orig_hook_patches, copy_tuples=False):
+ new_hook_patches = {}
+ for hook_ref in orig_hook_patches:
+ new_hook_patches[hook_ref] = {}
+ for k in orig_hook_patches[hook_ref]:
+ new_hook_patches[hook_ref][k] = orig_hook_patches[hook_ref][k][:]
+ if copy_tuples:
+ for i in range(len(new_hook_patches[hook_ref][k])):
+ new_hook_patches[hook_ref][k][i] = tuple(new_hook_patches[hook_ref][k][i])
+ return new_hook_patches
+
+def wipe_lowvram_weight(m):
+ if hasattr(m, "prev_comfy_cast_weights"):
+ m.comfy_cast_weights = m.prev_comfy_cast_weights
+ del m.prev_comfy_cast_weights
+
+ if hasattr(m, "weight_function"):
+ m.weight_function = []
+
+ if hasattr(m, "bias_function"):
+ m.bias_function = []
+
+def move_weight_functions(m, device):
+ if device is None:
+ return 0
+
+ memory = 0
+ if hasattr(m, "weight_function"):
+ for f in m.weight_function:
+ if hasattr(f, "move_to"):
+ memory += f.move_to(device=device)
+
+ if hasattr(m, "bias_function"):
+ for f in m.bias_function:
+ if hasattr(f, "move_to"):
+ memory += f.move_to(device=device)
+ return memory
+
+def string_to_seed(data):
+ logging.warning("WARNING: string_to_seed has moved from comfy.model_patcher to comfy.utils")
+ return comfy.utils.string_to_seed(data)
+
+class LowVramPatch:
+ is_lowvram_patch = True
+
+ def __init__(self, key, patches, convert_func=None, set_func=None):
+ self.key = key
+ self.patches = patches
+ self.convert_func = convert_func # TODO: remove
+ self.set_func = set_func
+ self.prepared_patches = None
+
+ def memory_required(self):
+ counter = [0]
+ for patch in self.patches[self.key]:
+ comfy.lora.prefetch_prepared_value(patch[1], counter, None, None, False)
+ return counter[0]
+
+ def prepare(self, destination, stream, copy=True, commit=True):
+ counter = [0]
+ prepared_patches = [
+ (patch[0], comfy.lora.prefetch_prepared_value(patch[1], counter, destination, stream, copy), patch[2], patch[3], patch[4])
+ for patch in self.patches[self.key]
+ ]
+ if commit:
+ self.prepared_patches = prepared_patches
+ return prepared_patches
+
+ def clear_prepared(self):
+ self.prepared_patches = None
+
+ def __call__(self, weight):
+ patches = self.prepared_patches if self.prepared_patches is not None else self.patches[self.key]
+ return comfy.lora.calculate_weight(patches, weight, self.key, intermediate_dtype=weight.dtype)
+
+LOWVRAM_PATCH_ESTIMATE_MATH_FACTOR = 2
+
+def low_vram_patch_estimate_vram(model, key):
+ weight, set_func, convert_func = get_key_weight(model, key)
+ if weight is None:
+ return 0
+ model_dtype = getattr(model, "manual_cast_dtype", torch.float32)
+ if model_dtype is None:
+ model_dtype = weight.dtype
+
+ return weight.numel() * model_dtype.itemsize * LOWVRAM_PATCH_ESTIMATE_MATH_FACTOR
+
+def get_key_weight(model, key):
+ set_func = None
+ convert_func = None
+ op_keys = key.rsplit('.', 1)
+ if len(op_keys) < 2:
+ weight = comfy.utils.get_attr(model, key)
+ else:
+ op = comfy.utils.get_attr(model, op_keys[0])
+ try:
+ set_func = getattr(op, "set_{}".format(op_keys[1]))
+ except AttributeError:
+ pass
+
+ try:
+ convert_func = getattr(op, "convert_{}".format(op_keys[1]))
+ except AttributeError:
+ pass
+
+ weight = getattr(op, op_keys[1])
+ if convert_func is not None:
+ weight = comfy.utils.get_attr(model, key)
+
+ return weight, set_func, convert_func
+
+def key_param_name_to_key(key, param):
+ if len(key) == 0:
+ return param
+ return "{}.{}".format(key, param)
+
+class AutoPatcherEjector:
+ def __init__(self, model: 'ModelPatcher', skip_and_inject_on_exit_only=False):
+ self.model = model
+ self.was_injected = False
+ self.prev_skip_injection = False
+ self.skip_and_inject_on_exit_only = skip_and_inject_on_exit_only
+
+ def __enter__(self):
+ self.was_injected = False
+ self.prev_skip_injection = self.model.skip_injection
+ if self.skip_and_inject_on_exit_only:
+ self.model.skip_injection = True
+ if self.model.is_injected:
+ self.model.eject_model()
+ self.was_injected = True
+
+ def __exit__(self, *args):
+ if self.skip_and_inject_on_exit_only:
+ self.model.skip_injection = self.prev_skip_injection
+ self.model.inject_model()
+ if self.was_injected and not self.model.skip_injection:
+ self.model.inject_model()
+ self.model.skip_injection = self.prev_skip_injection
+
+class MemoryCounter:
+ def __init__(self, initial: int, minimum=0):
+ self.value = initial
+ self.minimum = minimum
+ # TODO: add a safe limit besides 0
+
+ def use(self, weight: torch.Tensor):
+ weight_size = weight.nelement() * weight.element_size()
+ if self.is_useable(weight_size):
+ self.decrement(weight_size)
+ return True
+ return False
+
+ def is_useable(self, used: int):
+ return self.value - used > self.minimum
+
+ def decrement(self, used: int):
+ self.value -= used
+
+CustomTorchDevice = collections.namedtuple("FakeDevice", ["type", "index"])("comfy-lazy-caster", 0)
+
+class LazyCastingParam(torch.nn.Parameter):
+ def __new__(cls, model, key, tensor):
+ return super().__new__(cls, tensor)
+
+ def __init__(self, model, key, tensor):
+ self.model = model
+ self.key = key
+
+ @property
+ def device(self):
+ return CustomTorchDevice
+
+ #safetensors will .to() us to the cpu which we catch here to cast on demand. The returned tensor is
+ #then just a short lived thing in the safetensors serialization logic inside its big for loop over
+ #all weights getting garbage collected per-weight
+ def to(self, *args, **kwargs):
+ return self.model.patch_weight_to_device(self.key, device_to=self.model.load_device, return_weight=True).to("cpu")
+
+
+class LazyCastingQuantizedParam:
+ def __init__(self, model, key):
+ self.model = model
+ self.key = key
+ self.cpu_state_dict = None
+
+ def state_dict_tensor(self, state_dict_key):
+ if self.cpu_state_dict is None:
+ weight = self.model.patch_weight_to_device(self.key, device_to=self.model.load_device, return_weight=True)
+ self.cpu_state_dict = {k: v.to("cpu") for k, v in weight.state_dict(self.key).items()}
+ return self.cpu_state_dict[state_dict_key]
+
+
+class LazyCastingParamPiece(torch.nn.Parameter):
+ def __new__(cls, caster, state_dict_key, tensor):
+ return super().__new__(cls, tensor)
+
+ def __init__(self, caster, state_dict_key, tensor):
+ self.caster = caster
+ self.state_dict_key = state_dict_key
+
+ @property
+ def device(self):
+ return CustomTorchDevice
+
+ def to(self, *args, **kwargs):
+ caster = self.caster
+ del self.caster
+ return caster.state_dict_tensor(self.state_dict_key)
+
+
+class ModelPatcher:
+ def __init__(self, model, load_device, offload_device, size=0, weight_inplace_update=False):
+ self.size = size
+ self.model = model
+ if not hasattr(self.model, 'device'):
+ logging.debug("Model doesn't have a device attribute.")
+ self.model.device = offload_device
+ elif self.model.device is None:
+ self.model.device = offload_device
+
+ self.patches = {}
+ self.backup = {}
+ self.backup_buffers = {}
+ self.object_patches = {}
+ self.object_patches_backup = {}
+ self.weight_wrapper_patches = {}
+ self.model_options = {"transformer_options":{}}
+ self.load_device = load_device
+ self.offload_device = offload_device
+ self.weight_inplace_update = weight_inplace_update
+ self.force_cast_weights = False
+ self.patches_uuid = uuid.uuid4()
+ self.parent = None
+ self.pinned = set()
+
+ self.attachments: dict[str] = {}
+ self.additional_models: dict[str, list[ModelPatcher]] = {}
+ self.callbacks: dict[str, dict[str, list[Callable]]] = CallbacksMP.init_callbacks()
+ self.wrappers: dict[str, dict[str, list[Callable]]] = WrappersMP.init_wrappers()
+
+ self.is_injected = False
+ self.skip_injection = False
+ self.injections: dict[str, list[PatcherInjection]] = {}
+
+ self.hook_patches: dict[comfy.hooks._HookRef] = {}
+ self.hook_patches_backup: dict[comfy.hooks._HookRef] = None
+ self.hook_backup: dict[str, tuple[torch.Tensor, torch.device]] = {}
+ self.cached_hook_patches: dict[comfy.hooks.HookGroup, dict[str, torch.Tensor]] = {}
+ self.current_hooks: Optional[comfy.hooks.HookGroup] = None
+ self.forced_hooks: Optional[comfy.hooks.HookGroup] = None # NOTE: only used for CLIP at this time
+ self.is_clip = False
+ self.hook_mode = comfy.hooks.EnumHookMode.MaxSpeed
+
+ self.cached_patcher_init: tuple[Callable, tuple] | tuple[Callable, tuple, int] | None = None
+ self.is_multigpu_base_clone = False
+ self.clone_base_uuid = uuid.uuid4()
+
+ if not hasattr(self.model, 'model_loaded_weight_memory'):
+ self.model.model_loaded_weight_memory = 0
+
+ if not hasattr(self.model, 'lowvram_patch_counter'):
+ self.model.lowvram_patch_counter = 0
+
+ if not hasattr(self.model, 'model_lowvram'):
+ self.model.model_lowvram = False
+
+ if not hasattr(self.model, 'current_weight_patches_uuid'):
+ self.model.current_weight_patches_uuid = None
+
+ if not hasattr(self.model, 'model_offload_buffer_memory'):
+ self.model.model_offload_buffer_memory = 0
+
+ def is_dynamic(self):
+ return False
+
+ def model_size(self):
+ if self.size > 0:
+ return self.size
+ self.size = comfy.model_management.module_size(self.model)
+ return self.size
+
+ def loaded_size(self):
+ return self.model.model_loaded_weight_memory
+
+ def lowvram_patch_counter(self):
+ return self.model.lowvram_patch_counter
+
+ def get_free_memory(self, device):
+ #Prioritize batching (incl. CFG/conds etc) over keeping the model resident. In
+ #the vast majority of setups a little bit of offloading on the giant model more
+ #than pays for CFG. So return everything both torch and Aimdo could give us
+ aimdo_mem = 0
+ if comfy.memory_management.aimdo_enabled:
+ aimdo_device = device.index if getattr(device, "type", None) == "cuda" else None
+ aimdo_mem = comfy_aimdo.model_vbar.vbars_analyze(aimdo_device)
+ return comfy.model_management.get_free_memory(device) + aimdo_mem
+
+ def get_clone_model_override(self):
+ return self.model, (self.backup, self.backup_buffers, self.object_patches_backup, self.pinned)
+
+ def clone(self, disable_dynamic=False, model_override=None, force_deepcopy=False):
+ class_ = self.__class__
+ if self.is_dynamic() and disable_dynamic or force_deepcopy:
+ if self.is_dynamic() and disable_dynamic:
+ class_ = ModelPatcher
+ if model_override is None:
+ if self.cached_patcher_init is None:
+ raise RuntimeError("Cannot create non-dynamic delegate: cached_patcher_init is not initialized.")
+ temp_model_patcher = self.cached_patcher_init[0](*self.cached_patcher_init[1], disable_dynamic=True)
+ if len(self.cached_patcher_init) > 2:
+ temp_model_patcher = temp_model_patcher[self.cached_patcher_init[2]]
+ model_override = temp_model_patcher.get_clone_model_override()
+ if model_override is None:
+ model_override = self.get_clone_model_override()
+
+ n = class_(model_override[0], self.load_device, self.offload_device, self.model_size(), weight_inplace_update=self.weight_inplace_update)
+ n.patches = {}
+ for k in self.patches:
+ n.patches[k] = self.patches[k][:]
+ n.patches_uuid = self.patches_uuid
+
+ n.object_patches = self.object_patches.copy()
+ n.weight_wrapper_patches = self.weight_wrapper_patches.copy()
+ n.model_options = comfy.utils.deepcopy_list_dict(self.model_options)
+ n.parent = self
+
+ n.force_cast_weights = self.force_cast_weights
+
+ n.backup, n.backup_buffers, n.object_patches_backup, n.pinned = model_override[1]
+
+ # attachments
+ n.attachments = {}
+ for k in self.attachments:
+ if hasattr(self.attachments[k], "on_model_patcher_clone"):
+ n.attachments[k] = self.attachments[k].on_model_patcher_clone()
+ else:
+ n.attachments[k] = self.attachments[k]
+ # additional models
+ for k, c in self.additional_models.items():
+ n.additional_models[k] = [x.clone() for x in c]
+ # callbacks
+ for k, c in self.callbacks.items():
+ n.callbacks[k] = {}
+ for k1, c1 in c.items():
+ n.callbacks[k][k1] = c1.copy()
+ # sample wrappers
+ for k, w in self.wrappers.items():
+ n.wrappers[k] = {}
+ for k1, w1 in w.items():
+ n.wrappers[k][k1] = w1.copy()
+ # injection
+ n.is_injected = self.is_injected
+ n.skip_injection = self.skip_injection
+ for k, i in self.injections.items():
+ n.injections[k] = i.copy()
+ # hooks
+ n.hook_patches = create_hook_patches_clone(self.hook_patches)
+ n.hook_patches_backup = create_hook_patches_clone(self.hook_patches_backup) if self.hook_patches_backup else self.hook_patches_backup
+ for group in self.cached_hook_patches:
+ n.cached_hook_patches[group] = {}
+ for k in self.cached_hook_patches[group]:
+ n.cached_hook_patches[group][k] = self.cached_hook_patches[group][k]
+ n.hook_backup = self.hook_backup
+ n.current_hooks = self.current_hooks.clone() if self.current_hooks else self.current_hooks
+ n.forced_hooks = self.forced_hooks.clone() if self.forced_hooks else self.forced_hooks
+ n.is_clip = self.is_clip
+ n.hook_mode = self.hook_mode
+
+ n.cached_patcher_init = self.cached_patcher_init
+ n.is_multigpu_base_clone = self.is_multigpu_base_clone
+ n.clone_base_uuid = self.clone_base_uuid
+
+ for callback in self.get_all_callbacks(CallbacksMP.ON_CLONE):
+ callback(self, n)
+ return n
+
+ def deepclone_multigpu(self, new_load_device=None, models_cache: dict[uuid.UUID,ModelPatcher]=None):
+ logging.info(f"Creating deepclone of {self.model.__class__.__name__} for {new_load_device if new_load_device else self.load_device}.")
+ if self.cached_patcher_init is None:
+ raise RuntimeError(
+ f"Cannot create multigpu deepclone of {self.model.__class__.__name__}: "
+ "the loader that produced this model does not support multigpu "
+ "(cached_patcher_init is not initialized). Use a core loader "
+ "(CheckpointLoaderSimple, UNETLoader, CLIPLoader/DualCLIPLoader, VAELoader), "
+ "or have the custom loader register a cached_patcher_init factory."
+ )
+ comfy.model_management.unload_model_and_clones(self)
+ # Produce a freshly-loaded patcher from the loader factory so the multigpu
+ # clone owns its own untainted model weights (rather than relying on
+ # copy.deepcopy of an already-patched/already-loaded module).
+ temp_model_patcher: ModelPatcher | list[ModelPatcher] = self.cached_patcher_init[0](*self.cached_patcher_init[1])
+ if len(self.cached_patcher_init) > 2:
+ temp_model_patcher = temp_model_patcher[self.cached_patcher_init[2]]
+ # Override clone()'s normal "share self.model + share backup containers" with
+ # the pristine model from temp_model_patcher plus empty backup containers --
+ # the fresh model has no patches applied, so any deepcopy of self's stale
+ # backup/object_patches_backup/pinned would just propagate dead state that
+ # no longer corresponds to anything in n.model.
+ model_override = (temp_model_patcher.model, ({}, {}, {}, set()))
+ n = self.clone(model_override=model_override)
+ # clone() copies hook_backup by reference from self; reset since model is pristine.
+ n.hook_backup = {}
+ # set load device, if present
+ if new_load_device is not None:
+ n.load_device = new_load_device
+ # Ensure any per-device bookkeeping (e.g. ModelPatcherDynamic.dynamic_pins)
+ # has an entry for n.load_device on the freshly-loaded n.model. temp_model_patcher's
+ # __init__ only registered its own (default) load_device.
+ if hasattr(n, "register_load_device"):
+ n.register_load_device(n.load_device)
+ # multigpu clone should not have multigpu additional_models entry
+ n.remove_additional_models("multigpu")
+ # multigpu_clone all stored additional_models; make sure circular references are properly handled
+ if models_cache is None:
+ models_cache = {}
+ for key, model_list in n.additional_models.items():
+ for i in range(len(model_list)):
+ add_model = n.additional_models[key][i]
+ if add_model.clone_base_uuid not in models_cache:
+ models_cache[add_model.clone_base_uuid] = add_model.deepclone_multigpu(new_load_device=new_load_device, models_cache=models_cache)
+ n.additional_models[key][i] = models_cache[add_model.clone_base_uuid]
+ for callback in self.get_all_callbacks(CallbacksMP.ON_DEEPCLONE_MULTIGPU):
+ callback(self, n)
+ return n
+
+ def match_multigpu_clones(self):
+ multigpu_models = self.get_additional_models_with_key("multigpu")
+ if len(multigpu_models) > 0:
+ new_multigpu_models = []
+ for mm in multigpu_models:
+ # clone main model, but bring over relevant props from existing multigpu clone
+ n = self.clone(model_override=mm.get_clone_model_override())
+ n.load_device = mm.load_device
+ n.hook_backup = mm.hook_backup
+ n.is_multigpu_base_clone = mm.is_multigpu_base_clone
+ n.remove_additional_models("multigpu")
+ orig_additional_models: dict[str, list[ModelPatcher]] = comfy.patcher_extension.copy_nested_dicts(n.additional_models)
+ n.additional_models = comfy.patcher_extension.copy_nested_dicts(mm.additional_models)
+ # figure out which additional models are not present in multigpu clone
+ models_cache = {}
+ for mm_add_model in mm.get_additional_models():
+ models_cache[mm_add_model.clone_base_uuid] = mm_add_model
+ remove_models_uuids = set(list(models_cache.keys()))
+ for key, model_list in orig_additional_models.items():
+ for orig_add_model in model_list:
+ if orig_add_model.clone_base_uuid not in models_cache:
+ models_cache[orig_add_model.clone_base_uuid] = orig_add_model.deepclone_multigpu(new_load_device=n.load_device, models_cache=models_cache)
+ existing_list = n.get_additional_models_with_key(key)
+ existing_list.append(models_cache[orig_add_model.clone_base_uuid])
+ n.set_additional_models(key, existing_list)
+ if orig_add_model.clone_base_uuid in remove_models_uuids:
+ remove_models_uuids.remove(orig_add_model.clone_base_uuid)
+ # remove duplicate additional models
+ for key, model_list in n.additional_models.items():
+ new_model_list = [x for x in model_list if x.clone_base_uuid not in remove_models_uuids]
+ n.set_additional_models(key, new_model_list)
+ for callback in self.get_all_callbacks(CallbacksMP.ON_MATCH_MULTIGPU_CLONES):
+ callback(self, n)
+ new_multigpu_models.append(n)
+ self.set_additional_models("multigpu", new_multigpu_models)
+
+ def is_clone(self, other):
+ if hasattr(other, 'model') and self.model is other.model:
+ return True
+ return False
+
+ def clone_has_same_weights(self, clone: ModelPatcher, allow_multigpu=False):
+ if allow_multigpu:
+ if self.clone_base_uuid != clone.clone_base_uuid:
+ return False
+ else:
+ if not self.is_clone(clone):
+ return False
+
+ if self.current_hooks != clone.current_hooks:
+ return False
+ if self.forced_hooks != clone.forced_hooks:
+ return False
+ if self.hook_patches.keys() != clone.hook_patches.keys():
+ return False
+ if self.attachments.keys() != clone.attachments.keys():
+ return False
+ if self.additional_models.keys() != clone.additional_models.keys():
+ return False
+ for key in self.callbacks:
+ if len(self.callbacks[key]) != len(clone.callbacks[key]):
+ return False
+ for key in self.wrappers:
+ if len(self.wrappers[key]) != len(clone.wrappers[key]):
+ return False
+ if self.injections.keys() != clone.injections.keys():
+ return False
+
+ if len(self.patches) == 0 and len(clone.patches) == 0:
+ return True
+
+ if self.patches_uuid == clone.patches_uuid:
+ if len(self.patches) != len(clone.patches):
+ logging.warning("WARNING: something went wrong, same patch uuid but different length of patches.")
+ else:
+ return True
+
+ def memory_required(self, input_shape):
+ return self.model.memory_required(input_shape=input_shape)
+
+ def disable_model_cfg1_optimization(self):
+ self.model_options["disable_cfg1_optimization"] = True
+
+ def set_model_sampler_cfg_function(self, sampler_cfg_function, disable_cfg1_optimization=False):
+ if len(inspect.signature(sampler_cfg_function).parameters) == 3:
+ self.model_options["sampler_cfg_function"] = lambda args: sampler_cfg_function(args["cond"], args["uncond"], args["cond_scale"]) #Old way
+ else:
+ self.model_options["sampler_cfg_function"] = sampler_cfg_function
+ if disable_cfg1_optimization:
+ self.disable_model_cfg1_optimization()
+
+ def set_model_sampler_post_cfg_function(self, post_cfg_function, disable_cfg1_optimization=False):
+ self.model_options = set_model_options_post_cfg_function(self.model_options, post_cfg_function, disable_cfg1_optimization)
+
+ def set_model_sampler_pre_cfg_function(self, pre_cfg_function, disable_cfg1_optimization=False):
+ self.model_options = set_model_options_pre_cfg_function(self.model_options, pre_cfg_function, disable_cfg1_optimization)
+
+ def set_model_sampler_calc_cond_batch_function(self, sampler_calc_cond_batch_function):
+ self.model_options["sampler_calc_cond_batch_function"] = sampler_calc_cond_batch_function
+
+ def set_model_unet_function_wrapper(self, unet_wrapper_function: UnetWrapperFunction):
+ self.model_options["model_function_wrapper"] = unet_wrapper_function
+
+ def set_model_denoise_mask_function(self, denoise_mask_function):
+ self.model_options["denoise_mask_function"] = denoise_mask_function
+
+ def set_model_patch(self, patch, name):
+ to = self.model_options["transformer_options"]
+ if "patches" not in to:
+ to["patches"] = {}
+ to["patches"][name] = to["patches"].get(name, []) + [patch]
+
+ def set_model_patch_replace(self, patch, name, block_name, number, transformer_index=None):
+ self.model_options = set_model_options_patch_replace(self.model_options, patch, name, block_name, number, transformer_index=transformer_index)
+
+ def set_model_attn1_patch(self, patch):
+ self.set_model_patch(patch, "attn1_patch")
+
+ def set_model_attn2_patch(self, patch):
+ self.set_model_patch(patch, "attn2_patch")
+
+ def set_model_attn1_replace(self, patch, block_name, number, transformer_index=None):
+ self.set_model_patch_replace(patch, "attn1", block_name, number, transformer_index)
+
+ def set_model_attn2_replace(self, patch, block_name, number, transformer_index=None):
+ self.set_model_patch_replace(patch, "attn2", block_name, number, transformer_index)
+
+ def set_model_attn1_output_patch(self, patch):
+ self.set_model_patch(patch, "attn1_output_patch")
+
+ def set_model_attn2_output_patch(self, patch):
+ self.set_model_patch(patch, "attn2_output_patch")
+
+ def set_model_input_block_patch(self, patch):
+ self.set_model_patch(patch, "input_block_patch")
+
+ def set_model_input_block_patch_after_skip(self, patch):
+ self.set_model_patch(patch, "input_block_patch_after_skip")
+
+ def set_model_output_block_patch(self, patch):
+ self.set_model_patch(patch, "output_block_patch")
+
+ def set_model_emb_patch(self, patch):
+ self.set_model_patch(patch, "emb_patch")
+
+ def set_model_forward_timestep_embed_patch(self, patch):
+ self.set_model_patch(patch, "forward_timestep_embed_patch")
+
+ def set_model_double_block_patch(self, patch):
+ self.set_model_patch(patch, "double_block")
+
+ def set_model_post_input_patch(self, patch):
+ self.set_model_patch(patch, "post_input")
+
+ def set_model_noise_refiner_patch(self, patch):
+ self.set_model_patch(patch, "noise_refiner")
+
+ def set_model_middle_block_after_patch(self, patch):
+ self.set_model_patch(patch, "middle_block_after_patch")
+
+
+ def set_model_rope_options(self, scale_x, shift_x, scale_y, shift_y, scale_t, shift_t, **kwargs):
+ rope_options = self.model_options["transformer_options"].get("rope_options", {})
+ rope_options["scale_x"] = scale_x
+ rope_options["scale_y"] = scale_y
+ rope_options["scale_t"] = scale_t
+
+ rope_options["shift_x"] = shift_x
+ rope_options["shift_y"] = shift_y
+ rope_options["shift_t"] = shift_t
+
+ self.model_options["transformer_options"]["rope_options"] = rope_options
+
+
+ def add_object_patch(self, name, obj):
+ self.object_patches[name] = obj
+
+ def set_model_compute_dtype(self, dtype):
+ self.add_object_patch("manual_cast_dtype", dtype)
+ if dtype is not None:
+ self.force_cast_weights = True
+ self.patches_uuid = uuid.uuid4() #TODO: optimize by preventing a full model reload for this
+
+ def add_weight_wrapper(self, name, function):
+ self.weight_wrapper_patches[name] = self.weight_wrapper_patches.get(name, []) + [function]
+ self.patches_uuid = uuid.uuid4()
+
+ def get_model_object(self, name: str) -> torch.nn.Module:
+ """Retrieves a nested attribute from an object using dot notation considering
+ object patches.
+
+ Args:
+ name (str): The attribute path using dot notation (e.g. "model.layer.weight")
+
+ Returns:
+ The value of the requested attribute
+
+ Example:
+ patcher = ModelPatcher()
+ weight = patcher.get_model_object("layer1.conv.weight")
+ """
+ if name in self.object_patches:
+ return self.object_patches[name]
+ else:
+ if name in self.object_patches_backup:
+ return self.object_patches_backup[name]
+ else:
+ return comfy.utils.get_attr(self.model, name)
+
+ def model_patches_to(self, device):
+ to = self.model_options["transformer_options"]
+ if "patches" in to:
+ patches = to["patches"]
+ for name in patches:
+ patch_list = patches[name]
+ for i in range(len(patch_list)):
+ if hasattr(patch_list[i], "to"):
+ patch_list[i] = patch_list[i].to(device)
+ if "patches_replace" in to:
+ patches = to["patches_replace"]
+ for name in patches:
+ patch_list = patches[name]
+ for k in patch_list:
+ if hasattr(patch_list[k], "to"):
+ patch_list[k] = patch_list[k].to(device)
+ if "model_function_wrapper" in self.model_options:
+ wrap_func = self.model_options["model_function_wrapper"]
+ if hasattr(wrap_func, "to"):
+ self.model_options["model_function_wrapper"] = wrap_func.to(device)
+
+ def model_patches_models(self):
+ to = self.model_options["transformer_options"]
+ models = []
+ if "patches" in to:
+ patches = to["patches"]
+ for name in patches:
+ patch_list = patches[name]
+ for i in range(len(patch_list)):
+ if hasattr(patch_list[i], "models"):
+ models += patch_list[i].models()
+ if "patches_replace" in to:
+ patches = to["patches_replace"]
+ for name in patches:
+ patch_list = patches[name]
+ for k in patch_list:
+ if hasattr(patch_list[k], "models"):
+ models += patch_list[k].models()
+ if "model_function_wrapper" in self.model_options:
+ wrap_func = self.model_options["model_function_wrapper"]
+ if hasattr(wrap_func, "models"):
+ models += wrap_func.models()
+
+ return models
+
+ def model_patches_call_function(self, function_name="cleanup", arguments={}):
+ to = self.model_options["transformer_options"]
+ if "patches" in to:
+ patches = to["patches"]
+ for name in patches:
+ patch_list = patches[name]
+ for i in range(len(patch_list)):
+ if hasattr(patch_list[i], function_name):
+ getattr(patch_list[i], function_name)(**arguments)
+ if "patches_replace" in to:
+ patches = to["patches_replace"]
+ for name in patches:
+ patch_list = patches[name]
+ for k in patch_list:
+ if hasattr(patch_list[k], function_name):
+ getattr(patch_list[k], function_name)(**arguments)
+ if "model_function_wrapper" in self.model_options:
+ wrap_func = self.model_options["model_function_wrapper"]
+ if hasattr(wrap_func, function_name):
+ getattr(wrap_func, function_name)(**arguments)
+
+ def model_dtype(self):
+ if hasattr(self.model, "get_dtype"):
+ return self.model.get_dtype()
+
+ def add_patches(self, patches, strength_patch=1.0, strength_model=1.0):
+ with self.use_ejected():
+ p = set()
+ model_sd = self.model.state_dict()
+ for k in patches:
+ offset = None
+ function = None
+ if isinstance(k, str):
+ key = k
+ else:
+ offset = k[1]
+ key = k[0]
+ if len(k) > 2:
+ function = k[2]
+
+ if key in model_sd:
+ p.add(k)
+ current_patches = self.patches.get(key, [])
+ current_patches.append((strength_patch, patches[k], strength_model, offset, function))
+ self.patches[key] = current_patches
+
+ self.patches_uuid = uuid.uuid4()
+ return list(p)
+
+ def get_key_patches(self, filter_prefix=None):
+ model_sd = self.model_state_dict()
+ p = {}
+ for k in model_sd:
+ if filter_prefix is not None:
+ if not k.startswith(filter_prefix):
+ continue
+ bk = self.backup.get(k, None)
+ hbk = self.hook_backup.get(k, None)
+ weight, set_func, convert_func = get_key_weight(self.model, k)
+ if bk is not None:
+ weight = bk.weight
+ if hbk is not None:
+ weight = hbk[0]
+ if convert_func is None:
+ convert_func = lambda a, **kwargs: a
+
+ if k in self.patches:
+ p[k] = [(weight, convert_func)] + self.patches[k]
+ else:
+ p[k] = [(weight, convert_func)]
+ return p
+
+ def model_state_dict(self, filter_prefix=None):
+ with self.use_ejected():
+ sd = self.model.state_dict()
+ keys = list(sd.keys())
+ if filter_prefix is not None:
+ for k in keys:
+ if not k.startswith(filter_prefix):
+ sd.pop(k)
+ return sd
+
+ def patch_weight_to_device(self, key, device_to=None, inplace_update=False, return_weight=False, force_cast=False):
+ weight, set_func, convert_func = get_key_weight(self.model, key)
+ if key not in self.patches and not force_cast:
+ return weight
+
+ inplace_update = self.weight_inplace_update or inplace_update
+
+ if key not in self.backup and not return_weight:
+ self.backup[key] = collections.namedtuple('Dimension', ['weight', 'inplace_update'])(weight.to(device=self.offload_device, copy=inplace_update), inplace_update)
+
+ temp_dtype = comfy.model_management.lora_compute_dtype(device_to) if key in self.patches else None
+ if device_to is not None:
+ temp_weight = comfy.model_management.cast_to_device(weight, device_to, temp_dtype, copy=True)
+ else:
+ temp_weight = weight.to(temp_dtype, copy=True)
+ if convert_func is not None:
+ temp_weight = convert_func(temp_weight, inplace=True)
+
+ out_weight = comfy.lora.calculate_weight(self.patches[key], temp_weight, key) if key in self.patches else temp_weight
+ if set_func is None:
+ if key in self.patches:
+ out_weight = comfy.float.stochastic_rounding(out_weight, weight.dtype, seed=comfy.utils.string_to_seed(key))
+ if return_weight:
+ return out_weight
+ elif inplace_update:
+ comfy.utils.copy_to_param(self.model, key, out_weight)
+ else:
+ comfy.utils.set_attr_param(self.model, key, out_weight)
+ else:
+ return set_func(out_weight, inplace_update=inplace_update, seed=comfy.utils.string_to_seed(key), return_weight=return_weight)
+
+ def pin_weight_to_device(self, key):
+ weight, set_func, convert_func = get_key_weight(self.model, key)
+ if comfy.model_management.pin_memory(weight):
+ self.pinned.add(key)
+
+ def unpin_weight(self, key):
+ if key in self.pinned:
+ weight, set_func, convert_func = get_key_weight(self.model, key)
+ comfy.model_management.unpin_memory(weight)
+ self.pinned.remove(key)
+
+ def unpin_all_weights(self):
+ for key in list(self.pinned):
+ self.unpin_weight(key)
+
+ def _load_list(self, for_dynamic=False, default_device=None):
+ loading = []
+ for n, m in self.model.named_modules():
+ default = False
+ params = { name: param for name, param in m.named_parameters(recurse=False) }
+ for name, param in m.named_parameters(recurse=True):
+ if name not in params:
+ default = True # default random weights in non leaf modules
+ break
+ if default and default_device is not None:
+ for param_name, param in params.items():
+ param.data = param.data.to(device=default_device, dtype=getattr(m, param_name + "_comfy_model_dtype", None))
+ if not default and (hasattr(m, "comfy_cast_weights") or len(params) > 0):
+ module_mem = comfy.model_management.module_size(m)
+ module_offload_mem = module_mem
+ if hasattr(m, "comfy_cast_weights"):
+ def check_module_offload_mem(key):
+ if key in self.patches:
+ return low_vram_patch_estimate_vram(self.model, key)
+ model_dtype = getattr(self.model, "manual_cast_dtype", None)
+ weight, _, _ = get_key_weight(self.model, key)
+ if model_dtype is None or weight is None:
+ return 0
+ if (weight.dtype != model_dtype or isinstance(weight, QuantizedTensor)):
+ return weight.numel() * model_dtype.itemsize
+ return 0
+ module_offload_mem += check_module_offload_mem("{}.weight".format(n))
+ module_offload_mem += check_module_offload_mem("{}.bias".format(n))
+ # Dynamic: small weights (<64KB) first, then larger weights prioritized by size.
+ # Non-dynamic: prioritize by module offload cost.
+ if for_dynamic:
+ sort_criteria = (module_offload_mem >= 64 * 1024, -module_offload_mem)
+ else:
+ sort_criteria = (module_offload_mem,)
+ loading.append(sort_criteria + (module_mem, n, m, params))
+ return loading
+
+ def load(self, device_to=None, lowvram_model_memory=0, force_patch_weights=False, full_load=False):
+ with self.use_ejected():
+ self.unpatch_hooks()
+ mem_counter = 0
+ patch_counter = 0
+ lowvram_counter = 0
+ lowvram_mem_counter = 0
+ loading = self._load_list()
+
+ load_completely = []
+ offloaded = []
+ offload_buffer = 0
+ loading.sort(reverse=True)
+ for i, x in enumerate(loading):
+ module_offload_mem, module_mem, n, m, params = x
+
+ lowvram_weight = False
+
+ potential_offload = max(offload_buffer, module_offload_mem + sum([ x1[1] for x1 in loading[i+1:i+1+comfy.model_management.NUM_STREAMS]]))
+ lowvram_fits = mem_counter + module_mem + potential_offload < lowvram_model_memory
+
+ weight_key = "{}.weight".format(n)
+ bias_key = "{}.bias".format(n)
+
+ if not full_load and hasattr(m, "comfy_cast_weights"):
+ if not lowvram_fits:
+ offload_buffer = potential_offload
+ lowvram_weight = True
+ lowvram_counter += 1
+ lowvram_mem_counter += module_mem
+ if hasattr(m, "prev_comfy_cast_weights"): #Already lowvramed
+ continue
+
+ cast_weight = self.force_cast_weights
+ m.comfy_force_cast_weights = self.force_cast_weights
+ if lowvram_weight:
+ if hasattr(m, "comfy_cast_weights"):
+ m.weight_function = []
+ m.bias_function = []
+
+ if weight_key in self.patches:
+ if force_patch_weights:
+ self.patch_weight_to_device(weight_key)
+ else:
+ _, set_func, convert_func = get_key_weight(self.model, weight_key)
+ m.weight_function = [LowVramPatch(weight_key, self.patches, convert_func, set_func)]
+ patch_counter += 1
+ if bias_key in self.patches:
+ if force_patch_weights:
+ self.patch_weight_to_device(bias_key)
+ else:
+ _, set_func, convert_func = get_key_weight(self.model, bias_key)
+ m.bias_function = [LowVramPatch(bias_key, self.patches, convert_func, set_func)]
+ patch_counter += 1
+
+ cast_weight = True
+ offloaded.append((module_mem, n, m, params))
+ else:
+ if hasattr(m, "comfy_cast_weights"):
+ wipe_lowvram_weight(m)
+
+ if full_load or lowvram_fits:
+ mem_counter += module_mem
+ load_completely.append((module_mem, n, m, params))
+ else:
+ offload_buffer = potential_offload
+
+ if cast_weight and hasattr(m, "comfy_cast_weights"):
+ m.prev_comfy_cast_weights = m.comfy_cast_weights
+ m.comfy_cast_weights = True
+
+ if weight_key in self.weight_wrapper_patches:
+ m.weight_function.extend(self.weight_wrapper_patches[weight_key])
+
+ if bias_key in self.weight_wrapper_patches:
+ m.bias_function.extend(self.weight_wrapper_patches[bias_key])
+
+ mem_counter += move_weight_functions(m, device_to)
+
+ load_completely.sort(reverse=True)
+ for x in load_completely:
+ n = x[1]
+ m = x[2]
+ params = x[3]
+ if hasattr(m, "comfy_patched_weights"):
+ if m.comfy_patched_weights == True:
+ continue
+
+ for param, param_value in params.items():
+ if hasattr(m, "comfy_cast_weights") and getattr(param_value, "is_meta", False):
+ comfy.ops.disable_weight_init._zero_init_parameter(m, param)
+ key = key_param_name_to_key(n, param)
+ self.unpin_weight(key)
+ self.patch_weight_to_device(key, device_to=device_to)
+ if comfy.model_management.is_device_cuda(device_to):
+ torch.cuda.synchronize()
+
+ logging.debug("lowvram: loaded module regularly {} {}".format(n, m))
+ m.comfy_patched_weights = True
+
+ for x in load_completely:
+ x[2].to(device_to)
+
+ for x in offloaded:
+ n = x[1]
+ params = x[3]
+ for param in params:
+ self.pin_weight_to_device(key_param_name_to_key(n, param))
+
+ usable_stat = "{:.2f} MB usable,".format(lowvram_model_memory / (1024 * 1024)) if lowvram_model_memory < 1e32 else ""
+ if lowvram_counter > 0:
+ logging.info("loaded partially; {} {:.2f} MB loaded, {:.2f} MB offloaded, {:.2f} MB buffer reserved, lowvram patches: {}".format(usable_stat, mem_counter / (1024 * 1024), lowvram_mem_counter / (1024 * 1024), offload_buffer / (1024 * 1024), patch_counter))
+ self.model.model_lowvram = True
+ else:
+ logging.info("loaded completely; {} {:.2f} MB loaded, full load: {}".format(usable_stat, mem_counter / (1024 * 1024), full_load))
+ self.model.model_lowvram = False
+ if full_load:
+ self.model.to(device_to)
+ mem_counter = self.model_size()
+
+ self.model.lowvram_patch_counter += patch_counter
+ self.model.device = device_to
+ self.model.model_loaded_weight_memory = mem_counter
+ self.model.model_offload_buffer_memory = offload_buffer
+ self.model.current_weight_patches_uuid = self.patches_uuid
+
+ for callback in self.get_all_callbacks(CallbacksMP.ON_LOAD):
+ callback(self, device_to, lowvram_model_memory, force_patch_weights, full_load)
+
+ self.apply_hooks(self.forced_hooks, force_apply=True)
+
+ def patch_model(self, device_to=None, lowvram_model_memory=0, load_weights=True, force_patch_weights=False):
+ with self.use_ejected():
+ for k in self.object_patches:
+ old = comfy.utils.set_attr(self.model, k, self.object_patches[k])
+ if k not in self.object_patches_backup:
+ self.object_patches_backup[k] = old
+
+ if lowvram_model_memory == 0:
+ full_load = True
+ else:
+ full_load = False
+
+ if load_weights:
+ self.load(device_to, lowvram_model_memory=lowvram_model_memory, force_patch_weights=force_patch_weights, full_load=full_load)
+ self.inject_model()
+ return self.model
+
+ def unpatch_model(self, device_to=None, unpatch_weights=True):
+ self.eject_model()
+ if unpatch_weights:
+ self.unpatch_hooks()
+ self.unpin_all_weights()
+ if self.model.model_lowvram:
+ for m in self.model.modules():
+ move_weight_functions(m, device_to)
+ wipe_lowvram_weight(m)
+
+ self.model.model_lowvram = False
+ self.model.lowvram_patch_counter = 0
+
+ keys = list(self.backup.keys())
+
+ for k in keys:
+ bk = self.backup[k]
+ if bk.inplace_update:
+ comfy.utils.copy_to_param(self.model, k, bk.weight)
+ else:
+ comfy.utils.set_attr_param(self.model, k, bk.weight)
+
+ self.model.current_weight_patches_uuid = None
+ self.backup.clear()
+
+ if device_to is not None:
+ self.model.to(device_to)
+ self.model.device = device_to
+ self.model.model_loaded_weight_memory = 0
+ self.model.model_offload_buffer_memory = 0
+
+ for m in self.model.modules():
+ if hasattr(m, "comfy_patched_weights"):
+ del m.comfy_patched_weights
+
+ keys = list(self.object_patches_backup.keys())
+ for k in keys:
+ comfy.utils.set_attr(self.model, k, self.object_patches_backup[k])
+
+ self.object_patches_backup.clear()
+
+ def partially_unload(self, device_to, memory_to_free=0, force_patch_weights=False):
+ with self.use_ejected():
+ hooks_unpatched = False
+ memory_freed = 0
+ patch_counter = 0
+ unload_list = self._load_list()
+ unload_list.sort()
+
+ offload_buffer = self.model.model_offload_buffer_memory
+ if len(unload_list) > 0:
+ NS = comfy.model_management.NUM_STREAMS
+ offload_weight_factor = [ min(offload_buffer / (NS + 1), unload_list[0][1]) ] * NS
+
+ for unload in unload_list:
+ if memory_to_free + offload_buffer - self.model.model_offload_buffer_memory < memory_freed:
+ break
+ module_offload_mem, module_mem, n, m, params = unload
+
+ potential_offload = module_offload_mem + sum(offload_weight_factor)
+
+ lowvram_possible = hasattr(m, "comfy_cast_weights")
+ if hasattr(m, "comfy_patched_weights") and m.comfy_patched_weights == True:
+ move_weight = True
+ for param in params:
+ key = key_param_name_to_key(n, param)
+ bk = self.backup.get(key, None)
+ if bk is not None:
+ if not lowvram_possible:
+ move_weight = False
+ break
+
+ if not hooks_unpatched:
+ self.unpatch_hooks()
+ hooks_unpatched = True
+
+ if bk.inplace_update:
+ comfy.utils.copy_to_param(self.model, key, bk.weight)
+ else:
+ comfy.utils.set_attr_param(self.model, key, bk.weight)
+ self.backup.pop(key)
+
+ weight_key = "{}.weight".format(n)
+ bias_key = "{}.bias".format(n)
+ if move_weight:
+ cast_weight = self.force_cast_weights
+ m.to(device_to)
+ module_mem += move_weight_functions(m, device_to)
+ if lowvram_possible:
+ if weight_key in self.patches:
+ if force_patch_weights:
+ self.patch_weight_to_device(weight_key)
+ else:
+ _, set_func, convert_func = get_key_weight(self.model, weight_key)
+ m.weight_function.append(LowVramPatch(weight_key, self.patches, convert_func, set_func))
+ patch_counter += 1
+ if bias_key in self.patches:
+ if force_patch_weights:
+ self.patch_weight_to_device(bias_key)
+ else:
+ _, set_func, convert_func = get_key_weight(self.model, bias_key)
+ m.bias_function.append(LowVramPatch(bias_key, self.patches, convert_func, set_func))
+ patch_counter += 1
+ cast_weight = True
+
+ if cast_weight and hasattr(m, "comfy_cast_weights"):
+ m.prev_comfy_cast_weights = m.comfy_cast_weights
+ m.comfy_cast_weights = True
+ m.comfy_patched_weights = False
+ memory_freed += module_mem
+ offload_buffer = max(offload_buffer, potential_offload)
+ offload_weight_factor.append(module_mem)
+ offload_weight_factor.pop(0)
+ logging.debug("freed {}".format(n))
+
+ for param in params:
+ self.pin_weight_to_device(key_param_name_to_key(n, param))
+
+
+ self.model.model_lowvram = True
+ self.model.lowvram_patch_counter += patch_counter
+ self.model.model_loaded_weight_memory -= memory_freed
+ self.model.model_offload_buffer_memory = offload_buffer
+ logging.info("Unloaded partially: {:.2f} MB freed, {:.2f} MB remains loaded, {:.2f} MB buffer reserved, lowvram patches: {}".format(memory_freed / (1024 * 1024), self.model.model_loaded_weight_memory / (1024 * 1024), offload_buffer / (1024 * 1024), self.model.lowvram_patch_counter))
+ return memory_freed
+
+ def partially_load(self, device_to, extra_memory=0, force_patch_weights=False):
+ with self.use_ejected(skip_and_inject_on_exit_only=True):
+ unpatch_weights = self.model.current_weight_patches_uuid is not None and (self.model.current_weight_patches_uuid != self.patches_uuid or force_patch_weights)
+ # TODO: force_patch_weights should not unload + reload full model
+ used = self.model.model_loaded_weight_memory
+ self.unpatch_model(self.offload_device, unpatch_weights=unpatch_weights)
+ if unpatch_weights:
+ extra_memory += (used - self.model.model_loaded_weight_memory)
+
+ self.patch_model(load_weights=False)
+ if extra_memory < 0 and not unpatch_weights:
+ self.partially_unload(self.offload_device, -extra_memory, force_patch_weights=force_patch_weights)
+ return 0
+ full_load = False
+ if self.model.model_lowvram == False and self.model.model_loaded_weight_memory > 0:
+ self.apply_hooks(self.forced_hooks, force_apply=True)
+ return 0
+ if self.model.model_loaded_weight_memory + extra_memory > self.model_size():
+ full_load = True
+ current_used = self.model.model_loaded_weight_memory
+ try:
+ self.load(device_to, lowvram_model_memory=current_used + extra_memory, force_patch_weights=force_patch_weights, full_load=full_load)
+ except Exception as e:
+ self.detach()
+ raise e
+
+ return self.model.model_loaded_weight_memory - current_used
+
+ def pinned_memory_size(self):
+ # Pinned memory pressure tracking is only implemented for DynamicVram loading
+ return 0
+
+ def loaded_ram_size(self):
+ # Loaded RAM pressure tracking is only implemented for DynamicVram loading
+ return 0
+
+ def partially_unload_ram(self, ram_to_unload):
+ return 0
+
+ def detach(self, unpatch_all=True):
+ self.eject_model()
+ self.model_patches_to(self.offload_device)
+ if unpatch_all:
+ self.unpatch_model(self.offload_device, unpatch_weights=unpatch_all)
+ for callback in self.get_all_callbacks(CallbacksMP.ON_DETACH):
+ callback(self, unpatch_all)
+ return self.model
+
+ def current_loaded_device(self):
+ return self.model.device
+
+ def calculate_weight(self, patches, weight, key, intermediate_dtype=torch.float32):
+ logging.warning("The ModelPatcher.calculate_weight function is deprecated, please use: comfy.lora.calculate_weight instead")
+ return comfy.lora.calculate_weight(patches, weight, key, intermediate_dtype=intermediate_dtype)
+
+ def cleanup(self):
+ self.model_patches_call_function(function_name="cleanup")
+ self.clean_hooks()
+ if hasattr(self.model, "current_patcher"):
+ self.model.current_patcher = None
+ for callback in self.get_all_callbacks(CallbacksMP.ON_CLEANUP):
+ callback(self)
+
+ def add_callback(self, call_type: str, callback: Callable):
+ self.add_callback_with_key(call_type, None, callback)
+
+ def add_callback_with_key(self, call_type: str, key: str, callback: Callable):
+ c = self.callbacks.setdefault(call_type, {}).setdefault(key, [])
+ c.append(callback)
+
+ def remove_callbacks_with_key(self, call_type: str, key: str):
+ c = self.callbacks.get(call_type, {})
+ if key in c:
+ c.pop(key)
+
+ def get_callbacks(self, call_type: str, key: str):
+ return self.callbacks.get(call_type, {}).get(key, [])
+
+ def get_all_callbacks(self, call_type: str):
+ c_list = []
+ for c in self.callbacks.get(call_type, {}).values():
+ c_list.extend(c)
+ return c_list
+
+ def add_wrapper(self, wrapper_type: str, wrapper: Callable):
+ self.add_wrapper_with_key(wrapper_type, None, wrapper)
+
+ def add_wrapper_with_key(self, wrapper_type: str, key: str, wrapper: Callable):
+ w = self.wrappers.setdefault(wrapper_type, {}).setdefault(key, [])
+ w.append(wrapper)
+
+ def remove_wrappers_with_key(self, wrapper_type: str, key: str):
+ w = self.wrappers.get(wrapper_type, {})
+ if key in w:
+ w.pop(key)
+
+ def get_wrappers(self, wrapper_type: str, key: str):
+ return self.wrappers.get(wrapper_type, {}).get(key, [])
+
+ def get_all_wrappers(self, wrapper_type: str):
+ w_list = []
+ for w in self.wrappers.get(wrapper_type, {}).values():
+ w_list.extend(w)
+ return w_list
+
+ def set_attachments(self, key: str, attachment):
+ self.attachments[key] = attachment
+
+ def remove_attachments(self, key: str):
+ if key in self.attachments:
+ self.attachments.pop(key)
+
+ def get_attachment(self, key: str):
+ return self.attachments.get(key, None)
+
+ def set_injections(self, key: str, injections: list[PatcherInjection]):
+ self.injections[key] = injections
+
+ def remove_injections(self, key: str):
+ if key in self.injections:
+ self.injections.pop(key)
+
+ def get_injections(self, key: str):
+ return self.injections.get(key, None)
+
+ def set_additional_models(self, key: str, models: list['ModelPatcher']):
+ self.additional_models[key] = models
+
+ def remove_additional_models(self, key: str):
+ if key in self.additional_models:
+ self.additional_models.pop(key)
+
+ def get_additional_models_with_key(self, key: str):
+ return self.additional_models.get(key, [])
+
+ def get_additional_models(self):
+ all_models: list[ModelPatcher] = []
+ for models in self.additional_models.values():
+ all_models.extend(models)
+ return all_models
+
+ def get_nested_additional_models(self):
+ def _evaluate_sub_additional_models(prev_models: list[ModelPatcher], cache_set: set[ModelPatcher]):
+ '''Make sure circular references do not cause infinite recursion.'''
+ next_models = []
+ for model in prev_models:
+ candidates = model.get_additional_models()
+ for c in candidates:
+ if c not in cache_set:
+ next_models.append(c)
+ cache_set.add(c)
+ if len(next_models) == 0:
+ return prev_models
+ return prev_models + _evaluate_sub_additional_models(next_models, cache_set)
+
+ all_models = self.get_additional_models()
+ models_set = set(all_models)
+ real_all_models = _evaluate_sub_additional_models(prev_models=all_models, cache_set=models_set)
+ return real_all_models
+
+ def use_ejected(self, skip_and_inject_on_exit_only=False):
+ return AutoPatcherEjector(self, skip_and_inject_on_exit_only=skip_and_inject_on_exit_only)
+
+ def inject_model(self):
+ if self.is_injected or self.skip_injection:
+ return
+ for injections in self.injections.values():
+ for inj in injections:
+ inj.inject(self)
+ self.is_injected = True
+ if self.is_injected:
+ for callback in self.get_all_callbacks(CallbacksMP.ON_INJECT_MODEL):
+ callback(self)
+
+ def eject_model(self):
+ if not self.is_injected:
+ return
+ for injections in self.injections.values():
+ for inj in injections:
+ inj.eject(self)
+ self.is_injected = False
+ for callback in self.get_all_callbacks(CallbacksMP.ON_EJECT_MODEL):
+ callback(self)
+
+ def pre_run(self):
+ if hasattr(self.model, "current_patcher"):
+ self.model.current_patcher = self
+ for callback in self.get_all_callbacks(CallbacksMP.ON_PRE_RUN):
+ callback(self)
+
+ def prepare_state(self, timestep, model_options):
+ ignore_multigpu = model_options.get("ignore_multigpu", False)
+ for callback in self.get_all_callbacks(CallbacksMP.ON_PREPARE_STATE):
+ callback(self, timestep, model_options)
+ if not ignore_multigpu and "multigpu_clones" in model_options:
+ model_options["ignore_multigpu"] = True
+ try:
+ for p in model_options["multigpu_clones"].values():
+ p: ModelPatcher
+ p.prepare_state(timestep, model_options)
+ finally:
+ model_options.pop("ignore_multigpu", None)
+
+ def restore_hook_patches(self):
+ if self.hook_patches_backup is not None:
+ self.hook_patches = self.hook_patches_backup
+ self.hook_patches_backup = None
+
+ def set_hook_mode(self, hook_mode: comfy.hooks.EnumHookMode):
+ self.hook_mode = hook_mode
+
+ def prepare_hook_patches_current_keyframe(self, t: torch.Tensor, hook_group: comfy.hooks.HookGroup, model_options: dict[str]):
+ curr_t = t[0]
+ reset_current_hooks = False
+ multigpu_kf_changed_cache = None
+ transformer_options = model_options.get("transformer_options", {})
+ for hook in hook_group.hooks:
+ changed = hook.hook_keyframe.prepare_current_keyframe(curr_t=curr_t, transformer_options=transformer_options)
+ # if keyframe changed, remove any cached HookGroups that contain hook with the same hook_ref;
+ # this will cause the weights to be recalculated when sampling
+ if changed:
+ # cache changed for multigpu usage
+ if "multigpu_clones" in model_options:
+ if multigpu_kf_changed_cache is None:
+ multigpu_kf_changed_cache = []
+ multigpu_kf_changed_cache.append(hook)
+ # reset current_hooks if contains hook that changed
+ if self.current_hooks is not None:
+ for current_hook in self.current_hooks.hooks:
+ if current_hook == hook:
+ reset_current_hooks = True
+ break
+ for cached_group in list(self.cached_hook_patches.keys()):
+ if cached_group.contains(hook):
+ self.cached_hook_patches.pop(cached_group)
+ if reset_current_hooks:
+ self.patch_hooks(None)
+ if "multigpu_clones" in model_options:
+ for p in model_options["multigpu_clones"].values():
+ p: ModelPatcher
+ p._handle_changed_hook_keyframes(multigpu_kf_changed_cache)
+
+ def _handle_changed_hook_keyframes(self, kf_changed_cache: list[comfy.hooks.Hook]):
+ 'Used to handle multigpu behavior inside prepare_hook_patches_current_keyframe.'
+ if kf_changed_cache is None:
+ return
+ reset_current_hooks = False
+ # reset current_hooks if contains hook that changed
+ for hook in kf_changed_cache:
+ if self.current_hooks is not None:
+ for current_hook in self.current_hooks.hooks:
+ if current_hook == hook:
+ reset_current_hooks = True
+ break
+ for cached_group in list(self.cached_hook_patches.keys()):
+ if cached_group.contains(hook):
+ self.cached_hook_patches.pop(cached_group)
+ if reset_current_hooks:
+ self.patch_hooks(None)
+
+ def register_all_hook_patches(self, hooks: comfy.hooks.HookGroup, target_dict: dict[str], model_options: dict=None,
+ registered: comfy.hooks.HookGroup = None):
+ self.restore_hook_patches()
+ if registered is None:
+ registered = comfy.hooks.HookGroup()
+ # handle WeightHooks
+ weight_hooks_to_register: list[comfy.hooks.WeightHook] = []
+ for hook in hooks.get_type(comfy.hooks.EnumHookType.Weight):
+ if hook.hook_ref not in self.hook_patches:
+ weight_hooks_to_register.append(hook)
+ else:
+ registered.add(hook)
+ if len(weight_hooks_to_register) > 0:
+ # clone hook_patches to become backup so that any non-dynamic hooks will return to their original state
+ self.hook_patches_backup = create_hook_patches_clone(self.hook_patches)
+ for hook in weight_hooks_to_register:
+ hook.add_hook_patches(self, model_options, target_dict, registered)
+ for callback in self.get_all_callbacks(CallbacksMP.ON_REGISTER_ALL_HOOK_PATCHES):
+ callback(self, hooks, target_dict, model_options, registered)
+ return registered
+
+ def add_hook_patches(self, hook: comfy.hooks.WeightHook, patches, strength_patch=1.0, strength_model=1.0):
+ with self.use_ejected():
+ # NOTE: this mirrors behavior of add_patches func
+ current_hook_patches: dict[str,list] = self.hook_patches.get(hook.hook_ref, {})
+ p = set()
+ model_sd = self.model.state_dict()
+ for k in patches:
+ offset = None
+ function = None
+ if isinstance(k, str):
+ key = k
+ else:
+ offset = k[1]
+ key = k[0]
+ if len(k) > 2:
+ function = k[2]
+
+ if key in model_sd:
+ p.add(k)
+ current_patches: list[tuple] = current_hook_patches.get(key, [])
+ current_patches.append((strength_patch, patches[k], strength_model, offset, function))
+ current_hook_patches[key] = current_patches
+ self.hook_patches[hook.hook_ref] = current_hook_patches
+ # since should care about these patches too to determine if same model, reroll patches_uuid
+ self.patches_uuid = uuid.uuid4()
+ return list(p)
+
+ def get_combined_hook_patches(self, hooks: comfy.hooks.HookGroup):
+ # combined_patches will contain weights of all relevant hooks, per key
+ combined_patches = {}
+ if hooks is not None:
+ for hook in hooks.hooks:
+ hook_patches: dict = self.hook_patches.get(hook.hook_ref, {})
+ for key in hook_patches.keys():
+ current_patches: list[tuple] = combined_patches.get(key, [])
+ if math.isclose(hook.strength, 1.0):
+ current_patches.extend(hook_patches[key])
+ else:
+ # patches are stored as tuples: (strength_patch, (tuple_with_weights,), strength_model)
+ for patch in hook_patches[key]:
+ new_patch = list(patch)
+ new_patch[0] *= hook.strength
+ current_patches.append(tuple(new_patch))
+ combined_patches[key] = current_patches
+ return combined_patches
+
+ def apply_hooks(self, hooks: comfy.hooks.HookGroup, transformer_options: dict=None, force_apply=False):
+ # TODO: return transformer_options dict with any additions from hooks
+ if self.current_hooks == hooks and (not force_apply or (not self.is_clip and hooks is None)):
+ return comfy.hooks.create_transformer_options_from_hooks(self, hooks, transformer_options)
+ self.patch_hooks(hooks=hooks)
+ for callback in self.get_all_callbacks(CallbacksMP.ON_APPLY_HOOKS):
+ callback(self, hooks)
+ return comfy.hooks.create_transformer_options_from_hooks(self, hooks, transformer_options)
+
+ def patch_hooks(self, hooks: comfy.hooks.HookGroup):
+ with self.use_ejected():
+ if hooks is not None:
+ model_sd_keys = list(self.model_state_dict().keys())
+ memory_counter = None
+ if self.hook_mode == comfy.hooks.EnumHookMode.MaxSpeed:
+ # TODO: minimum_counter should have a minimum that conforms to loaded model requirements
+ memory_counter = MemoryCounter(initial=comfy.model_management.get_free_memory(self.load_device),
+ minimum=comfy.model_management.minimum_inference_memory()*2)
+ # if have cached weights for hooks, use it
+ cached_weights = self.cached_hook_patches.get(hooks, None)
+ if cached_weights is not None:
+ model_sd_keys_set = set(model_sd_keys)
+ for key in cached_weights:
+ if key not in model_sd_keys:
+ logging.warning(f"Cached hook could not patch. Key does not exist in model: {key}")
+ continue
+ self.patch_cached_hook_weights(cached_weights=cached_weights, key=key, memory_counter=memory_counter)
+ model_sd_keys_set.remove(key)
+ self.unpatch_hooks(model_sd_keys_set)
+ else:
+ self.unpatch_hooks()
+ relevant_patches = self.get_combined_hook_patches(hooks=hooks)
+ original_weights = None
+ if len(relevant_patches) > 0:
+ original_weights = self.get_key_patches()
+ for key in relevant_patches:
+ if key not in model_sd_keys:
+ logging.warning(f"Cached hook would not patch. Key does not exist in model: {key}")
+ continue
+ self.patch_hook_weight_to_device(hooks=hooks, combined_patches=relevant_patches, key=key, original_weights=original_weights,
+ memory_counter=memory_counter)
+ else:
+ self.unpatch_hooks()
+ self.current_hooks = hooks
+
+ def patch_cached_hook_weights(self, cached_weights: dict, key: str, memory_counter: MemoryCounter):
+ if key not in self.hook_backup:
+ weight: torch.Tensor = comfy.utils.get_attr(self.model, key)
+ target_device = self.offload_device
+ if self.hook_mode == comfy.hooks.EnumHookMode.MaxSpeed:
+ used = memory_counter.use(weight)
+ if used:
+ target_device = weight.device
+ self.hook_backup[key] = (weight.to(device=target_device, copy=True), weight.device)
+ comfy.utils.copy_to_param(self.model, key, cached_weights[key][0].to(device=cached_weights[key][1]))
+
+ def clear_cached_hook_weights(self):
+ self.cached_hook_patches.clear()
+ self.patch_hooks(None)
+
+ def patch_hook_weight_to_device(self, hooks: comfy.hooks.HookGroup, combined_patches: dict, key: str, original_weights: dict, memory_counter: MemoryCounter):
+ if key not in combined_patches:
+ return
+
+ weight, set_func, convert_func = get_key_weight(self.model, key)
+ weight: torch.Tensor
+ if key not in self.hook_backup:
+ target_device = self.offload_device
+ if self.hook_mode == comfy.hooks.EnumHookMode.MaxSpeed:
+ used = memory_counter.use(weight)
+ if used:
+ target_device = weight.device
+ self.hook_backup[key] = (weight.to(device=target_device, copy=True), weight.device)
+ # TODO: properly handle LowVramPatch, if it ends up an issue
+ temp_weight = comfy.model_management.cast_to_device(weight, weight.device, torch.float32, copy=True)
+ if convert_func is not None:
+ temp_weight = convert_func(temp_weight, inplace=True)
+
+ out_weight = comfy.lora.calculate_weight(combined_patches[key],
+ temp_weight,
+ key, original_weights=original_weights)
+ del original_weights[key]
+ if set_func is None:
+ out_weight = comfy.float.stochastic_rounding(out_weight, weight.dtype, seed=comfy.utils.string_to_seed(key))
+ comfy.utils.copy_to_param(self.model, key, out_weight)
+ else:
+ set_func(out_weight, inplace_update=True, seed=comfy.utils.string_to_seed(key))
+ if self.hook_mode == comfy.hooks.EnumHookMode.MaxSpeed:
+ # TODO: disable caching if not enough system RAM to do so
+ target_device = self.offload_device
+ used = memory_counter.use(weight)
+ if used:
+ target_device = weight.device
+ self.cached_hook_patches.setdefault(hooks, {})
+ self.cached_hook_patches[hooks][key] = (out_weight.to(device=target_device, copy=False), weight.device)
+ del temp_weight
+ del out_weight
+ del weight
+
+ def unpatch_hooks(self, whitelist_keys_set: set[str]=None) -> None:
+ with self.use_ejected():
+ if len(self.hook_backup) == 0:
+ self.current_hooks = None
+ return
+ keys = list(self.hook_backup.keys())
+ if whitelist_keys_set:
+ for k in keys:
+ if k in whitelist_keys_set:
+ comfy.utils.copy_to_param(self.model, k, self.hook_backup[k][0].to(device=self.hook_backup[k][1]))
+ self.hook_backup.pop(k)
+ else:
+ for k in keys:
+ comfy.utils.copy_to_param(self.model, k, self.hook_backup[k][0].to(device=self.hook_backup[k][1]))
+
+ self.hook_backup.clear()
+ self.current_hooks = None
+
+ def clean_hooks(self):
+ self.unpatch_hooks()
+ self.clear_cached_hook_weights()
+
+ def model_state_dict_for_saving(self, model=None, prefix=""):
+ if model is None:
+ model = self.model
+
+ original_state_dict = model.state_dict()
+ output_state_dict = {}
+ keys = list(original_state_dict)
+ while len(keys) > 0:
+ k = keys.pop(0)
+ v = original_state_dict[k]
+ op_keys = k.rsplit('.', 1)
+ if (len(op_keys) < 2) or op_keys[1] not in ["weight", "bias"]:
+ output_state_dict[k] = v
+ continue
+ try:
+ op = comfy.utils.get_attr(model, op_keys[0])
+ except:
+ output_state_dict[k] = v
+ continue
+ if not op or not hasattr(op, "comfy_cast_weights") or \
+ (hasattr(op, "comfy_patched_weights") and op.comfy_patched_weights == True):
+ output_state_dict[k] = v
+ continue
+ key = prefix + k
+ weight = comfy.utils.get_attr(self.model, key)
+ if isinstance(weight, QuantizedTensor) and k in original_state_dict:
+ qt_state_dict = weight.state_dict(k)
+ caster = LazyCastingQuantizedParam(self, key)
+ for group_key in (x for x in qt_state_dict if x in original_state_dict):
+ if group_key in keys:
+ keys.remove(group_key)
+ output_state_dict.pop(group_key, "")
+ output_state_dict[group_key] = LazyCastingParamPiece(caster, prefix + group_key, original_state_dict[group_key])
+ continue
+ output_state_dict[k] = LazyCastingParam(self, key, weight)
+ return output_state_dict
+
+ def state_dict_for_saving(self, clip_state_dict=None, vae_state_dict=None, clip_vision_state_dict=None):
+ unet_state_dict = self.model_state_dict_for_saving(self.model.diffusion_model, "diffusion_model.")
+ return self.model.state_dict_for_saving(unet_state_dict, clip_state_dict=clip_state_dict, vae_state_dict=vae_state_dict, clip_vision_state_dict=clip_vision_state_dict)
+
+ def __del__(self):
+ self.unpin_all_weights()
+ self.detach(unpatch_all=False)
+
+class ModelPatcherDynamic(ModelPatcher):
+
+ def __new__(cls, model=None, load_device=None, offload_device=None, size=0, weight_inplace_update=False):
+ if load_device is not None and comfy.model_management.is_device_cpu(load_device):
+ #reroute to default MP for CPUs
+ return ModelPatcher(model, load_device, offload_device, size, weight_inplace_update)
+ return super().__new__(cls)
+
+ def __init__(self, model, load_device, offload_device, size=0, weight_inplace_update=False):
+ super().__init__(model, load_device, offload_device, size, weight_inplace_update)
+ if not hasattr(self.model, "dynamic_vbars"):
+ self.model.dynamic_vbars = {}
+ if not hasattr(self.model, "dynamic_pins"):
+ self.model.dynamic_pins = {}
+ self.register_load_device(self.load_device)
+ self.non_dynamic_delegate_model = None
+ assert load_device is not None
+ if not hasattr(self.model, "dynamic_patchers"):
+ self.model.dynamic_patchers = set()
+ self.model.dynamic_patchers.add(id(self))
+
+ def register_load_device(self, device):
+ """Ensure dynamic_pins has an entry for *device*.
+
+ Called from __init__ and also from any code that retargets an
+ already-constructed patcher to a new load_device (e.g. the
+ Select{Model,CLIP,VAE}Device selector nodes); without this entry
+ partially_unload_ram() raises KeyError when it tries to read the
+ per-device pin state.
+ """
+ if device not in self.model.dynamic_pins:
+ self.model.dynamic_pins[device] = {
+ "weights": (comfy_aimdo.host_buffer.HostBuffer(0, 0, 0), [], [-1], [0], [0], {}),
+ "patches": (comfy_aimdo.host_buffer.HostBuffer(0, 0, 0), [], [-1], [0], [0], {}),
+ "weights-loaded": (comfy_aimdo.host_buffer.HostBuffer(0, 0, 0), [], [-1], [0], [0], {}),
+ "patches-loaded": (comfy_aimdo.host_buffer.HostBuffer(0, 0, 0), [], [-1], [0], [0], {}),
+ "hostbufs_initialized": False,
+ "failed": False,
+ "active": False,
+ "current_prompt": False,
+ }
+
+ def is_dynamic(self):
+ return True
+
+ def set_in_use_by_current_prompt(self, in_use):
+ self.model.dynamic_pins[self.load_device]["current_prompt"] = in_use
+
+ def _vbar_get(self, create=False):
+ if self.load_device == torch.device("cpu"):
+ return None
+ vbar = self.model.dynamic_vbars.get(self.load_device, None)
+ if create and vbar is None:
+ # x10. We dont know what model defined type casts we have in the vbar, but virtual address
+ # space is pretty free. This will cover someone casting an entire model from FP4 to FP32
+ # with some left over.
+ vbar = comfy_aimdo.model_vbar.ModelVBAR(self.model_size() * 10, self.load_device.index)
+ self.model.dynamic_vbars[self.load_device] = vbar
+ return vbar
+
+ def loaded_size(self):
+ vbar = self._vbar_get()
+ return (vbar.loaded_size() if vbar is not None else 0) + self.model.model_loaded_weight_memory
+
+ #Pinning is deferred to ops time. Assert against this API to avoid pin leaks.
+
+ def pin_weight_to_device(self, key):
+ raise RuntimeError("pin_weight_to_device invalid for dymamic weight loading")
+
+ def unpin_weight(self, key):
+ raise RuntimeError("unpin_weight invalid for dymamic weight loading")
+
+ def unpin_all_weights(self):
+ self.partially_unload_ram(1e32)
+
+ def __del__(self):
+ model = getattr(self, "model", None)
+ dynamic_patchers = getattr(model, "dynamic_patchers", None)
+ if dynamic_patchers is None or id(self) not in dynamic_patchers:
+ return
+ dynamic_patchers.discard(id(self))
+ try:
+ if not dynamic_patchers:
+ self.unpin_all_weights()
+ finally:
+ self.detach(unpatch_all=False)
+
+ def memory_required(self, input_shape):
+ #Pad this significantly. We are trying to get away from precise estimates. This
+ #estimate is only used when using the ModelPatcherDynamic after ModelPatcher. If you
+ #use all ModelPatcherDynamic this is ignored and its all done dynamically.
+ return super().memory_required(input_shape=input_shape) * 1.3 + (1024 ** 3)
+
+ def restore_loaded_backups(self):
+ restored = self.model.model_loaded_weight_memory
+ for key in list(self.backup.keys()):
+ bk = self.backup.pop(key)
+ comfy.utils.set_attr_param(self.model, key, bk.weight)
+ for key in list(self.backup_buffers.keys()):
+ comfy.utils.set_attr_buffer(self.model, key, self.backup_buffers.pop(key))
+ self.model.model_loaded_weight_memory = 0
+ return restored
+
+
+ def load(self, device_to=None, lowvram_model_memory=0, force_patch_weights=False, full_load=False, dirty=False):
+
+ #Force patching doesn't make sense in Dynamic loading, as you dont know what does and
+ #doesn't need to be forced at this stage. The only thing you could do would be patch
+ #it all on CPU which consumes huge RAM.
+ assert not force_patch_weights
+
+ #Full load doesn't make sense as we dont actually have any loader capability here and
+ #now.
+ assert not full_load
+
+ assert device_to == self.load_device
+
+ num_patches = 0
+ allocated_size = 0
+ self.restore_loaded_backups()
+
+ with self.use_ejected():
+ self.unpatch_hooks()
+
+ vbar = self._vbar_get(create=True)
+ pin_state = self.model.dynamic_pins[self.load_device]
+ if not pin_state["hostbufs_initialized"]:
+ hostbuf_size = comfy.model_management.pinned_hostbuf_size(self.model_size())
+ pin_state["weights"] = (comfy_aimdo.host_buffer.HostBuffer(0, 64 * 1024 * 1024, hostbuf_size), [], [-1], [0], [0], {})
+ pin_state["patches"] = (comfy_aimdo.host_buffer.HostBuffer(0, 8 * 1024 * 1024, hostbuf_size), [], [-1], [0], [0], {})
+ pin_state["weights-loaded"] = (comfy_aimdo.host_buffer.HostBuffer(0, 64 * 1024 * 1024, hostbuf_size), [], [-1], [0], [0], {})
+ pin_state["patches-loaded"] = (comfy_aimdo.host_buffer.HostBuffer(0, 8 * 1024 * 1024, hostbuf_size), [], [-1], [0], [0], {})
+ pin_state["hostbufs_initialized"] = True
+ pin_state["failed"] = False
+ pin_state["active"] = True
+ if vbar is not None:
+ vbar.prioritize()
+
+ loading = self._load_list(for_dynamic=True, default_device=device_to)
+ loading.sort()
+
+ for x in loading:
+ *_, module_mem, n, m, params = x
+
+ def set_dirty(item, dirty):
+ if dirty or not hasattr(item, "_v_signature"):
+ item._v_signature = None
+
+ def setup_param(self, m, n, param_key):
+ nonlocal num_patches
+ key = key_param_name_to_key(n, param_key)
+
+ weight_function = []
+
+ weight, _, _ = get_key_weight(self.model, key)
+ if weight is None:
+ return (False, 0)
+ if key in self.patches:
+ if comfy.lora.calculate_shape(self.patches[key], weight, key) != weight.shape:
+ return (True, 0)
+ lowvram_patch = LowVramPatch(key, self.patches)
+ lowvram_patch._pin_state = pin_state
+ setattr(m, param_key + "_lowvram_function", lowvram_patch)
+ num_patches += 1
+ else:
+ setattr(m, param_key + "_lowvram_function", None)
+
+ if key in self.weight_wrapper_patches:
+ weight_function.extend(self.weight_wrapper_patches[key])
+ setattr(m, param_key + "_function", weight_function)
+ geometry = weight
+ if not isinstance(weight, QuantizedTensor):
+ model_dtype = getattr(m, param_key + "_comfy_model_dtype", None) or weight.dtype
+ weight._model_dtype = model_dtype
+ geometry = comfy.memory_management.TensorGeometry(shape=weight.shape, dtype=model_dtype)
+ return (False, comfy.memory_management.vram_aligned_size(geometry))
+
+ def force_load_param(self, param_key, device_to):
+ key = key_param_name_to_key(n, param_key)
+ weight, _, _ = get_key_weight(self.model, key)
+ if weight is None:
+ return
+ if key in self.backup:
+ comfy.utils.set_attr_param(self.model, key, self.backup[key].weight)
+ self.patch_weight_to_device(key, device_to=device_to, force_cast=True)
+ weight, _, _ = get_key_weight(self.model, key)
+ if weight is not None:
+ self.model.model_loaded_weight_memory += weight.numel() * weight.element_size()
+
+ if hasattr(m, "comfy_cast_weights"):
+ m.comfy_cast_weights = True
+ m.seed_key = n
+ m._pin_state = pin_state
+ set_dirty(m, dirty)
+
+ #Models that mix tiny and giant weights can causing lopsided stream buffer
+ #rotations and stall. force the tinys over.
+ if module_mem > 16 * 1024:
+ force_load, v_weight_size = setup_param(self, m, n, "weight")
+ force_load_bias, v_weight_bias = setup_param(self, m, n, "bias")
+ force_load = force_load or force_load_bias
+ v_weight_size += v_weight_bias
+ if force_load:
+ logging.info(f"Module {n} has resizing Lora - force loading")
+ else:
+ force_load=True
+
+ if force_load:
+ if hasattr(m, "_v"):
+ comfy_aimdo.model_vbar.vbar_unpin(m._v)
+ delattr(m, "_v")
+ force_load_param(self, "weight", device_to)
+ force_load_param(self, "bias", device_to)
+ else:
+ if vbar is not None and not hasattr(m, "_v"):
+ m._v = vbar.alloc(v_weight_size)
+ allocated_size += v_weight_size
+
+ for param in params:
+ if param not in ("weight", "bias"):
+ force_load_param(self, param, device_to)
+
+ else:
+ for param in params:
+ key = key_param_name_to_key(n, param)
+ weight, _, _ = get_key_weight(self.model, key)
+ if key not in self.backup:
+ self.backup[key] = collections.namedtuple('Dimension', ['weight', 'inplace_update'])(weight, False)
+ model_dtype = getattr(m, param + "_comfy_model_dtype", None)
+ casted_weight = weight.to(dtype=model_dtype, device=device_to)
+ comfy.utils.set_attr_param(self.model, key, casted_weight)
+ self.model.model_loaded_weight_memory += casted_weight.numel() * casted_weight.element_size()
+
+ move_weight_functions(m, device_to)
+
+ for key, buf in self.model.named_buffers(recurse=True):
+ if key not in self.backup_buffers:
+ self.backup_buffers[key] = buf
+ module, buf_name = comfy.utils.resolve_attr(self.model, key)
+ model_dtype = getattr(module, buf_name + "_comfy_model_dtype", None)
+ casted_buf = buf.to(dtype=model_dtype, device=device_to)
+ comfy.utils.set_attr_buffer(self.model, key, casted_buf)
+ self.model.model_loaded_weight_memory += casted_buf.numel() * casted_buf.element_size()
+
+ force_load_stat = f" Force pre-loaded {len(self.backup)} weights: {self.model.model_loaded_weight_memory // 1024} KB." if len(self.backup) > 0 else ""
+ log_key = (self.patches_uuid, allocated_size, num_patches, len(self.backup), self.model.model_loaded_weight_memory)
+ in_loop = bool(getattr(tqdm.tqdm, "_instances", None))
+ level = logging.DEBUG if in_loop and getattr(self, "_last_prepare_log_key", None) == log_key else logging.INFO
+ self._last_prepare_log_key = log_key
+ logging.log(level, f"Model {self.model.__class__.__name__} prepared for dynamic VRAM loading. {allocated_size // (1024 ** 2)}MB Staged. {num_patches} patches attached.{force_load_stat}")
+
+ self.model.device = device_to
+ self.model.current_weight_patches_uuid = self.patches_uuid
+
+ for callback in self.get_all_callbacks(CallbacksMP.ON_LOAD):
+ #These are all super dangerous. Who knows what the custom nodes actually do here...
+ callback(self, device_to, lowvram_model_memory, force_patch_weights, full_load)
+
+ self.apply_hooks(self.forced_hooks, force_apply=True)
+
+ def partially_unload(self, device_to, memory_to_free=0, force_patch_weights=False):
+ assert not force_patch_weights #See above
+ assert self.load_device != torch.device("cpu")
+
+ vbar = self._vbar_get()
+ vbar_freed = 0 if vbar is None else vbar.free_memory(memory_to_free)
+ freed = vbar_freed
+
+ backup_freed = 0
+ if freed < memory_to_free:
+ backup_freed = self.restore_loaded_backups()
+ freed += backup_freed
+
+ method = "vbar+backups" if vbar_freed and backup_freed else "vbar" if vbar_freed else "backups" if backup_freed else "none"
+ free_methods = getattr(self, "_free_methods", {})
+ free_methods[method] = free_methods.get(method, 0) + 1
+ self._free_methods = free_methods
+ now = time.monotonic()
+ if now - getattr(self, "_last_free_log_time", 0) >= 5:
+ requested = "all" if memory_to_free >= 1e30 else f"{memory_to_free / (1024 ** 2):.1f}MB"
+ prevailing_method = max(free_methods, key=free_methods.get)
+ detail("AIMDO free: model=%s device=%s prevailing_method=%s methods=%s requested=%s vbar_mb=%.1f backups_mb=%.1f", self.model.__class__.__name__, self.load_device, prevailing_method, free_methods, requested, vbar_freed / (1024 ** 2), backup_freed / (1024 ** 2))
+ self._free_methods = {}
+ self._last_free_log_time = now
+
+ return freed
+
+ def loaded_ram_size(self):
+ pin_state = self.model.dynamic_pins[self.load_device]
+ return pin_state["weights"][0].size + pin_state["weights-loaded"][0].size
+
+ def pinned_memory_size(self):
+ pin_state = self.model.dynamic_pins[self.load_device]
+ return pin_state["weights"][3][0] + pin_state["weights-loaded"][3][0]
+
+ def unregister_inactive_pins(self, ram_to_unload, subsets=[ "weights-loaded", "patches-loaded", "weights", "patches" ]):
+ freed = 0
+ pin_state = self.model.dynamic_pins[self.load_device]
+ for subset in subsets:
+ hostbuf, stack, stack_split, pinned_size, *_ = pin_state[subset]
+ split = stack_split[0]
+ while split >= 0:
+ module, offset = stack[split]
+ module_pin = module._pins[subset]
+ split -= 1
+ stack_split[0] = split
+ if not module_pin["registered"]:
+ continue
+ pin = module_pin["pin"]
+ size = pin.numel() * pin.element_size()
+ if torch.cuda.cudart().cudaHostUnregister(pin.data_ptr()) != 0:
+ comfy.model_management.discard_cuda_async_error()
+ continue
+ module_pin["registered"] = False
+ comfy.model_management.TOTAL_PINNED_MEMORY = max(0, comfy.model_management.TOTAL_PINNED_MEMORY - size)
+ pinned_size[0] = max(0, pinned_size[0] - size)
+ freed += size
+ ram_to_unload -= size
+ if ram_to_unload <= 0:
+ return freed
+ return freed
+
+ def partially_unload_ram(self, ram_to_unload, subsets=[ "weights-loaded", "patches-loaded", "weights", "patches" ]):
+ freed = 0
+ pin_state = self.model.dynamic_pins[self.load_device]
+ for subset in subsets:
+ hostbuf, stack, stack_split, pinned_size, *_ = pin_state[subset]
+ while len(stack) > 0:
+ module, offset = stack.pop()
+ module_pin = module._pins[subset]
+ pin = module_pin["pin"]
+ size = pin.numel() * pin.element_size()
+ module_pin["balancer_entry"][-1] = None
+ del module_pin["balancer_entry"]
+ del module_pin["pin"]
+ registered = module_pin["registered"]
+ hostbuf.truncate(offset, do_unregister=registered)
+ stack_split[0] = min(stack_split[0], len(stack) - 1)
+ if registered:
+ comfy.model_management.TOTAL_PINNED_MEMORY = max(0, comfy.model_management.TOTAL_PINNED_MEMORY - size)
+ pinned_size[0] = max(0, pinned_size[0] - size)
+ freed += size
+ ram_to_unload -= size
+ if ram_to_unload <= 0:
+ return freed
+ return freed
+
+ def patch_model(self, device_to=None, lowvram_model_memory=0, load_weights=True, force_patch_weights=False):
+ #This isn't used by the core at all and can only be to load a model out of
+ #the control of proper model_managment. If you are a custom node author reading
+ #this, the correct pattern is to call load_models_gpu() to get a proper
+ #managed load of your model.
+ assert not load_weights
+ return super().patch_model(load_weights=load_weights, force_patch_weights=force_patch_weights)
+
+ def unpatch_model(self, device_to=None, unpatch_weights=True):
+ super().unpatch_model(device_to=None, unpatch_weights=False)
+
+ if unpatch_weights:
+ self.partially_unload_ram(1e32)
+ self.partially_unload(None, 1e32)
+ for m in self.model.modules():
+ move_weight_functions(m, device_to)
+
+ def partially_load(self, device_to, extra_memory=0, force_patch_weights=False):
+ assert not force_patch_weights #See above
+ with self.use_ejected(skip_and_inject_on_exit_only=True):
+ dirty = self.model.current_weight_patches_uuid is not None and (self.model.current_weight_patches_uuid != self.patches_uuid)
+
+ self.unpatch_model(self.offload_device, unpatch_weights=False)
+ self.patch_model(load_weights=False)
+
+ try:
+ self.load(device_to, dirty=dirty)
+ except Exception as e:
+ self.detach()
+ raise e
+ #ModelPatcher::partially_load returns a number on what got loaded but
+ #nothing in core uses this and we have no data in the Dynamic world. Hit
+ #the custom node devs with a None rather than a 0 that would mislead any
+ #logic they might have.
+ return None
+
+ def patch_cached_hook_weights(self, cached_weights: dict, key: str, memory_counter: MemoryCounter):
+ assert False #Should be unreachable - we dont ever cache in the new implementation
+
+ def patch_hook_weight_to_device(self, hooks: comfy.hooks.HookGroup, combined_patches: dict, key: str, original_weights: dict, memory_counter: MemoryCounter):
+ if key not in combined_patches:
+ return
+
+ raise RuntimeError("Hooks not implemented in ModelPatcherDynamic. Please remove --fast arguments form ComfyUI startup")
+
+ def unpatch_hooks(self, whitelist_keys_set: set[str]=None) -> None:
+ pass
+
+ def get_non_dynamic_delegate(self):
+ model_patcher = self.clone(disable_dynamic=True, model_override=self.non_dynamic_delegate_model)
+ self.non_dynamic_delegate_model = model_patcher.get_clone_model_override()
+ return model_patcher
+
+
+CoreModelPatcher = ModelPatcher
diff --git a/ComfyUI/comfy/model_prefetch.py b/ComfyUI/comfy/model_prefetch.py
new file mode 100644
index 0000000000000000000000000000000000000000..aa6d22d77ebb73387319eb423749e69c1662b358
--- /dev/null
+++ b/ComfyUI/comfy/model_prefetch.py
@@ -0,0 +1,77 @@
+import comfy_aimdo.model_vbar
+import comfy.memory_management
+import comfy.model_management
+import comfy.ops
+
+PREFETCH_QUEUES = []
+
+def cleanup_prefetched_modules(comfy_modules):
+ for s in comfy_modules:
+ prefetch = getattr(s, "_prefetch", None)
+ if prefetch is None:
+ continue
+ for param_key in ("weight", "bias"):
+ lowvram_fn = getattr(s, param_key + "_lowvram_function", None)
+ if lowvram_fn is not None:
+ lowvram_fn.clear_prepared()
+ if prefetch["signature"] is not None:
+ comfy_aimdo.model_vbar.vbar_unpin(s._v)
+ delattr(s, "_prefetch")
+
+def cleanup_prefetch_queues():
+ global PREFETCH_QUEUES
+
+ for queue in PREFETCH_QUEUES:
+ for entry in queue:
+ if entry is None or not isinstance(entry, tuple):
+ continue
+ _, prefetch_state = entry
+ comfy_modules = prefetch_state[1]
+ if comfy_modules is not None:
+ cleanup_prefetched_modules(comfy_modules)
+ PREFETCH_QUEUES = []
+
+def prefetch_queue_pop(queue, device, module):
+ if queue is None:
+ return
+
+ consumed = queue.pop(0)
+ if consumed is not None:
+ offload_stream, prefetch_state = consumed
+ if offload_stream is not None:
+ offload_stream.wait_stream(comfy.model_management.current_stream(device))
+ _, comfy_modules = prefetch_state
+ if comfy_modules is not None:
+ cleanup_prefetched_modules(comfy_modules)
+
+ prefetch = queue[0]
+ if prefetch is not None:
+ comfy_modules = []
+ for s in prefetch.modules():
+ if hasattr(s, "_v"):
+ comfy_modules.append(s)
+
+ registerable_size = 0
+ for s in comfy_modules:
+ registerable_size += comfy.memory_management.vram_aligned_size([s.weight, s.bias])
+ for param_key in ("weight", "bias"):
+ lowvram_fn = getattr(s, param_key + "_lowvram_function", None)
+ if lowvram_fn is not None:
+ registerable_size += lowvram_fn.memory_required()
+
+ offload_stream = comfy.ops.cast_modules_with_vbar(comfy_modules, None, device, None, True)
+ if not comfy.model_management.args.fast_disk:
+ comfy.model_management.ensure_pin_registerable(registerable_size)
+ comfy.model_management.sync_stream(device, offload_stream)
+ queue[0] = (offload_stream, (prefetch, comfy_modules))
+
+def make_prefetch_queue(queue, device, transformer_options):
+ if (not transformer_options.get("prefetch_dynamic_vbars", False)
+ or comfy.model_management.NUM_STREAMS == 0
+ or comfy.model_management.is_device_cpu(device)
+ or not comfy.model_management.device_supports_non_blocking(device)):
+ return None
+
+ queue = [None] + queue + [None]
+ PREFETCH_QUEUES.append(queue)
+ return queue
diff --git a/ComfyUI/comfy/model_sampling.py b/ComfyUI/comfy/model_sampling.py
new file mode 100644
index 0000000000000000000000000000000000000000..5af336e76fd480a50425dd924f2ac9752083c09f
--- /dev/null
+++ b/ComfyUI/comfy/model_sampling.py
@@ -0,0 +1,431 @@
+import torch
+from comfy.ldm.modules.diffusionmodules.util import make_beta_schedule
+import math
+
+def rescale_zero_terminal_snr_sigmas(sigmas):
+ alphas_cumprod = 1 / ((sigmas * sigmas) + 1)
+ alphas_bar_sqrt = alphas_cumprod.sqrt()
+
+ # Store old values.
+ alphas_bar_sqrt_0 = alphas_bar_sqrt[0].clone()
+ alphas_bar_sqrt_T = alphas_bar_sqrt[-1].clone()
+
+ # Shift so the last timestep is zero.
+ alphas_bar_sqrt -= (alphas_bar_sqrt_T)
+
+ # Scale so the first timestep is back to the old value.
+ alphas_bar_sqrt *= alphas_bar_sqrt_0 / (alphas_bar_sqrt_0 - alphas_bar_sqrt_T)
+
+ # Convert alphas_bar_sqrt to betas
+ alphas_bar = alphas_bar_sqrt**2 # Revert sqrt
+ alphas_bar[-1] = 4.8973451890853435e-08
+ return ((1 - alphas_bar) / alphas_bar) ** 0.5
+
+def reshape_sigma(sigma, noise_dim):
+ if sigma.nelement() == 1:
+ return sigma.view(())
+ else:
+ return sigma.view(sigma.shape[:1] + (1,) * (noise_dim - 1))
+
+class EPS:
+ def calculate_input(self, sigma, noise):
+ sigma = reshape_sigma(sigma, noise.ndim)
+ return noise / (sigma ** 2 + self.sigma_data ** 2) ** 0.5
+
+ def calculate_denoised(self, sigma, model_output, model_input):
+ sigma = reshape_sigma(sigma, model_output.ndim)
+ return model_input - model_output * sigma
+
+ def noise_scaling(self, sigma, noise, latent_image, max_denoise=False):
+ sigma = reshape_sigma(sigma, noise.ndim)
+ if max_denoise:
+ noise = noise * torch.sqrt(1.0 + sigma ** 2.0)
+ else:
+ noise = noise * sigma
+
+ noise += latent_image
+ return noise
+
+ def inverse_noise_scaling(self, sigma, latent):
+ return latent
+
+class V_PREDICTION(EPS):
+ def calculate_denoised(self, sigma, model_output, model_input):
+ sigma = reshape_sigma(sigma, model_output.ndim)
+ return model_input * self.sigma_data ** 2 / (sigma ** 2 + self.sigma_data ** 2) - model_output * sigma * self.sigma_data / (sigma ** 2 + self.sigma_data ** 2) ** 0.5
+
+class V_PREDICTION_DDPM:
+ """CogVideoX v-prediction: model receives raw x_t (unscaled), predicts velocity v.
+ x_0 = sqrt(alpha) * x_t - sqrt(1-alpha) * v
+ = x_t / sqrt(sigma^2 + 1) - v * sigma / sqrt(sigma^2 + 1)
+ """
+ def calculate_input(self, sigma, noise):
+ return noise
+
+ def calculate_denoised(self, sigma, model_output, model_input):
+ sigma = reshape_sigma(sigma, model_output.ndim)
+ return model_input / (sigma ** 2 + 1.0) ** 0.5 - model_output * sigma / (sigma ** 2 + 1.0) ** 0.5
+
+ def noise_scaling(self, sigma, noise, latent_image, max_denoise=False):
+ sigma = reshape_sigma(sigma, noise.ndim)
+ if max_denoise:
+ noise = noise * torch.sqrt(1.0 + sigma ** 2.0)
+ else:
+ noise = noise * sigma
+ noise += latent_image
+ return noise
+
+ def inverse_noise_scaling(self, sigma, latent):
+ return latent
+
+class EDM(V_PREDICTION):
+ def calculate_denoised(self, sigma, model_output, model_input):
+ sigma = reshape_sigma(sigma, model_output.ndim)
+ return model_input * self.sigma_data ** 2 / (sigma ** 2 + self.sigma_data ** 2) + model_output * sigma * self.sigma_data / (sigma ** 2 + self.sigma_data ** 2) ** 0.5
+
+class CONST:
+ def calculate_input(self, sigma, noise):
+ return noise
+
+ def calculate_denoised(self, sigma, model_output, model_input):
+ sigma = reshape_sigma(sigma, model_output.ndim)
+ return model_input - model_output * sigma
+
+ def noise_scaling(self, sigma, noise, latent_image, max_denoise=False):
+ sigma = reshape_sigma(sigma, noise.ndim)
+ s = getattr(self, "noise_scale", 1.0)
+ return sigma * (s * noise) + (1.0 - sigma) * latent_image
+
+ def inverse_noise_scaling(self, sigma, latent):
+ sigma = reshape_sigma(sigma, latent.ndim)
+ return latent / (1.0 - sigma)
+
+class X0(EPS):
+ def calculate_denoised(self, sigma, model_output, model_input):
+ return model_output
+
+class IMG_TO_IMG(X0):
+ def calculate_input(self, sigma, noise):
+ return noise
+
+class IMG_TO_IMG_FLOW(CONST):
+ def calculate_denoised(self, sigma, model_output, model_input):
+ return model_output
+
+ def noise_scaling(self, sigma, noise, latent_image, max_denoise=False):
+ return latent_image
+
+ def inverse_noise_scaling(self, sigma, latent):
+ return 1.0 - latent
+
+class COSMOS_RFLOW:
+ def calculate_input(self, sigma, noise):
+ sigma = (sigma / (sigma + 1))
+ sigma = reshape_sigma(sigma, noise.ndim)
+ return noise * (1.0 - sigma)
+
+ def calculate_denoised(self, sigma, model_output, model_input):
+ sigma = (sigma / (sigma + 1))
+ sigma = reshape_sigma(sigma, model_output.ndim)
+ return model_input * (1.0 - sigma) - model_output * sigma
+
+ def noise_scaling(self, sigma, noise, latent_image, max_denoise=False):
+ sigma = reshape_sigma(sigma, noise.ndim)
+ noise = noise * sigma
+ noise += latent_image
+ return noise
+
+ def inverse_noise_scaling(self, sigma, latent):
+ return latent
+
+class ModelSamplingDiscrete(torch.nn.Module):
+ def __init__(self, model_config=None, zsnr=None):
+ super().__init__()
+
+ if model_config is not None:
+ sampling_settings = model_config.sampling_settings
+ else:
+ sampling_settings = {}
+
+ beta_schedule = sampling_settings.get("beta_schedule", "linear")
+ linear_start = sampling_settings.get("linear_start", 0.00085)
+ linear_end = sampling_settings.get("linear_end", 0.012)
+ timesteps = sampling_settings.get("timesteps", 1000)
+
+ if zsnr is None:
+ zsnr = sampling_settings.get("zsnr", False)
+
+ self._register_schedule(given_betas=None, beta_schedule=beta_schedule, timesteps=timesteps, linear_start=linear_start, linear_end=linear_end, cosine_s=8e-3, zsnr=zsnr)
+ self.sigma_data = 1.0
+
+ def _register_schedule(self, given_betas=None, beta_schedule="linear", timesteps=1000,
+ linear_start=1e-4, linear_end=2e-2, cosine_s=8e-3, zsnr=False):
+ if given_betas is not None:
+ betas = given_betas
+ else:
+ betas = make_beta_schedule(beta_schedule, timesteps, linear_start=linear_start, linear_end=linear_end, cosine_s=cosine_s)
+ alphas = 1. - betas
+ alphas_cumprod = torch.cumprod(alphas, dim=0)
+
+ timesteps, = betas.shape
+ self.num_timesteps = int(timesteps)
+ self.linear_start = linear_start
+ self.linear_end = linear_end
+ self.zsnr = zsnr
+
+ # self.register_buffer('betas', torch.tensor(betas, dtype=torch.float32))
+ # self.register_buffer('alphas_cumprod', torch.tensor(alphas_cumprod, dtype=torch.float32))
+ # self.register_buffer('alphas_cumprod_prev', torch.tensor(alphas_cumprod_prev, dtype=torch.float32))
+
+ sigmas = ((1 - alphas_cumprod) / alphas_cumprod) ** 0.5
+ if self.zsnr:
+ sigmas = rescale_zero_terminal_snr_sigmas(sigmas)
+
+ self.set_sigmas(sigmas)
+
+ def set_sigmas(self, sigmas):
+ self.register_buffer('sigmas', sigmas.float())
+ self.register_buffer('log_sigmas', sigmas.log().float())
+
+ @property
+ def sigma_min(self):
+ return self.sigmas[0]
+
+ @property
+ def sigma_max(self):
+ return self.sigmas[-1]
+
+ def timestep(self, sigma):
+ log_sigma = sigma.log()
+ dists = log_sigma.to(self.log_sigmas.device) - self.log_sigmas[:, None]
+ return dists.abs().argmin(dim=0).view(sigma.shape).to(sigma.device)
+
+ def sigma(self, timestep):
+ t = torch.clamp(timestep.float().to(self.log_sigmas.device), min=0, max=(len(self.sigmas) - 1))
+ low_idx = t.floor().long()
+ high_idx = t.ceil().long()
+ w = t.frac()
+ log_sigma = (1 - w) * self.log_sigmas[low_idx] + w * self.log_sigmas[high_idx]
+ return log_sigma.exp().to(timestep.device)
+
+ def percent_to_sigma(self, percent):
+ if percent <= 0.0:
+ return 999999999.9
+ if percent >= 1.0:
+ return 0.0
+ percent = 1.0 - percent
+ return self.sigma(torch.tensor(percent * 999.0)).item()
+
+class ModelSamplingDiscreteEDM(ModelSamplingDiscrete):
+ def timestep(self, sigma):
+ return 0.25 * sigma.log()
+
+ def sigma(self, timestep):
+ return (timestep / 0.25).exp()
+
+class ModelSamplingContinuousEDM(torch.nn.Module):
+ def __init__(self, model_config=None):
+ super().__init__()
+ if model_config is not None:
+ sampling_settings = model_config.sampling_settings
+ else:
+ sampling_settings = {}
+
+ sigma_min = sampling_settings.get("sigma_min", 0.002)
+ sigma_max = sampling_settings.get("sigma_max", 120.0)
+ sigma_data = sampling_settings.get("sigma_data", 1.0)
+ self.set_parameters(sigma_min, sigma_max, sigma_data)
+
+ def set_parameters(self, sigma_min, sigma_max, sigma_data):
+ self.sigma_data = sigma_data
+ sigmas = torch.linspace(math.log(sigma_min), math.log(sigma_max), 1000).exp()
+
+ self.register_buffer('sigmas', sigmas) #for compatibility with some schedulers
+ self.register_buffer('log_sigmas', sigmas.log())
+
+ @property
+ def sigma_min(self):
+ return self.sigmas[0]
+
+ @property
+ def sigma_max(self):
+ return self.sigmas[-1]
+
+ def timestep(self, sigma):
+ return 0.25 * sigma.log()
+
+ def sigma(self, timestep):
+ return (timestep / 0.25).exp()
+
+ def percent_to_sigma(self, percent):
+ if percent <= 0.0:
+ return 999999999.9
+ if percent >= 1.0:
+ return 0.0
+ percent = 1.0 - percent
+
+ log_sigma_min = math.log(self.sigma_min)
+ return math.exp((math.log(self.sigma_max) - log_sigma_min) * percent + log_sigma_min)
+
+
+class ModelSamplingContinuousV(ModelSamplingContinuousEDM):
+ def timestep(self, sigma):
+ return sigma.atan() / math.pi * 2
+
+ def sigma(self, timestep):
+ return (timestep * math.pi / 2).tan()
+
+
+def time_snr_shift(alpha, t):
+ if alpha == 1.0:
+ return t
+ return alpha * t / (1 + (alpha - 1) * t)
+
+class ModelSamplingDiscreteFlow(torch.nn.Module):
+ def __init__(self, model_config=None):
+ super().__init__()
+ if model_config is not None:
+ sampling_settings = model_config.sampling_settings
+ else:
+ sampling_settings = {}
+
+ self.set_noise_scale(sampling_settings.get("noise_scale", 1.0))
+ self.set_parameters(
+ shift=sampling_settings.get("shift", 1.0),
+ multiplier=sampling_settings.get("multiplier", 1000),
+ )
+
+ def set_parameters(self, shift=1.0, timesteps=1000, multiplier=1000):
+ self.shift = shift
+ self.multiplier = multiplier
+ ts = self.sigma((torch.arange(1, timesteps + 1, 1) / timesteps) * multiplier)
+ self.register_buffer('sigmas', ts)
+
+ def set_noise_scale(self, noise_scale):
+ self.noise_scale = float(noise_scale)
+
+ @property
+ def sigma_min(self):
+ return self.sigmas[0]
+
+ @property
+ def sigma_max(self):
+ return self.sigmas[-1]
+
+ def timestep(self, sigma):
+ return sigma * self.multiplier
+
+ def sigma(self, timestep):
+ return time_snr_shift(self.shift, timestep / self.multiplier)
+
+ def percent_to_sigma(self, percent):
+ if percent <= 0.0:
+ return 1.0
+ if percent >= 1.0:
+ return 0.0
+ return time_snr_shift(self.shift, 1.0 - percent)
+
+class StableCascadeSampling(ModelSamplingDiscrete):
+ def __init__(self, model_config=None):
+ super().__init__()
+
+ if model_config is not None:
+ sampling_settings = model_config.sampling_settings
+ else:
+ sampling_settings = {}
+
+ self.set_parameters(sampling_settings.get("shift", 1.0))
+
+ def set_parameters(self, shift=1.0, cosine_s=8e-3):
+ self.shift = shift
+ self.cosine_s = torch.tensor(cosine_s)
+ self._init_alpha_cumprod = torch.cos(self.cosine_s / (1 + self.cosine_s) * torch.pi * 0.5) ** 2
+
+ #This part is just for compatibility with some schedulers in the codebase
+ self.num_timesteps = 10000
+ sigmas = torch.empty((self.num_timesteps), dtype=torch.float32)
+ for x in range(self.num_timesteps):
+ t = (x + 1) / self.num_timesteps
+ sigmas[x] = self.sigma(t)
+
+ self.set_sigmas(sigmas)
+
+ def sigma(self, timestep):
+ alpha_cumprod = (torch.cos((timestep + self.cosine_s) / (1 + self.cosine_s) * torch.pi * 0.5) ** 2 / self._init_alpha_cumprod)
+
+ if self.shift != 1.0:
+ var = alpha_cumprod
+ logSNR = (var/(1-var)).log()
+ logSNR += 2 * torch.log(1.0 / torch.tensor(self.shift))
+ alpha_cumprod = logSNR.sigmoid()
+
+ alpha_cumprod = alpha_cumprod.clamp(0.0001, 0.9999)
+ return ((1 - alpha_cumprod) / alpha_cumprod) ** 0.5
+
+ def timestep(self, sigma):
+ var = 1 / ((sigma * sigma) + 1)
+ var = var.clamp(0, 1.0)
+ s, min_var = self.cosine_s.to(var.device), self._init_alpha_cumprod.to(var.device)
+ t = (((var * min_var) ** 0.5).acos() / (torch.pi * 0.5)) * (1 + s) - s
+ return t
+
+ def percent_to_sigma(self, percent):
+ if percent <= 0.0:
+ return 999999999.9
+ if percent >= 1.0:
+ return 0.0
+
+ percent = 1.0 - percent
+ return self.sigma(torch.tensor(percent))
+
+
+def flux_time_shift(mu: float, sigma: float, t):
+ return math.exp(mu) / (math.exp(mu) + (1 / t - 1) ** sigma)
+
+class ModelSamplingFlux(torch.nn.Module):
+ def __init__(self, model_config=None):
+ super().__init__()
+ if model_config is not None:
+ sampling_settings = model_config.sampling_settings
+ else:
+ sampling_settings = {}
+
+ self.set_parameters(shift=sampling_settings.get("shift", 1.15))
+
+ def set_parameters(self, shift=1.15, timesteps=10000):
+ self.shift = shift
+ ts = self.sigma((torch.arange(1, timesteps + 1, 1) / timesteps))
+ self.register_buffer('sigmas', ts)
+
+ @property
+ def sigma_min(self):
+ return self.sigmas[0]
+
+ @property
+ def sigma_max(self):
+ return self.sigmas[-1]
+
+ def timestep(self, sigma):
+ return sigma
+
+ def sigma(self, timestep):
+ return flux_time_shift(self.shift, 1.0, timestep)
+
+ def percent_to_sigma(self, percent):
+ if percent <= 0.0:
+ return 1.0
+ if percent >= 1.0:
+ return 0.0
+ return flux_time_shift(self.shift, 1.0, 1.0 - percent)
+
+
+class ModelSamplingCosmosRFlow(ModelSamplingContinuousEDM):
+ def timestep(self, sigma):
+ return sigma / (sigma + 1)
+
+ def sigma(self, timestep):
+ sigma_max = self.sigma_max
+ if timestep >= (sigma_max / (sigma_max + 1)):
+ return sigma_max
+
+ return timestep / (1 - timestep)
diff --git a/ComfyUI/comfy/multigpu.py b/ComfyUI/comfy/multigpu.py
new file mode 100644
index 0000000000000000000000000000000000000000..2b6d8260daa72892fc09ffa84fe779bb9bc6a549
--- /dev/null
+++ b/ComfyUI/comfy/multigpu.py
@@ -0,0 +1,250 @@
+from __future__ import annotations
+import queue
+import threading
+import torch
+import logging
+
+from collections import namedtuple
+from typing import TYPE_CHECKING
+if TYPE_CHECKING:
+ from comfy.model_patcher import ModelPatcher
+import comfy.utils
+import comfy.patcher_extension
+import comfy.model_management
+
+
+class MultiGPUThreadPool:
+ """Persistent thread pool for multi-GPU work distribution.
+
+ Maintains one worker thread per extra GPU device. Each thread calls
+ set_torch_device() once at startup so that compiled kernel caches
+ (inductor/triton) stay warm across diffusion steps.
+ """
+
+ def __init__(self, devices: list[torch.device]):
+ self._workers: list[threading.Thread] = []
+ self._work_queues: dict[torch.device, queue.Queue] = {}
+ self._result_queues: dict[torch.device, queue.Queue] = {}
+
+ for device in devices:
+ wq = queue.Queue()
+ rq = queue.Queue()
+ self._work_queues[device] = wq
+ self._result_queues[device] = rq
+ t = threading.Thread(target=self._worker_loop, args=(device, wq, rq), daemon=True)
+ t.start()
+ self._workers.append(t)
+
+ def _worker_loop(self, device: torch.device, work_q: queue.Queue, result_q: queue.Queue):
+ try:
+ comfy.model_management.set_torch_device(device)
+ except Exception as e:
+ logging.error(f"MultiGPUThreadPool: failed to set device {device}: {e}")
+ while True:
+ item = work_q.get()
+ if item is None:
+ return
+ result_q.put((None, e))
+ return
+ while True:
+ item = work_q.get()
+ if item is None:
+ break
+ fn, args, kwargs = item
+ try:
+ result = fn(*args, **kwargs)
+ result_q.put((result, None))
+ except comfy.model_management.InterruptProcessingException as e:
+ result_q.put((None, e))
+ except Exception as e:
+ result_q.put((None, e))
+
+ def submit(self, device: torch.device, fn, *args, **kwargs):
+ self._work_queues[device].put((fn, args, kwargs))
+
+ def get_result(self, device: torch.device):
+ return self._result_queues[device].get()
+
+ @property
+ def devices(self) -> list[torch.device]:
+ return list(self._work_queues.keys())
+
+ def shutdown(self):
+ for wq in self._work_queues.values():
+ wq.put(None) # sentinel
+ for t in self._workers:
+ t.join(timeout=5.0)
+
+
+class GPUOptions:
+ def __init__(self, device_index: int, relative_speed: float):
+ self.device_index = device_index
+ self.relative_speed = relative_speed
+
+ def clone(self):
+ return GPUOptions(self.device_index, self.relative_speed)
+
+ def create_dict(self):
+ return {
+ "relative_speed": self.relative_speed
+ }
+
+class GPUOptionsGroup:
+ def __init__(self):
+ self.options: dict[int, GPUOptions] = {}
+
+ def add(self, info: GPUOptions):
+ self.options[info.device_index] = info
+
+ def clone(self):
+ c = GPUOptionsGroup()
+ for opt in self.options.values():
+ c.add(opt)
+ return c
+
+ def register(self, model: ModelPatcher):
+ opts_dict = {}
+ # get devices that are valid for this model
+ devices: list[torch.device] = [model.load_device]
+ for extra_model in model.get_additional_models_with_key("multigpu"):
+ extra_model: ModelPatcher
+ devices.append(extra_model.load_device)
+ # create dictionary with actual device mapped to its GPUOptions
+ device_opts_list: list[GPUOptions] = []
+ for device in devices:
+ device_opts = self.options.get(device.index, GPUOptions(device_index=device.index, relative_speed=1.0))
+ opts_dict[device] = device_opts.create_dict()
+ device_opts_list.append(device_opts)
+ # make relative_speed relative to 1.0
+ min_speed = min([x.relative_speed for x in device_opts_list])
+ for value in opts_dict.values():
+ value['relative_speed'] /= min_speed
+ model.model_options['multigpu_options'] = opts_dict
+
+
+def create_multigpu_deepclones(model: ModelPatcher, max_gpus: int, gpu_options: GPUOptionsGroup=None, reuse_loaded=False):
+ 'Prepare ModelPatcher to contain deepclones of its BaseModel and related properties.'
+ model = model.clone()
+ # check if multigpu is already prepared - get the load devices from them if possible to exclude
+ skip_devices = set()
+ multigpu_models = model.get_additional_models_with_key("multigpu")
+ if len(multigpu_models) > 0:
+ for mm in multigpu_models:
+ skip_devices.add(mm.load_device)
+ skip_devices = list(skip_devices)
+
+ # Exclude the primary model's actual device, not the global current device:
+ # after SelectModelDevice(gpu:N) the primary may not live on the process's
+ # current CUDA device, and excluding the wrong device picks bad extras.
+ all_devices = comfy.model_management.get_all_torch_devices(exclude_current=False)
+ full_extra_devices = [d for d in all_devices if d != model.load_device]
+ limit_extra_devices = full_extra_devices[:max_gpus-1]
+ extra_devices = limit_extra_devices.copy()
+ # exclude skipped devices
+ for skip in skip_devices:
+ if skip in extra_devices:
+ extra_devices.remove(skip)
+ # create new deepclones
+ if len(extra_devices) > 0:
+ for device in extra_devices:
+ device_patcher = None
+ if reuse_loaded:
+ # Only reuse a previously-loaded MultiGPU clone. A SelectModelDevice
+ # patcher on the same device shares clone_base_uuid but has
+ # is_multigpu_base_clone=False, which would later be filtered out by
+ # prepare_model_patcher_multigpu_clones() and silently shrink the
+ # work split back to one GPU.
+ loaded_models: list[ModelPatcher] = comfy.model_management.loaded_models()
+ for lm in loaded_models:
+ if lm.model is None:
+ continue
+ if lm.load_device != device:
+ continue
+ if lm.clone_base_uuid != model.clone_base_uuid:
+ continue
+ if not getattr(lm, "is_multigpu_base_clone", False):
+ continue
+ device_patcher = lm.clone()
+ logging.info(f"Reusing loaded multigpu deepclone of {device_patcher.model.__class__.__name__} for {device}")
+ break
+ if device_patcher is None:
+ device_patcher = model.deepclone_multigpu(new_load_device=device)
+ # Always flag the clone; whether reused or freshly deepcloned, it must
+ # advertise itself as a MultiGPU base clone so the cond scheduler picks
+ # it up in prepare_model_patcher_multigpu_clones().
+ device_patcher.is_multigpu_base_clone = True
+ multigpu_models = model.get_additional_models_with_key("multigpu")
+ multigpu_models.append(device_patcher)
+ model.set_additional_models("multigpu", multigpu_models)
+ model.match_multigpu_clones()
+ if gpu_options is None:
+ gpu_options = GPUOptionsGroup()
+ gpu_options.register(model)
+ else:
+ logging.info("No extra torch devices need initialization, skipping initializing MultiGPU Work Units.")
+ # only keep model clones that don't go 'past' the intended max_gpu count;
+ # this prunes any inherited multigpu clones whose load_device is no longer allowed
+ # when max_gpus is lowered between runs.
+ allowed_devices = set(limit_extra_devices)
+ allowed_devices.add(model.load_device)
+ multigpu_models = model.get_additional_models_with_key("multigpu")
+ new_multigpu_models = [m for m in multigpu_models if m.load_device in allowed_devices]
+ if len(new_multigpu_models) != len(multigpu_models):
+ model.set_additional_models("multigpu", new_multigpu_models)
+ model.match_multigpu_clones()
+ return model
+
+
+LoadBalance = namedtuple('LoadBalance', ['work_per_device', 'idle_time'])
+def load_balance_devices(model_options: dict[str], total_work: int, return_idle_time=False, work_normalized: int=None):
+ 'Optimize work assigned to different devices, accounting for their relative speeds and splittable work.'
+ opts_dict = model_options['multigpu_options']
+ devices = list(model_options['multigpu_clones'].keys())
+ speed_per_device = []
+ work_per_device = []
+ # get sum of each device's relative_speed
+ total_speed = 0.0
+ for opts in opts_dict.values():
+ total_speed += opts['relative_speed']
+ # get relative work for each device;
+ # obtained by w = (W*r)/R
+ for device in devices:
+ relative_speed = opts_dict[device]['relative_speed']
+ relative_work = (total_work*relative_speed) / total_speed
+ speed_per_device.append(relative_speed)
+ work_per_device.append(relative_work)
+ # relative work must be expressed in whole numbers, but likely is a decimal;
+ # perform rounding while maintaining total sum equal to total work (sum of relative works)
+ work_per_device = round_preserved(work_per_device)
+ dict_work_per_device = {}
+ for device, relative_work in zip(devices, work_per_device):
+ dict_work_per_device[device] = relative_work
+ if not return_idle_time:
+ return LoadBalance(dict_work_per_device, None)
+ # divide relative work by relative speed to get estimated completion time of said work by each device;
+ # time here is relative and does not correspond to real-world units
+ completion_time = [w/r for w,r in zip(work_per_device, speed_per_device)]
+ # calculate relative time spent by the devices waiting on each other after their work is completed
+ idle_time = abs(min(completion_time) - max(completion_time))
+ # if need to compare work idle time, need to normalize to a common total work
+ if work_normalized:
+ idle_time *= (work_normalized/total_work)
+
+ return LoadBalance(dict_work_per_device, idle_time)
+
+def round_preserved(values: list[float]):
+ 'Round all values in a list, preserving the combined sum of values.'
+ # get floor of values; casting to int does it too
+ floored = [int(x) for x in values]
+ total_floored = sum(floored)
+ # get remainder to distribute
+ remainder = round(sum(values)) - total_floored
+ # pair values with fractional portions
+ fractional = [(i, x-floored[i]) for i, x in enumerate(values)]
+ # sort by fractional part in descending order
+ fractional.sort(key=lambda x: x[1], reverse=True)
+ # distribute the remainder
+ for i in range(remainder):
+ index = fractional[i][0]
+ floored[index] += 1
+ return floored
diff --git a/ComfyUI/comfy/nested_tensor.py b/ComfyUI/comfy/nested_tensor.py
new file mode 100644
index 0000000000000000000000000000000000000000..08c7133f8eb1cd147269a3be25089455258cb475
--- /dev/null
+++ b/ComfyUI/comfy/nested_tensor.py
@@ -0,0 +1,94 @@
+import torch
+
+class NestedTensor:
+ def __init__(self, tensors):
+ self.tensors = list(tensors)
+ self.is_nested = True
+
+ def _copy(self):
+ return NestedTensor(self.tensors)
+
+ def apply_operation(self, other, operation):
+ o = self._copy()
+ if isinstance(other, NestedTensor):
+ for i, t in enumerate(o.tensors):
+ o.tensors[i] = operation(t, other.tensors[i])
+ else:
+ for i, t in enumerate(o.tensors):
+ o.tensors[i] = operation(t, other)
+ return o
+
+ def __add__(self, b):
+ return self.apply_operation(b, lambda x, y: x + y)
+
+ def __sub__(self, b):
+ return self.apply_operation(b, lambda x, y: x - y)
+
+ def __mul__(self, b):
+ return self.apply_operation(b, lambda x, y: x * y)
+
+ # def __itruediv__(self, b):
+ # return self.apply_operation(b, lambda x, y: x / y)
+
+ def __truediv__(self, b):
+ return self.apply_operation(b, lambda x, y: x / y)
+
+ def __getitem__(self, *args, **kwargs):
+ return self.apply_operation(None, lambda x, y: x.__getitem__(*args, **kwargs))
+
+ def unbind(self):
+ return self.tensors
+
+ def to(self, *args, **kwargs):
+ o = self._copy()
+ for i, t in enumerate(o.tensors):
+ o.tensors[i] = t.to(*args, **kwargs)
+ return o
+
+ def new_ones(self, *args, **kwargs):
+ return self.tensors[0].new_ones(*args, **kwargs)
+
+ def float(self):
+ return self.to(dtype=torch.float)
+
+ def cpu(self):
+ return self.to(device="cpu")
+
+ def chunk(self, *args, **kwargs):
+ return self.apply_operation(None, lambda x, y: x.chunk(*args, **kwargs))
+
+ def size(self):
+ return self.tensors[0].size()
+
+ @property
+ def shape(self):
+ return self.tensors[0].shape
+
+ @property
+ def ndim(self):
+ dims = 0
+ for t in self.tensors:
+ dims = max(t.ndim, dims)
+ return dims
+
+ @property
+ def device(self):
+ return self.tensors[0].device
+
+ @property
+ def dtype(self):
+ return self.tensors[0].dtype
+
+ @property
+ def layout(self):
+ return self.tensors[0].layout
+
+
+def cat_nested(tensors, *args, **kwargs):
+ cated_tensors = []
+ for i in range(len(tensors[0].tensors)):
+ tens = []
+ for j in range(len(tensors)):
+ tens.append(tensors[j].tensors[i])
+ cated_tensors.append(torch.cat(tens, *args, **kwargs))
+ return NestedTensor(cated_tensors)
diff --git a/ComfyUI/comfy/ops.py b/ComfyUI/comfy/ops.py
new file mode 100644
index 0000000000000000000000000000000000000000..7cf077eeaf8ecdf2bc81f635ac18d02c9c32562d
--- /dev/null
+++ b/ComfyUI/comfy/ops.py
@@ -0,0 +1,1688 @@
+"""
+ This file is part of ComfyUI.
+ Copyright (C) 2024 Stability AI
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see .
+"""
+
+import torch
+import logging
+import contextlib
+import inspect
+import comfy.model_management
+from comfy.cli_args import args, PerformanceFeature
+import comfy.float
+import json
+import comfy.memory_management
+import comfy.pinned_memory
+import comfy.utils
+
+import comfy_aimdo.model_vbar
+import comfy_aimdo.torch
+
+def run_every_op():
+ if torch.compiler.is_compiling():
+ return
+
+ comfy.model_management.throw_exception_if_processing_interrupted()
+
+def gqa_repeat_factor(query_heads, key_heads, value_heads):
+ if key_heads != value_heads:
+ raise ValueError(f"Key/value head count mismatch for GQA: {key_heads} != {value_heads}")
+ if query_heads == key_heads:
+ return 1
+ if query_heads % key_heads != 0:
+ raise ValueError(f"Query heads must be divisible by key/value heads for GQA: {query_heads} vs {key_heads}")
+ return query_heads // key_heads
+
+def repeat_kv_for_gqa(k, v, query_heads, head_dim):
+ n_rep = gqa_repeat_factor(query_heads, k.shape[head_dim], v.shape[head_dim])
+ if n_rep > 1:
+ k = k.repeat_interleave(n_rep, dim=head_dim)
+ v = v.repeat_interleave(n_rep, dim=head_dim)
+ return k, v
+
+def scaled_dot_product_attention(q, k, v, *args, **kwargs):
+ attn_mask = args[0] if len(args) > 0 else kwargs.get("attn_mask")
+ if kwargs.get("enable_gqa", False) and attn_mask is not None:
+ k, v = repeat_kv_for_gqa(k, v, q.shape[-3], -3)
+ kwargs["enable_gqa"] = False
+ return torch.nn.functional.scaled_dot_product_attention(q, k, v, *args, **kwargs)
+
+
+try:
+ if torch.cuda.is_available():
+ from torch.nn.attention import SDPBackend, sdpa_kernel
+ if "set_priority" in inspect.signature(sdpa_kernel).parameters:
+ SDPA_BACKEND_PRIORITY = [
+ SDPBackend.FLASH_ATTENTION,
+ SDPBackend.CUDNN_ATTENTION,
+ SDPBackend.EFFICIENT_ATTENTION,
+ SDPBackend.MATH,
+ ]
+
+ def scaled_dot_product_attention(q, k, v, *args, **kwargs):
+ if q.nelement() < 1024 * 128: # arbitrary number, for small inputs cudnn attention seems slower
+ return torch.nn.functional.scaled_dot_product_attention(q, k, v, *args, **kwargs)
+ attn_mask = args[0] if len(args) > 0 else kwargs.get("attn_mask")
+ if kwargs.get("enable_gqa", False) and attn_mask is not None and not comfy.model_management.is_nvidia():
+ k, v = repeat_kv_for_gqa(k, v, q.shape[-3], -3)
+ kwargs["enable_gqa"] = False
+ with sdpa_kernel(SDPA_BACKEND_PRIORITY, set_priority=True):
+ if kwargs.get("enable_gqa", False) and attn_mask is not None and q.shape[-3] != k.shape[-3]:
+ dropout_p = args[1] if len(args) > 1 else kwargs.get("dropout_p", 0.0)
+ is_causal = args[2] if len(args) > 2 else kwargs.get("is_causal", False)
+ params = torch.backends.cuda.SDPAParams(q, k, v, attn_mask, dropout_p, is_causal, True)
+ supports_native_gqa = (
+ torch.backends.cuda.can_use_flash_attention(params)
+ or torch.backends.cuda.can_use_cudnn_attention(params)
+ or torch.backends.cuda.can_use_efficient_attention(params)
+ )
+ if not supports_native_gqa:
+ k, v = repeat_kv_for_gqa(k, v, q.shape[-3], -3)
+ kwargs["enable_gqa"] = False
+ return torch.nn.functional.scaled_dot_product_attention(q, k, v, *args, **kwargs)
+ else:
+ logging.warning("Torch version too old to set sdpa backend priority.")
+except (ModuleNotFoundError, TypeError):
+ logging.warning("Could not set sdpa backend priority.")
+
+NVIDIA_MEMORY_CONV_BUG_WORKAROUND = False
+try:
+ if comfy.model_management.is_nvidia():
+ cudnn_version = torch.backends.cudnn.version()
+ if (cudnn_version >= 91002 and cudnn_version < 91500) and comfy.model_management.torch_version_numeric >= (2, 9) and comfy.model_management.torch_version_numeric <= (2, 10):
+ #TODO: change upper bound version once it's fixed'
+ NVIDIA_MEMORY_CONV_BUG_WORKAROUND = True
+ logging.info("working around nvidia conv3d memory bug.")
+except:
+ pass
+
+cast_to = comfy.model_management.cast_to #TODO: remove once no more references
+
+def cast_to_input(weight, input, non_blocking=False, copy=True):
+ return comfy.model_management.cast_to(weight, input.dtype, input.device, non_blocking=non_blocking, copy=copy)
+
+
+def materialize_meta_param(s, param_keys):
+ for param_key in param_keys:
+ param = getattr(s, param_key, None)
+ if param is not None and getattr(param, "is_meta", False):
+ setattr(s, param_key, torch.nn.Parameter(torch.zeros(param.shape, dtype=param.dtype), requires_grad=param.requires_grad))
+
+
+# FIXME: add n=1 cache hit fast path
+def cast_modules_with_vbar(comfy_modules, dtype, device, bias_dtype, non_blocking):
+ offload_stream = None
+ cast_buffer = None
+ cast_buffer_offset = 0
+
+ def ensure_offload_stream(module, required_size, check_largest):
+ nonlocal offload_stream
+ nonlocal cast_buffer
+
+ if offload_stream is None:
+ offload_stream = comfy.model_management.get_offload_stream(device)
+ if offload_stream is None or not check_largest or len(comfy_modules) != 1:
+ return
+
+ current_size = 0 if cast_buffer is None else cast_buffer.size()
+ if current_size < required_size and module is comfy.model_management.LARGEST_AIMDO_CASTED_WEIGHT[0]:
+ offload_stream = comfy.model_management.get_offload_stream(device)
+ cast_buffer = None
+ if required_size > comfy.model_management.LARGEST_AIMDO_CASTED_WEIGHT[1]:
+ comfy.model_management.LARGEST_AIMDO_CASTED_WEIGHT = (module, required_size)
+
+ def get_cast_buffer(buffer_size):
+ nonlocal offload_stream
+ nonlocal cast_buffer
+ nonlocal cast_buffer_offset
+
+ if buffer_size == 0:
+ return None
+
+ if offload_stream is None:
+ return torch.empty((buffer_size,), dtype=torch.uint8, device=device)
+
+ cast_buffer = comfy.model_management.get_aimdo_cast_buffer(offload_stream, device)
+ buffer = comfy_aimdo.torch.aimdo_to_tensor(cast_buffer.get(buffer_size, cast_buffer_offset), device)
+ cast_buffer_offset += buffer_size
+ return buffer
+
+ for s in comfy_modules:
+ signature = comfy_aimdo.model_vbar.vbar_fault(s._v)
+ resident = comfy_aimdo.model_vbar.vbar_signature_compare(signature, s._v_signature)
+ prefetch = {
+ "signature": signature,
+ "resident": resident,
+ }
+
+ if resident:
+ s._prefetch = prefetch
+ continue
+
+ materialize_meta_param(s, ["weight", "bias"])
+ xfer_dest = comfy_aimdo.torch.aimdo_to_tensor(s._v, device) if signature is not None else None
+ cast_geometry = comfy.memory_management.tensors_to_geometries([ s.weight, s.bias ])
+ cast_dest = None
+ needs_cast = False
+
+ xfer_source = [ s.weight, s.bias ]
+ subset = "weights"
+ pin = comfy.pinned_memory.get_pin(s, subset=subset)
+ if pin is None and not args.fast_disk:
+ loaded_pin = comfy.pinned_memory.get_pin(s, subset="weights-loaded")
+ if loaded_pin is not None or signature is not None:
+ subset = "weights-loaded"
+ pin = loaded_pin
+ if pin is not None:
+ xfer_source = [ pin ]
+
+ for data, geometry in zip([ s.weight, s.bias ], cast_geometry):
+ if data is None:
+ continue
+ if data.dtype != geometry.dtype:
+ needs_cast = True
+ cast_dest = xfer_dest
+ xfer_dest = None
+ break
+
+ dest_size = comfy.memory_management.vram_aligned_size(xfer_source)
+ ensure_offload_stream(s, dest_size if xfer_dest is None else 0, True)
+ if xfer_dest is None:
+ xfer_dest = get_cast_buffer(dest_size)
+
+ def cast_maybe_lowvram_patch(xfer_source, xfer_dest, stream, xfer_dest2=None):
+ if xfer_source is not None:
+ if getattr(xfer_source, "is_lowvram_patch", False):
+ if xfer_dest is not None:
+ xfer_source.prepare(xfer_dest, stream, copy=True, commit=False)
+ xfer_source = [ xfer_dest ]
+ xfer_dest = xfer_dest2
+ xfer_dest2 = None
+ elif xfer_dest2 is not None:
+ xfer_source.prepare(xfer_dest2, stream, copy=True, commit=False)
+ return
+ else:
+ return
+ comfy.model_management.cast_to_gathered(xfer_source, xfer_dest, non_blocking=non_blocking, stream=stream, r2=xfer_dest2)
+
+ def handle_pin(m, pin, source, dest, subset="weights", size=None):
+ if pin is not None:
+ cast_maybe_lowvram_patch([pin], dest, offload_stream)
+ return
+ if signature is None or not args.fast_disk or args.high_ram:
+ comfy.pinned_memory.pin_memory(m, subset=subset, size=size)
+ pin = comfy.pinned_memory.get_pin(m, subset=subset)
+ cast_maybe_lowvram_patch(source, pin, offload_stream, xfer_dest2=dest)
+
+ handle_pin(s, pin, xfer_source, xfer_dest, subset=subset, size=dest_size)
+
+ for param_key in ("weight", "bias"):
+ lowvram_source = getattr(s, param_key + "_lowvram_function", None)
+ if lowvram_source is not None:
+ ensure_offload_stream(s, cast_buffer_offset, False)
+ lowvram_size = lowvram_source.memory_required()
+ lowvram_dest = get_cast_buffer(lowvram_size)
+ lowvram_source.prepare(lowvram_dest, None, copy=False, commit=True)
+
+ subset = "patches"
+ pin = comfy.pinned_memory.get_pin(lowvram_source, subset=subset)
+ if pin is None:
+ loaded_pin = comfy.pinned_memory.get_pin(lowvram_source, subset="patches-loaded")
+ if loaded_pin is not None:
+ subset = "patches-loaded"
+ pin = loaded_pin
+ elif signature is not None and not args.fast_disk:
+ subset = "patches-loaded"
+ handle_pin(lowvram_source, pin, lowvram_source, lowvram_dest, subset=subset, size=lowvram_size)
+
+
+ prefetch["xfer_dest"] = xfer_dest
+ prefetch["cast_dest"] = cast_dest
+ prefetch["cast_geometry"] = cast_geometry
+ prefetch["needs_cast"] = needs_cast
+ s._prefetch = prefetch
+
+ return offload_stream
+
+
+def resolve_cast_module_with_vbar(s, dtype, device, bias_dtype, compute_dtype, want_requant):
+
+ prefetch = getattr(s, "_prefetch", None)
+
+ if prefetch["resident"]:
+ weight = s._v_weight
+ bias = s._v_bias
+ else:
+ xfer_dest = prefetch["xfer_dest"]
+ if prefetch["needs_cast"]:
+ cast_dest = prefetch["cast_dest"] if prefetch["cast_dest"] is not None else torch.empty((comfy.memory_management.vram_aligned_size(prefetch["cast_geometry"]),), dtype=torch.uint8, device=device)
+ for pre_cast, post_cast in zip(comfy.memory_management.interpret_gathered_like([s.weight, s.bias ], xfer_dest),
+ comfy.memory_management.interpret_gathered_like(prefetch["cast_geometry"], cast_dest)):
+ if post_cast is not None:
+ post_cast.copy_(pre_cast)
+ xfer_dest = cast_dest
+
+ params = comfy.memory_management.interpret_gathered_like(prefetch["cast_geometry"], xfer_dest)
+ weight = params[0]
+ bias = params[1]
+ if prefetch["signature"] is not None:
+ s._v_weight = weight
+ s._v_bias = bias
+ s._v_signature = prefetch["signature"]
+
+ def post_cast(s, param_key, x, dtype, resident, update_weight):
+ lowvram_fn = getattr(s, param_key + "_lowvram_function", None)
+ fns = getattr(s, param_key + "_function", [])
+
+ if x is None:
+ return None
+
+ orig = x
+
+ def to_dequant(tensor, dtype):
+ tensor = tensor.to(dtype=dtype)
+ if isinstance(tensor, QuantizedTensor):
+ tensor = tensor.dequantize()
+ return tensor
+
+ if orig.dtype != dtype or len(fns) > 0:
+ x = to_dequant(x, dtype)
+ if not resident and lowvram_fn is not None:
+ x = to_dequant(x, dtype if compute_dtype is None else compute_dtype)
+ x = lowvram_fn(x)
+ if (want_requant and len(fns) == 0 or update_weight):
+ seed = comfy.utils.string_to_seed(s.seed_key)
+ if isinstance(orig, QuantizedTensor):
+ y = orig.requantize_from_float(x, scale="recalculate", stochastic_rounding=seed)
+ else:
+ y = comfy.float.stochastic_rounding(x, orig.dtype, seed=seed)
+ if want_requant and len(fns) == 0:
+ x = y
+ if update_weight:
+ orig.copy_(y)
+ for f in fns:
+ x = f(x)
+ return x
+
+ update_weight = prefetch["signature"] is not None
+ weight = post_cast(s, "weight", weight, dtype, prefetch["resident"], update_weight)
+ if bias is not None:
+ bias = post_cast(s, "bias", bias, bias_dtype, prefetch["resident"], update_weight)
+
+ if prefetch["signature"] is not None:
+ prefetch["resident"] = True
+
+ return weight, bias
+
+
+def cast_bias_weight(s, input=None, dtype=None, device=None, bias_dtype=None, offloadable=False, compute_dtype=None, want_requant=False):
+ # NOTE: offloadable=False is a legacy mode and if you are a custom node author reading this please pass
+ # offloadable=True and call uncast_bias_weight() after your last usage of the weight/bias. This
+ # will add async-offload support to your cast and improve performance.
+ if input is not None:
+ if dtype is None:
+ if isinstance(input, QuantizedTensor):
+ dtype = input.params.orig_dtype
+ else:
+ dtype = input.dtype
+ if bias_dtype is None:
+ bias_dtype = dtype
+ if device is None:
+ device = input.device
+
+ def format_return(result, offloadable):
+ weight, bias, offload_stream = result
+ return (weight, bias, offload_stream) if offloadable else (weight, bias)
+
+ non_blocking = comfy.model_management.device_supports_non_blocking(device)
+
+ if hasattr(s, "_v") and comfy.model_management.is_device_cpu(device):
+
+ #vbar doesn't support CPU weights, but some custom nodes have weird paths
+ #that might switch the layer to the CPU and expect it to work. We have to take
+ #a clone conservatively as we are mmapped and some SFT files are packed misaligned
+ #If you are a custom node author reading this, please move your layer to the GPU
+ #or declare your ModelPatcher as CPU in the first place.
+ materialize_meta_param(s, ["weight", "bias"])
+ weight = s.weight.to(dtype=dtype, copy=True)
+ if isinstance(weight, QuantizedTensor):
+ weight = weight.dequantize()
+ bias = s.bias.to(dtype=bias_dtype, copy=True) if s.bias is not None else None
+ return format_return((weight, bias, (None, None, None)), offloadable)
+
+ elif hasattr(s, "_v") and s.weight.device != device:
+ prefetched = hasattr(s, "_prefetch")
+ offload_stream = None
+ offload_device = None
+ if not prefetched:
+ offload_stream = cast_modules_with_vbar([s], dtype, device, bias_dtype, non_blocking)
+ comfy.model_management.sync_stream(device, offload_stream)
+
+ weight, bias = resolve_cast_module_with_vbar(s, dtype, device, bias_dtype, compute_dtype, want_requant)
+
+ if not prefetched:
+ if getattr(s, "_prefetch")["signature"] is not None:
+ offload_device = device
+ for param_key in ("weight", "bias"):
+ lowvram_fn = getattr(s, param_key + "_lowvram_function", None)
+ if lowvram_fn is not None:
+ lowvram_fn.clear_prepared()
+ delattr(s, "_prefetch")
+ return format_return((weight, bias, (offload_stream, offload_device, None)), offloadable)
+
+
+ if offloadable and (device != s.weight.device or
+ (s.bias is not None and device != s.bias.device)):
+ offload_stream = comfy.model_management.get_offload_stream(device)
+ else:
+ offload_stream = None
+
+ bias = None
+ weight = None
+
+ if offload_stream is not None and not args.cuda_malloc:
+ cast_buffer_size = comfy.memory_management.vram_aligned_size([ s.weight, s.bias ])
+ cast_buffer = comfy.model_management.get_cast_buffer(offload_stream, device, cast_buffer_size, s)
+ #The streams can be uneven in buffer capability and reject us. Retry to get the other stream
+ if cast_buffer is None:
+ offload_stream = comfy.model_management.get_offload_stream(device)
+ cast_buffer = comfy.model_management.get_cast_buffer(offload_stream, device, cast_buffer_size, s)
+ params = comfy.memory_management.interpret_gathered_like([ s.weight, s.bias ], cast_buffer)
+ weight = params[0]
+ bias = params[1]
+
+ weight_has_function = len(s.weight_function) > 0
+ bias_has_function = len(s.bias_function) > 0
+
+ weight = comfy.model_management.cast_to(s.weight, None, device, non_blocking=non_blocking, copy=weight_has_function, stream=offload_stream, r=weight)
+
+ if s.bias is not None:
+ bias = comfy.model_management.cast_to(s.bias, None, device, non_blocking=non_blocking, copy=bias_has_function, stream=offload_stream, r=bias)
+
+ comfy.model_management.sync_stream(device, offload_stream)
+
+ bias_a = bias
+ weight_a = weight
+
+ if s.bias is not None:
+ bias = bias.to(dtype=bias_dtype)
+ for f in s.bias_function:
+ bias = f(bias)
+
+ if weight_has_function or weight.dtype != dtype:
+ weight = weight.to(dtype=dtype)
+ if isinstance(weight, QuantizedTensor):
+ weight = weight.dequantize()
+ for f in s.weight_function:
+ weight = f(weight)
+
+ return format_return((weight, bias, (offload_stream, weight_a, bias_a)), offloadable)
+
+
+def uncast_bias_weight(s, weight, bias, offload_stream):
+ if offload_stream is None:
+ return
+ os, weight_a, bias_a = offload_stream
+ device=None
+ #FIXME: This is really bad RTTI
+ if weight_a is not None and not isinstance(weight_a, torch.Tensor):
+ comfy_aimdo.model_vbar.vbar_unpin(s._v)
+ device = weight_a
+ if os is None:
+ return
+ if device is None:
+ if weight_a is not None:
+ device = weight_a.device
+ else:
+ if bias_a is None:
+ return
+ device = bias_a.device
+ os.wait_stream(comfy.model_management.current_stream(device))
+
+
+class CastWeightBiasOp:
+ comfy_cast_weights = False
+ weight_function = []
+ bias_function = []
+
+class disable_weight_init:
+ @staticmethod
+ def _zero_init_parameter(module, name):
+ param = getattr(module, name)
+ device = None if getattr(param, "is_meta", False) else param.device
+ setattr(module, name, torch.nn.Parameter(torch.zeros(param.shape, device=device, dtype=param.dtype), requires_grad=False))
+
+ @staticmethod
+ def _lazy_load_from_state_dict(module, state_dict, prefix, local_metadata,
+ missing_keys, unexpected_keys, weight_shape,
+ bias_shape=None):
+ assign_to_params_buffers = local_metadata.get("assign_to_params_buffers", False)
+ prefix_len = len(prefix)
+ for k, v in state_dict.items():
+ key = k[prefix_len:]
+ if key == "weight":
+ if not assign_to_params_buffers:
+ v = v.clone()
+ module.weight = torch.nn.Parameter(v, requires_grad=False)
+ elif bias_shape is not None and key == "bias" and v is not None:
+ if not assign_to_params_buffers:
+ v = v.clone()
+ module.bias = torch.nn.Parameter(v, requires_grad=False)
+ else:
+ unexpected_keys.append(k)
+
+ if module.weight is None:
+ module.weight = torch.nn.Parameter(torch.zeros(weight_shape), requires_grad=False)
+ missing_keys.append(prefix + "weight")
+
+ if bias_shape is not None and module.bias is None and getattr(module, "comfy_need_lazy_init_bias", False):
+ module.bias = torch.nn.Parameter(torch.zeros(bias_shape), requires_grad=False)
+ missing_keys.append(prefix + "bias")
+
+ class Linear(torch.nn.Linear, CastWeightBiasOp):
+
+ def __init__(self, in_features, out_features, bias=True, device=None, dtype=None):
+ # don't trust subclasses that BYO state dict loader to call us.
+ if (not comfy.memory_management.aimdo_enabled
+ or type(self)._load_from_state_dict is not disable_weight_init.Linear._load_from_state_dict):
+ super().__init__(in_features, out_features, bias, device, dtype)
+ return
+
+ # Issue is with `torch.empty` still reserving the full memory for the layer.
+ # Windows doesn't over-commit memory so without this, We are momentarily commit
+ # charged for the weight even though we might zero-copy it when we load the
+ # state dict. If the commit charge exceeds the ceiling we can destabilize the
+ # system.
+ torch.nn.Module.__init__(self)
+ self.in_features = in_features
+ self.out_features = out_features
+ self.weight = None
+ self.bias = None
+ self.comfy_need_lazy_init_bias=bias
+ self.weight_comfy_model_dtype = dtype
+ self.bias_comfy_model_dtype = dtype
+
+ def _load_from_state_dict(self, state_dict, prefix, local_metadata,
+ strict, missing_keys, unexpected_keys, error_msgs):
+
+ if (not comfy.memory_management.aimdo_enabled
+ or type(self)._load_from_state_dict is not disable_weight_init.Linear._load_from_state_dict):
+ return super()._load_from_state_dict(state_dict, prefix, local_metadata, strict,
+ missing_keys, unexpected_keys, error_msgs)
+ disable_weight_init._lazy_load_from_state_dict(
+ self,
+ state_dict,
+ prefix,
+ local_metadata,
+ missing_keys,
+ unexpected_keys,
+ weight_shape=(self.in_features, self.out_features),
+ bias_shape=(self.out_features,),
+ )
+
+
+ def reset_parameters(self):
+ return None
+
+ def forward_comfy_cast_weights(self, input):
+ weight, bias, offload_stream = cast_bias_weight(self, input, offloadable=True)
+ x = torch.nn.functional.linear(input, weight, bias)
+ uncast_bias_weight(self, weight, bias, offload_stream)
+ return x
+
+ def forward(self, *args, **kwargs):
+ run_every_op()
+ if self.comfy_cast_weights or len(self.weight_function) > 0 or len(self.bias_function) > 0:
+ return self.forward_comfy_cast_weights(*args, **kwargs)
+ else:
+ return super().forward(*args, **kwargs)
+
+ class Conv1d(torch.nn.Conv1d, CastWeightBiasOp):
+ def reset_parameters(self):
+ return None
+
+ def forward_comfy_cast_weights(self, input):
+ weight, bias, offload_stream = cast_bias_weight(self, input, offloadable=True)
+ x = self._conv_forward(input, weight, bias)
+ uncast_bias_weight(self, weight, bias, offload_stream)
+ return x
+
+ def forward(self, *args, **kwargs):
+ run_every_op()
+ if self.comfy_cast_weights or len(self.weight_function) > 0 or len(self.bias_function) > 0:
+ return self.forward_comfy_cast_weights(*args, **kwargs)
+ else:
+ return super().forward(*args, **kwargs)
+
+ class Conv2d(torch.nn.Conv2d, CastWeightBiasOp):
+ def reset_parameters(self):
+ return None
+
+ def forward_comfy_cast_weights(self, input):
+ weight, bias, offload_stream = cast_bias_weight(self, input, offloadable=True)
+ x = self._conv_forward(input, weight, bias)
+ uncast_bias_weight(self, weight, bias, offload_stream)
+ return x
+
+ def forward(self, *args, **kwargs):
+ run_every_op()
+ if self.comfy_cast_weights or len(self.weight_function) > 0 or len(self.bias_function) > 0:
+ return self.forward_comfy_cast_weights(*args, **kwargs)
+ else:
+ return super().forward(*args, **kwargs)
+
+ class Conv3d(torch.nn.Conv3d, CastWeightBiasOp):
+ def reset_parameters(self):
+ return None
+
+ def _conv_forward(self, input, weight, bias, autopad=None, *args, **kwargs):
+ if autopad == "causal_zero":
+ weight = weight[:, :, -input.shape[2]:, :, :]
+ if NVIDIA_MEMORY_CONV_BUG_WORKAROUND and weight.dtype in (torch.float16, torch.bfloat16):
+ out = torch.cudnn_convolution(input, weight, self.padding, self.stride, self.dilation, self.groups, benchmark=False, deterministic=False, allow_tf32=True)
+ if bias is not None:
+ out += bias.reshape((1, -1) + (1,) * (out.ndim - 2))
+ return out
+ else:
+ return super()._conv_forward(input, weight, bias, *args, **kwargs)
+
+ def forward_comfy_cast_weights(self, input, autopad=None):
+ weight, bias, offload_stream = cast_bias_weight(self, input, offloadable=True)
+ x = self._conv_forward(input, weight, bias, autopad=autopad)
+ uncast_bias_weight(self, weight, bias, offload_stream)
+ return x
+
+ def forward(self, *args, **kwargs):
+ run_every_op()
+ if self.comfy_cast_weights or len(self.weight_function) > 0 or len(self.bias_function) > 0 or "autopad" in kwargs:
+ return self.forward_comfy_cast_weights(*args, **kwargs)
+ else:
+ return super().forward(*args, **kwargs)
+
+ class GroupNorm(torch.nn.GroupNorm, CastWeightBiasOp):
+ def reset_parameters(self):
+ return None
+
+ def forward_comfy_cast_weights(self, input):
+ weight, bias, offload_stream = cast_bias_weight(self, input, offloadable=True)
+ x = torch.nn.functional.group_norm(input, self.num_groups, weight, bias, self.eps)
+ uncast_bias_weight(self, weight, bias, offload_stream)
+ return x
+
+ def forward(self, *args, **kwargs):
+ run_every_op()
+ if self.comfy_cast_weights or len(self.weight_function) > 0 or len(self.bias_function) > 0:
+ return self.forward_comfy_cast_weights(*args, **kwargs)
+ else:
+ return super().forward(*args, **kwargs)
+
+ class BatchNorm2d(torch.nn.BatchNorm2d, CastWeightBiasOp):
+ def reset_parameters(self):
+ return None
+
+ def forward_comfy_cast_weights(self, input):
+ weight, bias, offload_stream = cast_bias_weight(self, input, offloadable=True)
+ running_mean = self.running_mean.to(device=input.device, dtype=weight.dtype) if self.running_mean is not None else None
+ running_var = self.running_var.to(device=input.device, dtype=weight.dtype) if self.running_var is not None else None
+ x = torch.nn.functional.batch_norm(input, running_mean, running_var, weight, bias, self.training, self.momentum, self.eps)
+ uncast_bias_weight(self, weight, bias, offload_stream)
+ return x
+
+ def forward(self, *args, **kwargs):
+ run_every_op()
+ if self.comfy_cast_weights or len(self.weight_function) > 0 or len(self.bias_function) > 0:
+ return self.forward_comfy_cast_weights(*args, **kwargs)
+ else:
+ return super().forward(*args, **kwargs)
+
+ class LayerNorm(torch.nn.LayerNorm, CastWeightBiasOp):
+ def reset_parameters(self):
+ return None
+
+ def forward_comfy_cast_weights(self, input):
+ if self.weight is not None:
+ weight, bias, offload_stream = cast_bias_weight(self, input, offloadable=True)
+ else:
+ weight = None
+ bias = None
+ offload_stream = None
+ x = torch.nn.functional.layer_norm(input, self.normalized_shape, weight, bias, self.eps)
+ uncast_bias_weight(self, weight, bias, offload_stream)
+ return x
+
+ def forward(self, *args, **kwargs):
+ run_every_op()
+ if self.comfy_cast_weights or len(self.weight_function) > 0 or len(self.bias_function) > 0:
+ return self.forward_comfy_cast_weights(*args, **kwargs)
+ else:
+ return super().forward(*args, **kwargs)
+
+ class RMSNorm(torch.nn.RMSNorm, CastWeightBiasOp):
+ def reset_parameters(self):
+ self.bias = None
+ return None
+
+ def forward_comfy_cast_weights(self, input):
+ if self.weight is not None:
+ weight, bias, offload_stream = cast_bias_weight(self, input, offloadable=True)
+ else:
+ weight = None
+ bias = None
+ offload_stream = None
+ x = torch.nn.functional.rms_norm(input, self.normalized_shape, weight, self.eps)
+ uncast_bias_weight(self, weight, bias, offload_stream)
+ return x
+
+ def forward(self, *args, **kwargs):
+ run_every_op()
+ if self.comfy_cast_weights or len(self.weight_function) > 0 or len(self.bias_function) > 0:
+ return self.forward_comfy_cast_weights(*args, **kwargs)
+ else:
+ return super().forward(*args, **kwargs)
+
+ class ConvTranspose2d(torch.nn.ConvTranspose2d, CastWeightBiasOp):
+ def reset_parameters(self):
+ return None
+
+ def forward_comfy_cast_weights(self, input, output_size=None):
+ num_spatial_dims = 2
+ output_padding = self._output_padding(
+ input, output_size, self.stride, self.padding, self.kernel_size,
+ num_spatial_dims, self.dilation)
+
+ weight, bias, offload_stream = cast_bias_weight(self, input, offloadable=True)
+ x = torch.nn.functional.conv_transpose2d(
+ input, weight, bias, self.stride, self.padding,
+ output_padding, self.groups, self.dilation)
+ uncast_bias_weight(self, weight, bias, offload_stream)
+ return x
+
+ def forward(self, *args, **kwargs):
+ run_every_op()
+ if self.comfy_cast_weights or len(self.weight_function) > 0 or len(self.bias_function) > 0:
+ return self.forward_comfy_cast_weights(*args, **kwargs)
+ else:
+ return super().forward(*args, **kwargs)
+
+ class ConvTranspose1d(torch.nn.ConvTranspose1d, CastWeightBiasOp):
+ def reset_parameters(self):
+ return None
+
+ def forward_comfy_cast_weights(self, input, output_size=None):
+ num_spatial_dims = 1
+ output_padding = self._output_padding(
+ input, output_size, self.stride, self.padding, self.kernel_size,
+ num_spatial_dims, self.dilation)
+
+ weight, bias, offload_stream = cast_bias_weight(self, input, offloadable=True)
+ x = torch.nn.functional.conv_transpose1d(
+ input, weight, bias, self.stride, self.padding,
+ output_padding, self.groups, self.dilation)
+ uncast_bias_weight(self, weight, bias, offload_stream)
+ return x
+
+ def forward(self, *args, **kwargs):
+ run_every_op()
+ if self.comfy_cast_weights or len(self.weight_function) > 0 or len(self.bias_function) > 0:
+ return self.forward_comfy_cast_weights(*args, **kwargs)
+ else:
+ return super().forward(*args, **kwargs)
+
+ class Embedding(torch.nn.Embedding, CastWeightBiasOp):
+ def __init__(self, num_embeddings, embedding_dim, padding_idx=None, max_norm=None,
+ norm_type=2.0, scale_grad_by_freq=False, sparse=False, _weight=None,
+ _freeze=False, device=None, dtype=None):
+ # don't trust subclasses that BYO state dict loader to call us.
+ if (not comfy.memory_management.aimdo_enabled
+ or type(self)._load_from_state_dict is not disable_weight_init.Embedding._load_from_state_dict):
+ super().__init__(num_embeddings, embedding_dim, padding_idx, max_norm,
+ norm_type, scale_grad_by_freq, sparse, _weight,
+ _freeze, device, dtype)
+ return
+
+ torch.nn.Module.__init__(self)
+ self.num_embeddings = num_embeddings
+ self.embedding_dim = embedding_dim
+ self.padding_idx = padding_idx
+ self.max_norm = max_norm
+ self.norm_type = norm_type
+ self.scale_grad_by_freq = scale_grad_by_freq
+ self.sparse = sparse
+ # Keep shape/dtype visible for module introspection without reserving storage.
+ embedding_dtype = dtype if dtype is not None else torch.get_default_dtype()
+ self.weight = torch.nn.Parameter(
+ torch.empty((num_embeddings, embedding_dim), device="meta", dtype=embedding_dtype),
+ requires_grad=False,
+ )
+ self.bias = None
+ self.weight_comfy_model_dtype = dtype
+
+ def _load_from_state_dict(self, state_dict, prefix, local_metadata,
+ strict, missing_keys, unexpected_keys, error_msgs):
+
+ if (not comfy.memory_management.aimdo_enabled
+ or type(self)._load_from_state_dict is not disable_weight_init.Embedding._load_from_state_dict):
+ return super()._load_from_state_dict(state_dict, prefix, local_metadata, strict,
+ missing_keys, unexpected_keys, error_msgs)
+ disable_weight_init._lazy_load_from_state_dict(
+ self,
+ state_dict,
+ prefix,
+ local_metadata,
+ missing_keys,
+ unexpected_keys,
+ weight_shape=(self.num_embeddings, self.embedding_dim),
+ )
+
+ def reset_parameters(self):
+ self.bias = None
+ return None
+
+ def forward_comfy_cast_weights(self, input, out_dtype=None):
+ output_dtype = out_dtype
+ if self.weight.dtype == torch.float16 or self.weight.dtype == torch.bfloat16:
+ out_dtype = None
+ weight, bias, offload_stream = cast_bias_weight(self, device=input.device, dtype=out_dtype, offloadable=True)
+ x = torch.nn.functional.embedding(input, weight, self.padding_idx, self.max_norm, self.norm_type, self.scale_grad_by_freq, self.sparse).to(dtype=output_dtype)
+ uncast_bias_weight(self, weight, bias, offload_stream)
+ return x
+
+
+ def forward(self, *args, **kwargs):
+ run_every_op()
+ if self.comfy_cast_weights or len(self.weight_function) > 0 or len(self.bias_function) > 0:
+ return self.forward_comfy_cast_weights(*args, **kwargs)
+ else:
+ if "out_dtype" in kwargs:
+ kwargs.pop("out_dtype")
+ return super().forward(*args, **kwargs)
+
+ @classmethod
+ def conv_nd(s, dims, *args, **kwargs):
+ if dims == 2:
+ return s.Conv2d(*args, **kwargs)
+ elif dims == 3:
+ return s.Conv3d(*args, **kwargs)
+ else:
+ raise ValueError(f"unsupported dimensions: {dims}")
+
+
+class manual_cast(disable_weight_init):
+ class Linear(disable_weight_init.Linear):
+ comfy_cast_weights = True
+
+ class Conv1d(disable_weight_init.Conv1d):
+ comfy_cast_weights = True
+
+ class Conv2d(disable_weight_init.Conv2d):
+ comfy_cast_weights = True
+
+ class Conv3d(disable_weight_init.Conv3d):
+ comfy_cast_weights = True
+
+ class BatchNorm2d(disable_weight_init.BatchNorm2d):
+ comfy_cast_weights = True
+
+ class GroupNorm(disable_weight_init.GroupNorm):
+ comfy_cast_weights = True
+
+ class LayerNorm(disable_weight_init.LayerNorm):
+ comfy_cast_weights = True
+
+ class ConvTranspose2d(disable_weight_init.ConvTranspose2d):
+ comfy_cast_weights = True
+
+ class ConvTranspose1d(disable_weight_init.ConvTranspose1d):
+ comfy_cast_weights = True
+
+ class RMSNorm(disable_weight_init.RMSNorm):
+ comfy_cast_weights = True
+
+ class Embedding(disable_weight_init.Embedding):
+ comfy_cast_weights = True
+
+
+def fp8_linear(self, input):
+ """
+ Legacy FP8 linear function for backward compatibility.
+ Uses QuantizedTensor subclass for dispatch.
+ """
+ dtype = self.weight.dtype
+ if dtype not in [torch.float8_e4m3fn]:
+ return None
+
+ input_dtype = input.dtype
+ input_shape = input.shape
+ tensor_3d = input.ndim == 3
+
+ if tensor_3d:
+ input = input.reshape(-1, input_shape[2])
+
+ if input.ndim != 2:
+ return None
+ lora_compute_dtype=comfy.model_management.lora_compute_dtype(input.device)
+ w, bias, offload_stream = cast_bias_weight(self, input, dtype=dtype, bias_dtype=input_dtype, offloadable=True, compute_dtype=lora_compute_dtype, want_requant=True)
+ scale_weight = torch.ones((), device=input.device, dtype=torch.float32)
+
+ scale_input = torch.ones((), device=input.device, dtype=torch.float32)
+ input = torch.clamp(input, min=-448, max=448, out=input)
+ input_fp8 = input.to(dtype).contiguous()
+ layout_params_input = TensorCoreFP8Layout.Params(scale=scale_input, orig_dtype=input_dtype, orig_shape=tuple(input_fp8.shape))
+ quantized_input = QuantizedTensor(input_fp8, "TensorCoreFP8Layout", layout_params_input)
+
+ # Wrap weight in QuantizedTensor - this enables unified dispatch
+ # Call F.linear - __torch_dispatch__ routes to fp8_linear handler in quant_ops.py!
+ layout_params_weight = TensorCoreFP8Layout.Params(scale=scale_weight, orig_dtype=input_dtype, orig_shape=tuple(w.shape))
+ quantized_weight = QuantizedTensor(w, "TensorCoreFP8Layout", layout_params_weight)
+ o = torch.nn.functional.linear(quantized_input, quantized_weight, bias)
+
+ uncast_bias_weight(self, w, bias, offload_stream)
+ if tensor_3d:
+ o = o.reshape((input_shape[0], input_shape[1], w.shape[0]))
+
+ return o
+
+class fp8_ops(manual_cast):
+ class Linear(manual_cast.Linear):
+ def reset_parameters(self):
+ self.scale_weight = None
+ self.scale_input = None
+ return None
+
+ def forward_comfy_cast_weights(self, input):
+ if len(self.weight_function) == 0 and len(self.bias_function) == 0:
+ try:
+ out = fp8_linear(self, input)
+ if out is not None:
+ return out
+ except Exception as e:
+ logging.info("Exception during fp8 op: {}".format(e))
+
+ weight, bias, offload_stream = cast_bias_weight(self, input, offloadable=True)
+ x = torch.nn.functional.linear(input, weight, bias)
+ uncast_bias_weight(self, weight, bias, offload_stream)
+ return x
+
+CUBLAS_IS_AVAILABLE = False
+try:
+ from cublas_ops import CublasLinear, cublas_half_matmul
+ CUBLAS_IS_AVAILABLE = True
+except ImportError:
+ pass
+
+if CUBLAS_IS_AVAILABLE:
+ class cublas_ops(manual_cast):
+ class Linear(CublasLinear, manual_cast.Linear):
+ def reset_parameters(self):
+ return None
+
+ def forward_comfy_cast_weights(self, input):
+ weight, bias, offload_stream = cast_bias_weight(self, input, offloadable=True)
+ x = cublas_half_matmul(input, weight, bias, self._epilogue_str, self.has_bias)
+ uncast_bias_weight(self, weight, bias, offload_stream)
+ return x
+
+ def forward(self, *args, **kwargs):
+ run_every_op()
+ if self.comfy_cast_weights or len(self.weight_function) > 0 or len(self.bias_function) > 0:
+ return self.forward_comfy_cast_weights(*args, **kwargs)
+ else:
+ return super().forward(*args, **kwargs)
+
+# ==============================================================================
+# Mixed Precision Operations
+# ==============================================================================
+from . import quant_ops
+from .quant_ops import (
+ QuantizedTensor,
+ QUANT_ALGOS,
+ TensorCoreFP8Layout,
+ TensorWiseINT8Layout,
+ get_layout_class,
+)
+
+def _swiglu_eager(x):
+ gate, up = x.chunk(2, dim=-1)
+ return torch.nn.functional.silu(gate).mul_(up)
+
+
+INPUT_ACT_EAGER = {
+ "gelu_tanh": lambda x: torch.nn.functional.gelu(x, approximate="tanh"),
+ "swiglu": _swiglu_eager,
+}
+
+
+def linear_input_act(linear, x, input_act):
+ """``linear(act(x))``, with ``act`` folded into an INT8 activation quantizer.
+
+ An INT8 linear quantizes its input anyway, so an elementwise activation can
+ ride along inside that kernel instead of writing a full-size intermediate to
+ HBM and reading it straight back. Worth it for an MLP's down-projection,
+ where the intermediate is several times the hidden size.
+
+ """
+ weight = linear.weight
+ if (comfy.model_management.in_training
+ or not isinstance(weight, QuantizedTensor)
+ or weight._layout_cls != "TensorWiseINT8Layout"
+ or getattr(weight._params, "transposed", False)):
+ return linear(INPUT_ACT_EAGER[input_act](x))
+
+ # want_requant keeps a vbar-streamed layer on the INT8 path when a LoRA is
+ # patched in on the fly; without it the cast hands back a dequantized weight.
+ weight, bias, offload_stream = cast_bias_weight(
+ linear, x, offloadable=True, compute_dtype=x.dtype, want_requant=True)
+ try:
+ if not isinstance(weight, QuantizedTensor):
+ # A LoRA weight_function, or activations whose dtype differs from the
+ # weight's, make the cast hand back a dequantized tensor.
+ return torch.nn.functional.linear(INPUT_ACT_EAGER[input_act](x), weight, bias)
+ qdata, scale = TensorWiseINT8Layout.get_plain_tensors(weight)
+ return quant_ops.ck.int8_linear(
+ x, qdata, scale, bias, x.dtype,
+ convrot=getattr(weight._params, "convrot", False),
+ convrot_groupsize=getattr(weight._params, "convrot_groupsize", 256),
+ input_act=input_act,
+ )
+ finally:
+ uncast_bias_weight(linear, weight, bias, offload_stream)
+
+
+class QuantLinearFunc(torch.autograd.Function):
+ """Custom autograd function for quantized linear: quantized forward, optionally FP8 backward.
+
+ When training_fp8_bwd is enabled:
+ - Forward: quantize input per layout (FP8/NVFP4), use quantized matmul
+ - Backward: all matmuls use FP8 tensor cores via torch.mm dispatch
+ - Cached input is FP8 (half the memory of bf16)
+
+ When training_fp8_bwd is disabled:
+ - Forward: quantize input per layout, use quantized matmul
+ - Backward: dequantize weight to compute_dtype, use standard matmul
+ """
+
+ @staticmethod
+ def forward(ctx, input_float, weight, bias, layout_type, input_scale, compute_dtype):
+ input_shape = input_float.shape
+ inp = input_float.detach().flatten(0, -2) # zero-cost view to 2D
+
+ # Quantize input for forward (same layout as weight)
+ if layout_type is not None:
+ q_input = QuantizedTensor.from_float(inp, layout_type, scale=input_scale)
+ else:
+ q_input = inp
+
+ w = weight.detach() if weight.requires_grad else weight
+ b = bias.detach() if bias is not None and bias.requires_grad else bias
+
+ output = torch.nn.functional.linear(q_input, w, b)
+
+ # Unflatten output to match original input shape
+ if len(input_shape) > 2:
+ output = output.unflatten(0, input_shape[:-1])
+
+ # Save for backward
+ ctx.input_shape = input_shape
+ ctx.has_bias = bias is not None
+ ctx.compute_dtype = compute_dtype
+ ctx.weight_requires_grad = weight.requires_grad
+ ctx.fp8_bwd = comfy.model_management.training_fp8_bwd
+
+ if ctx.fp8_bwd:
+ # Cache FP8 quantized input — half the memory of bf16
+ if isinstance(q_input, QuantizedTensor) and layout_type.startswith('TensorCoreFP8'):
+ ctx.q_input = q_input # already FP8, reuse
+ else:
+ # NVFP4 or other layout — quantize input to FP8 for backward
+ ctx.q_input = QuantizedTensor.from_float(inp, "TensorCoreFP8E4M3Layout")
+ ctx.save_for_backward(weight)
+ else:
+ ctx.q_input = None
+ ctx.save_for_backward(input_float, weight)
+
+ return output
+
+ @staticmethod
+ @torch.autograd.function.once_differentiable
+ def backward(ctx, grad_output):
+ compute_dtype = ctx.compute_dtype
+ grad_2d = grad_output.flatten(0, -2).to(compute_dtype)
+
+ # Value casting — only difference between fp8 and non-fp8 paths
+ if ctx.fp8_bwd:
+ weight, = ctx.saved_tensors
+ # Wrap as FP8 QuantizedTensors → torch.mm dispatches to _scaled_mm
+ grad_mm = QuantizedTensor.from_float(grad_2d, "TensorCoreFP8E5M2Layout")
+ if isinstance(weight, QuantizedTensor) and weight._layout_cls.startswith("TensorCoreFP8"):
+ weight_mm = weight
+ elif isinstance(weight, QuantizedTensor):
+ weight_mm = QuantizedTensor.from_float(weight.dequantize().to(compute_dtype), "TensorCoreFP8E4M3Layout")
+ else:
+ weight_mm = QuantizedTensor.from_float(weight.to(compute_dtype), "TensorCoreFP8E4M3Layout")
+ input_mm = ctx.q_input
+ else:
+ input_float, weight = ctx.saved_tensors
+ # Standard tensors → torch.mm does regular matmul
+ grad_mm = grad_2d
+ if isinstance(weight, QuantizedTensor):
+ weight_mm = weight.dequantize().to(compute_dtype)
+ else:
+ weight_mm = weight.to(compute_dtype)
+ input_mm = input_float.flatten(0, -2).to(compute_dtype) if ctx.weight_requires_grad else None
+
+ # Computation — same for both paths, dispatch handles the rest
+ grad_input = torch.mm(grad_mm, weight_mm)
+ if len(ctx.input_shape) > 2:
+ grad_input = grad_input.unflatten(0, ctx.input_shape[:-1])
+
+ grad_weight = None
+ if ctx.weight_requires_grad:
+ grad_weight = torch.mm(grad_mm.t(), input_mm)
+
+ grad_bias = None
+ if ctx.has_bias:
+ grad_bias = grad_2d.sum(dim=0)
+
+ return grad_input, grad_weight, grad_bias, None, None, None
+
+# Quantized-weight module helpers
+
+def _quantized_apply(module, fn, recurse=True):
+ """Re-wrap Parameters after fn so .to()/.cuda() propagate through QuantizedTensor weights."""
+ if recurse:
+ for child in module.children():
+ child._apply(fn)
+ for key, param in module._parameters.items():
+ if param is None:
+ continue
+ p = fn(param)
+ if (not torch.is_inference_mode_enabled()) and p.is_inference():
+ p = p.clone()
+ module.register_parameter(key, torch.nn.Parameter(p, requires_grad=False))
+ for key, buf in module._buffers.items():
+ if buf is not None:
+ module._buffers[key] = fn(buf)
+ return module
+
+
+def _load_quantized_module(module, super_load, state_dict, prefix, local_metadata, strict,
+ missing_keys, unexpected_keys, error_msgs, load_extra_params=False):
+ """Shared _load_from_state_dict body for quantized-weight modules.
+
+ Pops weight (+ scales, +/- extras), populates module.weight as a Parameter
+ or Parameter-wrapped QuantizedTensor, then calls super_load and strips
+ consumed keys from missing_keys. Reads compute_dtype from factory_kwargs
+ and disabled formats from module._disabled_formats.
+ """
+ device = module.factory_kwargs["device"]
+ compute_dtype = module.factory_kwargs["dtype"]
+ disabled_formats = module._disabled_formats
+ layer_name = prefix.rstrip('.')
+
+ weight = state_dict.pop(f"{prefix}weight", None)
+ if weight is None:
+ logging.warning(f"Missing weight for layer {layer_name}")
+ module.weight = None
+ return
+ manually_loaded_keys = [f"{prefix}weight"]
+
+ def pop_scale(name, dtype=None):
+ key = f"{prefix}{name}"
+ v = state_dict.pop(key, None)
+ if v is not None:
+ v = v.to(device=device)
+ if dtype is not None:
+ v = v.view(dtype=dtype)
+ manually_loaded_keys.append(key)
+ return v
+
+ layer_conf = state_dict.pop(f"{prefix}comfy_quant", None)
+ if layer_conf is not None:
+ layer_conf = json.loads(layer_conf.numpy().tobytes())
+
+ if layer_conf is None:
+ module.weight = torch.nn.Parameter(weight.to(device=device, dtype=compute_dtype), requires_grad=False)
+ else:
+ module.quant_format = layer_conf.get("format", None)
+ module._full_precision_mm_config = layer_conf.get("full_precision_matrix_mult", False)
+ if not module._full_precision_mm:
+ module._full_precision_mm = module._full_precision_mm_config
+ if module.quant_format in disabled_formats:
+ module._full_precision_mm = True
+ if module.quant_format is None:
+ raise ValueError(f"Unknown quantization format for layer {layer_name}")
+
+ qconfig = QUANT_ALGOS[module.quant_format]
+ module.layout_type = qconfig["comfy_tensor_layout"]
+ layout_cls = get_layout_class(module.layout_type)
+
+ # Per-format scales; fp8 dtype views handle both legacy uint8-on-disk and native fp8.
+ if module.quant_format in ("float8_e4m3fn", "float8_e5m2"):
+ scales = {"scale": pop_scale("weight_scale")}
+ elif module.quant_format == "mxfp8":
+ bs = pop_scale("weight_scale", torch.float8_e8m0fnu)
+ if bs is None:
+ raise ValueError(f"Missing MXFP8 block scales for layer {layer_name}")
+ scales = {"scale": bs}
+ elif module.quant_format == "nvfp4":
+ ts = pop_scale("weight_scale_2")
+ bs = pop_scale("weight_scale", torch.float8_e4m3fn)
+ if ts is None or bs is None:
+ raise ValueError(f"Missing NVFP4 scales for layer {layer_name}")
+ scales = {"scale": ts, "block_scale": bs}
+ elif module.quant_format == "int8_tensorwise":
+ scale = pop_scale("weight_scale")
+ if scale is None:
+ raise ValueError(f"Missing INT8 weight scale for layer {layer_name}")
+ scales = {"scale": scale}
+ params_conf = layer_conf.get("params", {})
+ if not isinstance(params_conf, dict):
+ params_conf = {}
+ if layer_conf.get("convrot", params_conf.get("convrot", False)):
+ scales["convrot"] = True
+ scales["convrot_groupsize"] = int(
+ layer_conf.get("convrot_groupsize", params_conf.get("convrot_groupsize", 256))
+ )
+ elif module.quant_format == "convrot_w4a4":
+ scale = pop_scale("weight_scale")
+ if scale is None:
+ raise ValueError(f"Missing ConvRot W4A4 weight scale for layer {layer_name}")
+ params_conf = layer_conf.get("params", {})
+ if not isinstance(params_conf, dict):
+ params_conf = {}
+ scales = {
+ "scale": scale,
+ "convrot_groupsize": int(
+ layer_conf.get("convrot_groupsize", params_conf.get("convrot_groupsize", 256))
+ ),
+ "quant_group_size": 64,
+ "linear_dtype": layer_conf.get("linear_dtype", params_conf.get("linear_dtype", "int4")),
+ }
+ else:
+ raise ValueError(f"Unsupported quantization format: {module.quant_format}")
+
+ params = layout_cls.Params(**scales, orig_dtype=compute_dtype, orig_shape=module._orig_shape)
+ module.weight = torch.nn.Parameter(
+ QuantizedTensor(weight.to(device=device, dtype=qconfig["storage_t"]), module.layout_type, params),
+ requires_grad=False,
+ )
+
+ if load_extra_params:
+ for param_name in qconfig["parameters"]:
+ if param_name in {"weight_scale", "weight_scale_2"}:
+ continue
+ param_key = f"{prefix}{param_name}"
+ _v = state_dict.pop(param_key, None)
+ if _v is None:
+ continue
+ module.register_parameter(param_name, torch.nn.Parameter(_v.to(device=device), requires_grad=False))
+ manually_loaded_keys.append(param_key)
+
+ super_load(state_dict, prefix, local_metadata, strict, missing_keys, unexpected_keys, error_msgs)
+ for key in manually_loaded_keys:
+ if key in missing_keys:
+ missing_keys.remove(key)
+
+
+def _quantized_weight_state_dict(module, sd, prefix, extra_quant_conf=None, extra_quant_params=()):
+ """Shared state_dict body. extra_quant_conf merges into the comfy_quant JSON;
+ extra_quant_params names attributes written as additional top-level keys."""
+ if not hasattr(module, 'weight'):
+ logging.warning(f"Warning: state dict on uninitialized op {prefix}")
+ return sd
+ bias = getattr(module, 'bias', None)
+ if bias is not None:
+ sd[f"{prefix}bias"] = bias
+ if module.weight is None:
+ return sd
+ if isinstance(module.weight, QuantizedTensor):
+ sd.update(module.weight.state_dict(f"{prefix}weight"))
+ quant_conf = {"format": module.quant_format}
+ if getattr(module, '_full_precision_mm_config', False):
+ quant_conf["full_precision_matrix_mult"] = True
+ params = getattr(module.weight, "_params", None)
+ if module.quant_format == "int8_tensorwise" and getattr(params, "convrot", False):
+ quant_conf["convrot"] = True
+ quant_conf["convrot_groupsize"] = getattr(params, "convrot_groupsize", 256)
+ elif module.quant_format == "convrot_w4a4":
+ quant_conf["convrot_groupsize"] = getattr(params, "convrot_groupsize", 256)
+ linear_dtype = getattr(params, "linear_dtype", "int4")
+ if linear_dtype != "int4":
+ quant_conf["linear_dtype"] = linear_dtype
+ if extra_quant_conf:
+ quant_conf.update(extra_quant_conf)
+ sd[f"{prefix}comfy_quant"] = torch.tensor(list(json.dumps(quant_conf).encode("utf-8")), dtype=torch.uint8)
+ for name in extra_quant_params:
+ value = getattr(module, name, None)
+ if value is not None:
+ sd[f"{prefix}{name}"] = value
+ else:
+ sd[f"{prefix}weight"] = module.weight
+ return sd
+
+
+def mixed_precision_ops(quant_config={}, compute_dtype=torch.bfloat16, full_precision_mm=False, disabled=[]):
+ class MixedPrecisionOps(manual_cast):
+ _quant_config = quant_config
+ _compute_dtype = compute_dtype
+ _full_precision_mm = full_precision_mm
+ _disabled = disabled
+
+ class Linear(torch.nn.Module, CastWeightBiasOp):
+ _disabled_formats = disabled
+
+ def __init__(self, in_features: int, out_features: int, bias: bool = True, device=None, dtype=None):
+ super().__init__()
+
+ self.factory_kwargs = {"device": device, "dtype": MixedPrecisionOps._compute_dtype}
+
+ self.in_features = in_features
+ self.out_features = out_features
+ self._orig_shape = (out_features, in_features)
+ if bias:
+ self.bias = torch.nn.Parameter(torch.empty(out_features, **self.factory_kwargs))
+ else:
+ self.register_parameter("bias", None)
+
+ self.tensor_class = None
+ self._full_precision_mm = MixedPrecisionOps._full_precision_mm
+ self._full_precision_mm_config = False
+
+ def reset_parameters(self):
+ return None
+
+ def _load_from_state_dict(self, *args):
+ _load_quantized_module(self, super()._load_from_state_dict, *args, load_extra_params=True)
+
+ def state_dict(self, *args, destination=None, prefix="", **kwargs):
+ sd = destination if destination is not None else {}
+ return _quantized_weight_state_dict(self, sd, prefix, extra_quant_params=("input_scale", "pre_quant_scale"))
+
+ def _forward(self, input, weight, bias):
+ return torch.nn.functional.linear(input, weight, bias)
+
+ def forward_comfy_cast_weights(
+ self,
+ input,
+ compute_dtype=None,
+ want_requant=False,
+ weight_only_quant=False,
+ ):
+ if weight_only_quant:
+ weight, bias, offload_stream = cast_bias_weight(
+ self,
+ input=None,
+ dtype=self.weight.dtype,
+ device=input.device,
+ bias_dtype=input.dtype,
+ offloadable=True,
+ compute_dtype=compute_dtype,
+ want_requant=True,
+ )
+ weight = weight.to(dtype=input.dtype)
+ else:
+ weight, bias, offload_stream = cast_bias_weight(
+ self,
+ input,
+ offloadable=True,
+ compute_dtype=compute_dtype,
+ want_requant=want_requant,
+ )
+ x = self._forward(input, weight, bias)
+ uncast_bias_weight(self, weight, bias, offload_stream)
+ return x
+
+ def forward(self, input, *args, **kwargs):
+ run_every_op()
+
+ # ModelOpt AWQ-style smoothing
+ pre_quant_scale = getattr(self, 'pre_quant_scale', None)
+ if pre_quant_scale is not None:
+ input = input * comfy.model_management.cast_to_device(pre_quant_scale, input.device, input.dtype)
+
+ input_shape = input.shape
+ reshaped_nd = False
+ #If cast needs to apply lora, it should be done in the compute dtype
+ compute_dtype = input.dtype
+
+ _use_quantized = (
+ getattr(self, 'layout_type', None) is not None and
+ not isinstance(input, QuantizedTensor) and not self._full_precision_mm and
+ not getattr(self, 'comfy_force_cast_weights', False) and
+ len(self.weight_function) == 0 and len(self.bias_function) == 0
+ )
+ quantize_input = QUANT_ALGOS.get(getattr(self, 'quant_format', None), {}).get("quantize_input", True)
+
+ # Training path: quantized forward with compute_dtype backward via autograd function
+ if (input.requires_grad and _use_quantized and quantize_input):
+
+ weight, bias, offload_stream = cast_bias_weight(
+ self,
+ input,
+ offloadable=True,
+ compute_dtype=compute_dtype,
+ want_requant=True
+ )
+
+ scale = getattr(self, 'input_scale', None)
+ if scale is not None:
+ scale = comfy.model_management.cast_to_device(scale, input.device, None)
+
+ output = QuantLinearFunc.apply(
+ input, weight, bias, self.layout_type, scale, compute_dtype
+ )
+
+ uncast_bias_weight(self, weight, bias, offload_stream)
+ return output
+
+ # Inference path (unchanged)
+ if _use_quantized and quantize_input:
+
+ # Reshape >=3D tensors to 2D for quantization (needed for NVFP4 and others)
+ input_reshaped = input.reshape(-1, input_shape[-1]) if input.ndim >= 3 else input
+
+ # Fall back to non-quantized for non-2D tensors
+ if input_reshaped.ndim == 2:
+ reshaped_nd = input.ndim >= 3
+ # dtype is now implicit in the layout class
+ scale = getattr(self, 'input_scale', None)
+ if scale is not None:
+ scale = comfy.model_management.cast_to_device(scale, input.device, None)
+ input = QuantizedTensor.from_float(input_reshaped, self.layout_type, scale=scale)
+
+ weight_only_quant = _use_quantized and not quantize_input and isinstance(self.weight, QuantizedTensor)
+ output = self.forward_comfy_cast_weights(
+ input,
+ compute_dtype,
+ want_requant=isinstance(input, QuantizedTensor),
+ weight_only_quant=weight_only_quant,
+ )
+
+ # Reshape output back to original rank if input was >2D
+ if reshaped_nd:
+ output = output.reshape((*input_shape[:-1], self.weight.shape[0]))
+
+ return output
+
+ def convert_weight(self, weight, inplace=False, **kwargs):
+ if isinstance(weight, QuantizedTensor):
+ return weight.dequantize()
+ else:
+ return weight
+
+ def set_weight(self, weight, inplace_update=False, seed=None, return_weight=False, **kwargs):
+ if getattr(self, 'layout_type', None) is not None:
+ weight = self.weight.requantize_from_float(weight, scale="recalculate", stochastic_rounding=seed, inplace_ops=True).to(self.weight.dtype)
+ else:
+ weight = weight.to(self.weight.dtype)
+ if return_weight:
+ return weight
+
+ assert inplace_update is False # TODO: eventually remove the inplace_update stuff
+ self.weight = torch.nn.Parameter(weight, requires_grad=False)
+
+ def _apply(self, fn, recurse=True): # This is to get torch.compile + moving weights to another device working
+ return _quantized_apply(self, fn, recurse)
+
+ class MoEExperts(torch.nn.Module, CastWeightBiasOp):
+ """Container for E quantized expert weights, indexed via expert_weight(i).
+
+ The bank lives on self.weight as a single 3D tensor — either a
+ compute_dtype Parameter or a Parameter wrapping a QuantizedTensor
+ with leading expert dim.
+
+ State-dict layout matches mixed_precision_ops.Linear with a leading
+ expert dim:
+ {prefix}.weight quant data (storage_t), leading dim = E
+ {prefix}.weight_scale block / per-tensor scale
+ {prefix}.weight_scale_2 [E] or scalar NVFP4 only
+ {prefix}.bias [E, out_features] optional, compute_dtype
+ {prefix}.comfy_quant json -> {{"format": "...", "num_experts": E}}
+
+ Without comfy_quant the weight loads as a plain compute_dtype 3D Parameter [E, out, in].
+ """
+
+ _disabled_formats = disabled
+
+ def __init__(self, num_experts: int, in_features: int, out_features: int, bias: bool = True, device=None, dtype=None):
+ super().__init__()
+ self.num_experts = num_experts
+ self.in_features = in_features
+ self.out_features = out_features
+ self._orig_shape = (num_experts, out_features, in_features)
+ self.factory_kwargs = {"device": device, "dtype": MixedPrecisionOps._compute_dtype}
+ if bias:
+ self.bias = torch.nn.Parameter(torch.empty(num_experts, out_features, **self.factory_kwargs))
+ else:
+ self.register_parameter("bias", None)
+
+ # Populated by _load_from_state_dict:
+ self.weight = None
+ self.quant_format = None
+ self.layout_type = None
+ self._full_precision_mm = MixedPrecisionOps._full_precision_mm
+ self._full_precision_mm_config = False
+ self._resident_bank = None
+
+ def reset_parameters(self):
+ return None
+
+ def _apply(self, fn, recurse=True):
+ return _quantized_apply(self, fn, recurse)
+
+ def _load_from_state_dict(self, *args):
+ _load_quantized_module(self, super()._load_from_state_dict, *args, load_extra_params=False)
+
+ def expert_weight(self, i: int):
+ """Expert i's weight (Tensor or per-expert QuantizedTensor view)."""
+ if isinstance(self.weight, QuantizedTensor):
+ return self._expert_qt_from(self.weight, i)
+ return self.weight[i]
+
+ @contextlib.contextmanager
+ def bank_resident(self, input):
+ """Cast the whole bank once; expert_linear inside reuses the cast.
+ Not re-entrant — do not nest calls on the same instance.
+ """
+ weight, bias, offload_stream = cast_bias_weight(self, input, offloadable=True)
+ self._resident_bank = (weight, bias)
+ try:
+ yield self
+ finally:
+ self._resident_bank = None
+ uncast_bias_weight(self, weight, bias, offload_stream)
+
+ def expert_linear(self, input: torch.Tensor, i: int) -> torch.Tensor:
+ """Linear against expert i's weight (with optional bias)."""
+ resident = getattr(self, "_resident_bank", None)
+ if resident is not None:
+ weight, bias = resident
+ return self._expert_linear_impl(input, weight, bias, i)
+ weight, bias, offload_stream = cast_bias_weight(self, input, offloadable=True)
+ try:
+ return self._expert_linear_impl(input, weight, bias, i)
+ finally:
+ uncast_bias_weight(self, weight, bias, offload_stream)
+
+ def _expert_linear_impl(self, input, weight, bias, i):
+ if isinstance(weight, QuantizedTensor):
+ qw = self._expert_qt_from(weight, i)
+ else:
+ qw = weight[i]
+ b = cast_to_input(bias[i], input, copy=False) if bias is not None else None
+
+ if isinstance(qw, QuantizedTensor):
+ use_fast = (
+ not self._full_precision_mm
+ and qw.layout_cls.supports_fast_matmul()
+ and input.dim() == 2
+ )
+ if use_fast:
+ qin = QuantizedTensor.from_float(input, self.layout_type)
+ return torch.nn.functional.linear(qin, qw, b)
+ out = input @ qw.dequantize().t()
+ return out + b if b is not None else out
+ return torch.nn.functional.linear(input, qw, b)
+
+ def _expert_qt_from(self, weight: QuantizedTensor, i: int) -> QuantizedTensor:
+ """Build a per-expert QuantizedTensor by indexing into a resident bank."""
+ params = weight._params
+ kwargs = {
+ "scale": params.scale[i] if params.scale.dim() else params.scale,
+ "orig_dtype": params.orig_dtype,
+ "orig_shape": (self.out_features, self.in_features),
+ }
+ if hasattr(params, "block_scale"): # NVFP4
+ kwargs["block_scale"] = params.block_scale[i]
+ if hasattr(params, "quant_group_size"):
+ kwargs["quant_group_size"] = params.quant_group_size
+ if hasattr(params, "convrot_groupsize"):
+ kwargs["convrot_groupsize"] = params.convrot_groupsize
+ if hasattr(params, "linear_dtype"):
+ kwargs["linear_dtype"] = params.linear_dtype
+ return QuantizedTensor(weight._qdata[i], weight._layout_cls, type(params)(**kwargs))
+
+ def state_dict(self, *args, destination=None, prefix="", **kwargs):
+ sd = destination if destination is not None else {}
+ return _quantized_weight_state_dict(self, sd, prefix, extra_quant_conf={"num_experts": self.num_experts})
+
+ class Embedding(manual_cast.Embedding):
+ def _load_from_state_dict(self, state_dict, prefix, local_metadata, strict, missing_keys, unexpected_keys, error_msgs):
+ weight_key = f"{prefix}weight"
+ layer_conf = state_dict.pop(f"{prefix}comfy_quant", None)
+ if layer_conf is not None:
+ layer_conf = json.loads(layer_conf.numpy().tobytes())
+
+ # Only fp8 and int8_tensorwise support per-row dequant via index select.
+ # Block-scaled formats (NVFP4, MXFP8) can't do per-row lookup efficiently.
+ quant_format = layer_conf.get("format") if layer_conf is not None else None
+ manually_loaded_keys = []
+
+ if quant_format in ("float8_e4m3fn", "float8_e5m2", "int8_tensorwise") and weight_key in state_dict:
+ self.quant_format = quant_format
+ qconfig = QUANT_ALGOS[quant_format]
+ self.layout_type = qconfig["comfy_tensor_layout"]
+ layout_cls = get_layout_class(self.layout_type)
+ weight = state_dict.pop(weight_key)
+ manually_loaded_keys.append(weight_key)
+
+ scale_key = f"{prefix}weight_scale"
+ scale = state_dict.pop(scale_key, None)
+ if scale is not None:
+ scale = scale.float()
+ manually_loaded_keys.append(scale_key)
+
+ extra = {}
+ if quant_format == "int8_tensorwise" and layer_conf.get("convrot", False):
+ # rotated embedding table: record it so the forward un-rotates after lookup
+ extra["convrot"] = True
+ extra["convrot_groupsize"] = int(layer_conf.get("convrot_groupsize", 256))
+ params = layout_cls.Params(
+ scale=scale if scale is not None else torch.ones((), dtype=torch.float32),
+ orig_dtype=MixedPrecisionOps._compute_dtype,
+ orig_shape=(self.num_embeddings, self.embedding_dim),
+ **extra,
+ )
+ self.weight = torch.nn.Parameter(
+ QuantizedTensor(weight.to(dtype=qconfig["storage_t"]), qconfig["comfy_tensor_layout"], params),
+ requires_grad=False)
+ elif layer_conf is not None:
+ # Unsupported format — restore the marker so it round-trips; fall through to default load.
+ state_dict[f"{prefix}comfy_quant"] = torch.tensor(
+ list(json.dumps(layer_conf).encode('utf-8')), dtype=torch.uint8)
+
+ super()._load_from_state_dict(state_dict, prefix, local_metadata, strict, missing_keys, unexpected_keys, error_msgs)
+ for k in manually_loaded_keys:
+ if k in missing_keys:
+ missing_keys.remove(k)
+
+ def state_dict(self, *args, destination=None, prefix="", **kwargs):
+ sd = destination if destination is not None else {}
+ return _quantized_weight_state_dict(self, sd, prefix)
+
+ def forward_comfy_cast_weights(self, input, out_dtype=None):
+ weight = self.weight
+
+ # Optimized path: lookup in fp8/int8, dequantize only the selected rows.
+ if isinstance(weight, QuantizedTensor) and len(self.weight_function) == 0:
+ qdata, _, offload_stream = cast_bias_weight(self, device=input.device, dtype=weight.dtype, offloadable=True)
+ if isinstance(qdata, QuantizedTensor):
+ params = qdata._params
+ scale = params.scale
+ qdata = qdata._qdata
+ else:
+ params = weight._params
+ scale = None
+
+ # int8: per-row scale possible ConvRot, so let the layout do the gather
+ if self.quant_format == "int8_tensorwise":
+ x = get_layout_class(self.layout_type).dequantize_embedding(qdata, params, input)
+ uncast_bias_weight(self, qdata, None, offload_stream)
+ return x if out_dtype is None else x.to(dtype=out_dtype)
+
+ x = torch.nn.functional.embedding(
+ input, qdata, self.padding_idx, self.max_norm,
+ self.norm_type, self.scale_grad_by_freq, self.sparse)
+ uncast_bias_weight(self, qdata, None, offload_stream)
+ target_dtype = out_dtype if out_dtype is not None else weight._params.orig_dtype
+ x = x.to(dtype=target_dtype)
+ if scale is not None and scale != 1.0:
+ x = x * scale.to(dtype=target_dtype)
+ return x
+
+ # Fallback for non-quantized or weight_function (LoRA) case
+ return super().forward_comfy_cast_weights(input, out_dtype=out_dtype)
+
+ return MixedPrecisionOps
+
+def pick_operations(weight_dtype, compute_dtype, load_device=None, disable_fast_fp8=False, fp8_optimizations=False, model_config=None):
+ fp8_compute = comfy.model_management.supports_fp8_compute(load_device) # TODO: if we support more ops this needs to be more granular
+ nvfp4_compute = comfy.model_management.supports_nvfp4_compute(load_device)
+ mxfp8_compute = comfy.model_management.supports_mxfp8_compute(load_device)
+
+ if model_config and hasattr(model_config, 'quant_config') and model_config.quant_config:
+ logging.info("Using mixed precision operations")
+ disabled = set()
+ if not nvfp4_compute:
+ disabled.add("nvfp4")
+ if not mxfp8_compute:
+ disabled.add("mxfp8")
+ if not fp8_compute:
+ disabled.add("float8_e4m3fn")
+ disabled.add("float8_e5m2")
+ logging.info("Native ops: {} {}".format(", ".join(QUANT_ALGOS.keys() - disabled), ", emulated ops: {}".format(", ".join(disabled)) if len(disabled) > 0 else ""))
+ return mixed_precision_ops(model_config.quant_config, compute_dtype, disabled=disabled)
+
+ if (
+ fp8_compute and
+ (fp8_optimizations or PerformanceFeature.Fp8MatrixMultiplication in args.fast) and
+ not disable_fast_fp8
+ ):
+ return fp8_ops
+
+ if (
+ PerformanceFeature.CublasOps in args.fast and
+ CUBLAS_IS_AVAILABLE and
+ weight_dtype == torch.float16 and
+ (compute_dtype == torch.float16 or compute_dtype is None)
+ ):
+ logging.info("Using cublas ops")
+ return cublas_ops
+
+ if compute_dtype is None or weight_dtype == compute_dtype:
+ return disable_weight_init
+
+ return manual_cast
diff --git a/ComfyUI/comfy/options.py b/ComfyUI/comfy/options.py
new file mode 100644
index 0000000000000000000000000000000000000000..f7f8af41ebd8b9669ef0ef21827ea6195bcb4752
--- /dev/null
+++ b/ComfyUI/comfy/options.py
@@ -0,0 +1,6 @@
+
+args_parsing = False
+
+def enable_args_parsing(enable=True):
+ global args_parsing
+ args_parsing = enable
diff --git a/ComfyUI/comfy/patcher_extension.py b/ComfyUI/comfy/patcher_extension.py
new file mode 100644
index 0000000000000000000000000000000000000000..189ee84caa353a0ba869d287d931a78e70faca06
--- /dev/null
+++ b/ComfyUI/comfy/patcher_extension.py
@@ -0,0 +1,159 @@
+from typing import Callable
+
+class CallbacksMP:
+ ON_CLONE = "on_clone"
+ ON_DEEPCLONE_MULTIGPU = "on_deepclone_multigpu"
+ ON_MATCH_MULTIGPU_CLONES = "on_match_multigpu_clones"
+ ON_LOAD = "on_load_after"
+ ON_DETACH = "on_detach_after"
+ ON_CLEANUP = "on_cleanup"
+ ON_PRE_RUN = "on_pre_run"
+ ON_PREPARE_STATE = "on_prepare_state"
+ ON_APPLY_HOOKS = "on_apply_hooks"
+ ON_REGISTER_ALL_HOOK_PATCHES = "on_register_all_hook_patches"
+ ON_INJECT_MODEL = "on_inject_model"
+ ON_EJECT_MODEL = "on_eject_model"
+
+ # callbacks dict is in the format:
+ # {"call_type": {"key": [Callable1, Callable2, ...]} }
+ @classmethod
+ def init_callbacks(cls) -> dict[str, dict[str, list[Callable]]]:
+ return {}
+
+def add_callback(call_type: str, callback: Callable, transformer_options: dict, is_model_options=False):
+ add_callback_with_key(call_type, None, callback, transformer_options, is_model_options)
+
+def add_callback_with_key(call_type: str, key: str, callback: Callable, transformer_options: dict, is_model_options=False):
+ if is_model_options:
+ transformer_options = transformer_options.setdefault("transformer_options", {})
+ callbacks: dict[str, dict[str, list]] = transformer_options.setdefault("callbacks", {})
+ c = callbacks.setdefault(call_type, {}).setdefault(key, [])
+ c.append(callback)
+
+def get_callbacks_with_key(call_type: str, key: str, transformer_options: dict, is_model_options=False):
+ if is_model_options:
+ transformer_options = transformer_options.get("transformer_options", {})
+ c_list = []
+ callbacks: dict[str, list] = transformer_options.get("callbacks", {})
+ c_list.extend(callbacks.get(call_type, {}).get(key, []))
+ return c_list
+
+def get_all_callbacks(call_type: str, transformer_options: dict, is_model_options=False):
+ if is_model_options:
+ transformer_options = transformer_options.get("transformer_options", {})
+ c_list = []
+ callbacks: dict[str, list] = transformer_options.get("callbacks", {})
+ for c in callbacks.get(call_type, {}).values():
+ c_list.extend(c)
+ return c_list
+
+class WrappersMP:
+ OUTER_SAMPLE = "outer_sample"
+ PREPARE_SAMPLING = "prepare_sampling"
+ SAMPLER_SAMPLE = "sampler_sample"
+ PREDICT_NOISE = "predict_noise"
+ CALC_COND_BATCH = "calc_cond_batch"
+ APPLY_MODEL = "apply_model"
+ DIFFUSION_MODEL = "diffusion_model"
+
+ # wrappers dict is in the format:
+ # {"wrapper_type": {"key": [Callable1, Callable2, ...]} }
+ @classmethod
+ def init_wrappers(cls) -> dict[str, dict[str, list[Callable]]]:
+ return {}
+
+def add_wrapper(wrapper_type: str, wrapper: Callable, transformer_options: dict, is_model_options=False):
+ add_wrapper_with_key(wrapper_type, None, wrapper, transformer_options, is_model_options)
+
+def add_wrapper_with_key(wrapper_type: str, key: str, wrapper: Callable, transformer_options: dict, is_model_options=False):
+ if is_model_options:
+ transformer_options = transformer_options.setdefault("transformer_options", {})
+ wrappers: dict[str, dict[str, list]] = transformer_options.setdefault("wrappers", {})
+ w = wrappers.setdefault(wrapper_type, {}).setdefault(key, [])
+ w.append(wrapper)
+
+def get_wrappers_with_key(wrapper_type: str, key: str, transformer_options: dict, is_model_options=False):
+ if is_model_options:
+ transformer_options = transformer_options.get("transformer_options", {})
+ w_list = []
+ wrappers: dict[str, list] = transformer_options.get("wrappers", {})
+ w_list.extend(wrappers.get(wrapper_type, {}).get(key, []))
+ return w_list
+
+def get_all_wrappers(wrapper_type: str, transformer_options: dict, is_model_options=False):
+ if is_model_options:
+ transformer_options = transformer_options.get("transformer_options", {})
+ w_list = []
+ wrappers: dict[str, list] = transformer_options.get("wrappers", {})
+ for w in wrappers.get(wrapper_type, {}).values():
+ w_list.extend(w)
+ return w_list
+
+class WrapperExecutor:
+ """Handles call stack of wrappers around a function in an ordered manner."""
+ def __init__(self, original: Callable, class_obj: object, wrappers: list[Callable], idx: int):
+ # NOTE: class_obj exists so that wrappers surrounding a class method can access
+ # the class instance at runtime via executor.class_obj
+ self.original = original
+ self.class_obj = class_obj
+ self.wrappers = wrappers.copy()
+ self.idx = idx
+ self.is_last = idx == len(wrappers)
+
+ def __call__(self, *args, **kwargs):
+ """Calls the next wrapper or original function, whichever is appropriate."""
+ new_executor = self._create_next_executor()
+ return new_executor.execute(*args, **kwargs)
+
+ def execute(self, *args, **kwargs):
+ """Used to initiate executor internally - DO NOT use this if you received executor in wrapper."""
+ args = list(args)
+ kwargs = dict(kwargs)
+ if self.is_last:
+ return self.original(*args, **kwargs)
+ return self.wrappers[self.idx](self, *args, **kwargs)
+
+ def _create_next_executor(self) -> 'WrapperExecutor':
+ new_idx = self.idx + 1
+ if new_idx > len(self.wrappers):
+ raise Exception("Wrapper idx exceeded available wrappers; something went very wrong.")
+ if self.class_obj is None:
+ return WrapperExecutor.new_executor(self.original, self.wrappers, new_idx)
+ return WrapperExecutor.new_class_executor(self.original, self.class_obj, self.wrappers, new_idx)
+
+ @classmethod
+ def new_executor(cls, original: Callable, wrappers: list[Callable], idx=0):
+ return cls(original, class_obj=None, wrappers=wrappers, idx=idx)
+
+ @classmethod
+ def new_class_executor(cls, original: Callable, class_obj: object, wrappers: list[Callable], idx=0):
+ return cls(original, class_obj, wrappers, idx=idx)
+
+class PatcherInjection:
+ def __init__(self, inject: Callable, eject: Callable):
+ self.inject = inject
+ self.eject = eject
+
+def copy_nested_dicts(input_dict: dict):
+ new_dict = input_dict.copy()
+ for key, value in input_dict.items():
+ if isinstance(value, dict):
+ new_dict[key] = copy_nested_dicts(value)
+ elif isinstance(value, list):
+ new_dict[key] = value.copy()
+ return new_dict
+
+def merge_nested_dicts(dict1: dict, dict2: dict, copy_dict1=True):
+ if copy_dict1:
+ merged_dict = copy_nested_dicts(dict1)
+ else:
+ merged_dict = dict1
+ for key, value in dict2.items():
+ if isinstance(value, dict):
+ curr_value = merged_dict.setdefault(key, {})
+ merged_dict[key] = merge_nested_dicts(curr_value, value)
+ elif isinstance(value, list):
+ merged_dict.setdefault(key, []).extend(value)
+ else:
+ merged_dict[key] = value
+ return merged_dict
diff --git a/ComfyUI/comfy/pinned_memory.py b/ComfyUI/comfy/pinned_memory.py
new file mode 100644
index 0000000000000000000000000000000000000000..e9a9a70e2984b6b1a018e8fcae177196ad79f91a
--- /dev/null
+++ b/ComfyUI/comfy/pinned_memory.py
@@ -0,0 +1,127 @@
+import bisect
+
+import comfy.model_management
+import comfy.memory_management
+import comfy.utils
+import comfy_aimdo.host_buffer
+import comfy_aimdo.torch
+import torch
+
+from comfy.cli_args import args
+
+def _add_to_bucket(module, module_pin, buckets, size, priority):
+ bucket = buckets.setdefault(size, [])
+ entry = [-priority, 0, module]
+ entry[1] = id(entry)
+ bisect.insort(bucket, entry)
+ module_pin["balancer_entry"] = entry
+
+def _steal_pin(module, stack, buckets, size, priority, subset):
+ bucket = buckets.get(size)
+ if bucket is None:
+ return False
+
+ while bucket and bucket[-1][-1] is None:
+ bucket.pop()
+ if not bucket:
+ del buckets[size]
+ return False
+
+ if priority <= -bucket[-1][0]:
+ return False
+
+ *_, victim = bucket.pop()
+ module_pin = module._pins[subset]
+ victim_pin = victim._pins[subset]
+ module_pin["pin"] = victim_pin["pin"]
+ module_pin["registered"] = victim_pin["registered"]
+ module_pin["stack_index"] = victim_pin["stack_index"]
+ stack_index = module_pin["stack_index"]
+ stack[stack_index] = (module, stack[stack_index][1])
+
+ victim_pin["registered"] = False
+ del victim_pin["pin"]
+ del victim_pin["stack_index"]
+ del victim_pin["balancer_entry"]
+
+ _add_to_bucket(module, module_pin, buckets, size, priority)
+ return True
+
+def get_pin(module, subset="weights"):
+ pins = module.__dict__.get("_pins")
+ module_pin = None if pins is None else pins.get(subset)
+ pin = None if module_pin is None else module_pin.get("pin")
+ if pin is None or module_pin["registered"] or args.disable_pinned_memory:
+ return pin
+
+ _, _, stack_split, pinned_size, *_ = module._pin_state[subset]
+ size = pin.nbytes
+ comfy.model_management.ensure_pin_registerable(size)
+
+ if torch.cuda.cudart().cudaHostRegister(pin.data_ptr(), size, 1) != 0:
+ comfy.model_management.discard_cuda_async_error()
+ return pin
+
+ module_pin["registered"] = True
+ stack_split[0] = max(stack_split[0], module_pin["stack_index"])
+ comfy.model_management.TOTAL_PINNED_MEMORY += size
+ pinned_size[0] += size
+ return pin
+
+def pin_memory(module, subset="weights", size=None):
+ pin_state = module._pin_state
+ if args.disable_pinned_memory:
+ return
+
+ pin = get_pin(module, subset)
+ if pin is not None:
+ return
+
+ pins = module.__dict__.setdefault("_pins", {})
+ module_pin = pins.setdefault(subset, {})
+ hostbuf, stack, stack_split, pinned_size, counter, buckets = pin_state[subset]
+ if size is None:
+ size = comfy.memory_management.vram_aligned_size([ module.weight, module.bias ])
+ registerable_size = size
+ loaded = subset.endswith("-loaded")
+ priority = module_pin.get("balancer_priority")
+
+ if priority is None:
+ priority = comfy.utils.bit_reverse_range(counter[0], 16)
+ counter[0] += 1
+ module_pin["balancer_priority"] = priority
+
+ comfy.memory_management.extra_ram_release(comfy.memory_management.RAM_CACHE_HEADROOM)
+ if (not comfy.model_management.ensure_pin_budget(size, loaded=loaded) or
+ not comfy.model_management.ensure_pin_registerable(registerable_size)):
+ return _steal_pin(module, stack, buckets, size, priority, subset)
+
+ offset = hostbuf.size
+ extended = False
+ try:
+ hostbuf.extend(size=size, register=False)
+ extended = True
+ pin = comfy_aimdo.torch.hostbuf_to_tensor(hostbuf)[offset:offset + size]
+ pin.untyped_storage()._comfy_hostbuf = hostbuf
+ if torch.cuda.cudart().cudaHostRegister(pin.data_ptr(), size, 1) != 0:
+ comfy.model_management.discard_cuda_async_error()
+ comfy.model_management.free_registrations(size)
+ if torch.cuda.cudart().cudaHostRegister(pin.data_ptr(), size, 1) != 0:
+ comfy.model_management.discard_cuda_async_error()
+ del pin
+ hostbuf.truncate(offset, do_unregister=False)
+ return _steal_pin(module, stack, buckets, size, priority, subset)
+ except RuntimeError:
+ if extended:
+ hostbuf.truncate(offset, do_unregister=False)
+ return _steal_pin(module, stack, buckets, size, priority, subset)
+
+ module_pin["pin"] = pin
+ stack.append((module, offset))
+ module_pin["registered"] = True
+ module_pin["stack_index"] = len(stack) - 1
+ stack_split[0] = max(stack_split[0], module_pin["stack_index"])
+ comfy.model_management.TOTAL_PINNED_MEMORY += size
+ pinned_size[0] += size
+ _add_to_bucket(module, module_pin, buckets, size, priority)
+ return True
diff --git a/ComfyUI/comfy/pixel_space_convert.py b/ComfyUI/comfy/pixel_space_convert.py
new file mode 100644
index 0000000000000000000000000000000000000000..049bbcfb42d273108c12cd7856ca46273ceca1cd
--- /dev/null
+++ b/ComfyUI/comfy/pixel_space_convert.py
@@ -0,0 +1,16 @@
+import torch
+
+
+# "Fake" VAE that converts from IMAGE B, H, W, C and values on the scale of 0..1
+# to LATENT B, C, H, W and values on the scale of -1..1.
+class PixelspaceConversionVAE(torch.nn.Module):
+ def __init__(self):
+ super().__init__()
+ self.pixel_space_vae = torch.nn.Parameter(torch.tensor(1.0))
+
+ def encode(self, pixels: torch.Tensor, *_args, **_kwargs) -> torch.Tensor:
+ return pixels
+
+ def decode(self, samples: torch.Tensor, *_args, **_kwargs) -> torch.Tensor:
+ return samples
+
diff --git a/ComfyUI/comfy/quant_ops.py b/ComfyUI/comfy/quant_ops.py
new file mode 100644
index 0000000000000000000000000000000000000000..53586956a1c0d096b2085d483c14c10a65a33c3a
--- /dev/null
+++ b/ComfyUI/comfy/quant_ops.py
@@ -0,0 +1,287 @@
+import torch
+import logging
+
+from comfy.cli_args import args
+
+
+def _rocm_kitchen_arch_supported():
+ """comfy-kitchen's INT8 Triton kernels compile tl.dot to matrix-core instructions.
+ RDNA3/3.5/4 (gfx11xx/gfx12xx) have WMMA and CDNA (gfx9xx) has MFMA; RDNA1/RDNA2
+ (gfx10xx) have neither, so the INT8 path hangs the GPU there. Gates the automatic
+ ROCm default so those cards stay on the eager fallback (an explicit
+ --enable-triton-backend still forces it on any arch)."""
+ try:
+ arch = torch.cuda.get_device_properties(torch.cuda.current_device()).gcnArchName.split(":")[0]
+ except Exception:
+ return False
+ if arch.startswith(("gfx11", "gfx12")):
+ return True
+ return arch in ("gfx908", "gfx90a", "gfx940", "gfx941", "gfx942", "gfx950")
+
+
+try:
+ import comfy_kitchen as ck
+ from comfy_kitchen.tensor import (
+ QuantizedTensor,
+ QuantizedLayout,
+ TensorCoreFP8Layout as _CKFp8Layout,
+ TensorCoreNVFP4Layout as _CKNvfp4Layout,
+ TensorCoreConvRotW4A4Layout as _CKTensorCoreConvRotW4A4Layout,
+ TensorWiseINT8Layout as _CKTensorWiseINT8Layout,
+ register_layout_op,
+ register_layout_class,
+ get_layout_class,
+ )
+ _CK_AVAILABLE = True
+ if torch.version.cuda is None:
+ ck.registry.disable("cuda")
+ else:
+ cuda_version = tuple(map(int, str(torch.version.cuda).split('.')))
+ if cuda_version < (13,):
+ ck.registry.disable("cuda")
+ logging.warning("WARNING: You need pytorch with cu130 or higher to use optimized CUDA operations.")
+
+ # On ROCm/AMD the CUDA backend is unavailable, so Triton is the only accelerated
+ # comfy-kitchen backend. Enable it by default there, but only on Triton >= 3.7 AND a
+ # matrix-core GPU (RDNA3+ WMMA gfx11xx/gfx12xx, CDNA MFMA gfx9xx). RDNA1/RDNA2
+ # (gfx10xx) have no WMMA -> the INT8 tl.dot path hangs the GPU, so they stay eager.
+ # older Triton lacks libdevice.rint on the HIP backend and hard-crashes the INT8 path.
+ if args.disable_triton_backend:
+ ck.registry.disable("triton")
+ elif args.enable_triton_backend: # or (torch.version.hip is not None and _rocm_kitchen_arch_supported()):
+ try:
+ import triton
+ triton_version = tuple(int(v) for v in triton.__version__.split(".")[:2])
+ if args.enable_triton_backend or triton_version >= (3, 7):
+ logging.info("Found triton %s. Enabling comfy-kitchen triton backend.", triton.__version__)
+ else:
+ logging.info("Triton %s is too old for the ROCm INT8 path (needs >= 3.7); comfy-kitchen triton backend disabled.", triton.__version__)
+ ck.registry.disable("triton")
+ except ImportError as e:
+ logging.error(f"Failed to import triton, Error: {e}, the comfy-kitchen triton backend will not be available.")
+ ck.registry.disable("triton")
+ else:
+ ck.registry.disable("triton")
+ for k, v in ck.list_backends().items():
+ logging.info(f"Found comfy_kitchen backend {k}: {v}")
+except ImportError as e:
+ logging.error(f"Failed to import comfy_kitchen, Error: {e}, fp8 and fp4 support will not be available.")
+ _CK_AVAILABLE = False
+
+ class QuantizedTensor:
+ pass
+
+ class _CKFp8Layout:
+ pass
+
+ class _CKNvfp4Layout:
+ pass
+
+ class _CKTensorWiseINT8Layout:
+ pass
+
+ class _CKTensorCoreConvRotW4A4Layout:
+ pass
+
+ def register_layout_class(name, cls):
+ pass
+
+ def get_layout_class(name):
+ return None
+
+_CK_MXFP8_AVAILABLE = False
+if _CK_AVAILABLE:
+ try:
+ from comfy_kitchen.tensor import TensorCoreMXFP8Layout as _CKMxfp8Layout
+ _CK_MXFP8_AVAILABLE = True
+ except ImportError:
+ logging.warning("comfy_kitchen does not support MXFP8, please update comfy_kitchen.")
+
+if not _CK_MXFP8_AVAILABLE:
+ class _CKMxfp8Layout:
+ pass
+
+import comfy.float
+
+# ==============================================================================
+# FP8 Layouts with Comfy-Specific Extensions
+# ==============================================================================
+
+class _TensorCoreFP8LayoutBase(_CKFp8Layout):
+ FP8_DTYPE = None # Must be overridden in subclass
+
+ @classmethod
+ def quantize(cls, tensor, scale=None, stochastic_rounding=0, inplace_ops=False):
+ if cls.FP8_DTYPE is None:
+ raise NotImplementedError(f"{cls.__name__} must define FP8_DTYPE")
+
+ orig_dtype = tensor.dtype
+ orig_shape = tuple(tensor.shape)
+
+ if isinstance(scale, str) and scale == "recalculate":
+ scale = torch.amax(tensor.abs()).to(dtype=torch.float32) / torch.finfo(cls.FP8_DTYPE).max
+ if tensor.dtype not in [torch.float32, torch.bfloat16]: # Prevent scale from being too small
+ tensor_info = torch.finfo(tensor.dtype)
+ scale = (1.0 / torch.clamp((1.0 / scale), min=tensor_info.min, max=tensor_info.max))
+
+ if scale is None:
+ scale = torch.ones((), device=tensor.device, dtype=torch.float32)
+ if not isinstance(scale, torch.Tensor):
+ scale = torch.tensor(scale, device=tensor.device, dtype=torch.float32)
+
+ if stochastic_rounding > 0:
+ if inplace_ops:
+ tensor *= (1.0 / scale).to(tensor.dtype)
+ else:
+ tensor = tensor * (1.0 / scale).to(tensor.dtype)
+ qdata = comfy.float.stochastic_rounding(tensor, dtype=cls.FP8_DTYPE, seed=stochastic_rounding)
+ else:
+ qdata = ck.quantize_per_tensor_fp8(tensor, scale, cls.FP8_DTYPE)
+
+ params = cls.Params(scale=scale.float(), orig_dtype=orig_dtype, orig_shape=orig_shape)
+ return qdata, params
+
+
+class TensorCoreMXFP8Layout(_CKMxfp8Layout):
+ @classmethod
+ def quantize(cls, tensor, scale=None, stochastic_rounding=0, inplace_ops=False):
+ if tensor.dim() != 2:
+ raise ValueError(f"MXFP8 requires 2D tensor, got {tensor.dim()}D")
+
+ orig_dtype = tensor.dtype
+ orig_shape = tuple(tensor.shape)
+
+ padded_shape = cls.get_padded_shape(orig_shape)
+ needs_padding = padded_shape != orig_shape
+
+ if stochastic_rounding > 0:
+ qdata, block_scale = comfy.float.stochastic_round_quantize_mxfp8_by_block(tensor, pad_32x=needs_padding, seed=stochastic_rounding)
+ else:
+ qdata, block_scale = ck.quantize_mxfp8(tensor, pad_32x=needs_padding)
+
+ params = cls.Params(
+ scale=block_scale,
+ orig_dtype=orig_dtype,
+ orig_shape=orig_shape,
+ )
+ return qdata, params
+
+
+class TensorCoreNVFP4Layout(_CKNvfp4Layout):
+ @classmethod
+ def quantize(cls, tensor, scale=None, stochastic_rounding=0, inplace_ops=False):
+ if tensor.dim() != 2:
+ raise ValueError(f"NVFP4 requires 2D tensor, got {tensor.dim()}D")
+
+ orig_dtype = tensor.dtype
+ orig_shape = tuple(tensor.shape)
+
+ if scale is None or (isinstance(scale, str) and scale == "recalculate"):
+ scale = torch.amax(tensor.abs()) / (ck.float_utils.F8_E4M3_MAX * ck.float_utils.F4_E2M1_MAX)
+
+ if not isinstance(scale, torch.Tensor):
+ scale = torch.tensor(scale)
+ scale = scale.to(device=tensor.device, dtype=torch.float32)
+
+ padded_shape = cls.get_padded_shape(orig_shape)
+ needs_padding = padded_shape != orig_shape
+
+ if stochastic_rounding > 0:
+ qdata, block_scale = comfy.float.stochastic_round_quantize_nvfp4_by_block(tensor, scale, pad_16x=needs_padding, seed=stochastic_rounding)
+ else:
+ qdata, block_scale = ck.quantize_nvfp4(tensor, scale, pad_16x=needs_padding)
+
+ params = cls.Params(
+ scale=scale,
+ orig_dtype=orig_dtype,
+ orig_shape=orig_shape,
+ block_scale=block_scale,
+ )
+ return qdata, params
+
+
+class TensorCoreFP8E4M3Layout(_TensorCoreFP8LayoutBase):
+ FP8_DTYPE = torch.float8_e4m3fn
+
+
+class TensorCoreFP8E5M2Layout(_TensorCoreFP8LayoutBase):
+ FP8_DTYPE = torch.float8_e5m2
+
+
+# Backward compatibility alias - default to E4M3
+TensorCoreFP8Layout = TensorCoreFP8E4M3Layout
+TensorWiseINT8Layout = _CKTensorWiseINT8Layout
+TensorCoreConvRotW4A4Layout = _CKTensorCoreConvRotW4A4Layout
+
+
+# ==============================================================================
+# Registry
+# ==============================================================================
+
+register_layout_class("TensorCoreFP8Layout", TensorCoreFP8Layout)
+register_layout_class("TensorCoreFP8E4M3Layout", TensorCoreFP8E4M3Layout)
+register_layout_class("TensorCoreFP8E5M2Layout", TensorCoreFP8E5M2Layout)
+register_layout_class("TensorCoreNVFP4Layout", TensorCoreNVFP4Layout)
+register_layout_class("TensorWiseINT8Layout", _CKTensorWiseINT8Layout)
+register_layout_class("TensorCoreConvRotW4A4Layout", _CKTensorCoreConvRotW4A4Layout)
+if _CK_MXFP8_AVAILABLE:
+ register_layout_class("TensorCoreMXFP8Layout", TensorCoreMXFP8Layout)
+
+QUANT_ALGOS = {
+ "float8_e4m3fn": {
+ "storage_t": torch.float8_e4m3fn,
+ "parameters": {"weight_scale", "input_scale"},
+ "comfy_tensor_layout": "TensorCoreFP8E4M3Layout",
+ },
+ "float8_e5m2": {
+ "storage_t": torch.float8_e5m2,
+ "parameters": {"weight_scale", "input_scale"},
+ "comfy_tensor_layout": "TensorCoreFP8E5M2Layout",
+ },
+ "nvfp4": {
+ "storage_t": torch.uint8,
+ "parameters": {"weight_scale", "weight_scale_2", "input_scale", "pre_quant_scale"},
+ "comfy_tensor_layout": "TensorCoreNVFP4Layout",
+ "group_size": 16,
+ },
+}
+
+if _CK_MXFP8_AVAILABLE:
+ QUANT_ALGOS["mxfp8"] = {
+ "storage_t": torch.float8_e4m3fn,
+ "parameters": {"weight_scale", "input_scale"},
+ "comfy_tensor_layout": "TensorCoreMXFP8Layout",
+ "group_size": 32,
+ }
+
+QUANT_ALGOS["int8_tensorwise"] = {
+ "storage_t": torch.int8,
+ "parameters": {"weight_scale"},
+ "comfy_tensor_layout": "TensorWiseINT8Layout",
+ "quantize_input": False,
+}
+
+QUANT_ALGOS["convrot_w4a4"] = {
+ "storage_t": torch.int8,
+ "parameters": {"weight_scale"},
+ "comfy_tensor_layout": "TensorCoreConvRotW4A4Layout",
+ "quantize_input": False,
+}
+
+
+# ==============================================================================
+# Re-exports for backward compatibility
+# ==============================================================================
+
+__all__ = [
+ "QuantizedTensor",
+ "QuantizedLayout",
+ "TensorCoreFP8Layout",
+ "TensorCoreFP8E4M3Layout",
+ "TensorCoreFP8E5M2Layout",
+ "TensorCoreNVFP4Layout",
+ "TensorCoreConvRotW4A4Layout",
+ "TensorWiseINT8Layout",
+ "QUANT_ALGOS",
+ "register_layout_op",
+]
diff --git a/ComfyUI/comfy/rmsnorm.py b/ComfyUI/comfy/rmsnorm.py
new file mode 100644
index 0000000000000000000000000000000000000000..e54be98d6392a6c5c4641f6c7f8b952da922125e
--- /dev/null
+++ b/ComfyUI/comfy/rmsnorm.py
@@ -0,0 +1,11 @@
+import torch
+import comfy.model_management
+
+RMSNorm = torch.nn.RMSNorm
+
+# Note: torch's fused F.rms_norm is faster but produces slightly different output than manual implementations (rsqrt/reduction rounding).
+def rms_norm(x, weight=None, eps=1e-6):
+ if weight is None:
+ return torch.nn.functional.rms_norm(x, (x.shape[-1],), eps=eps)
+ else:
+ return torch.nn.functional.rms_norm(x, weight.shape, weight=comfy.model_management.cast_to(weight, dtype=x.dtype, device=x.device), eps=eps)
diff --git a/ComfyUI/comfy/sample.py b/ComfyUI/comfy/sample.py
new file mode 100644
index 0000000000000000000000000000000000000000..2be0cae5f87273c6ffbf641ae70676d0bdff97cc
--- /dev/null
+++ b/ComfyUI/comfy/sample.py
@@ -0,0 +1,81 @@
+import torch
+import comfy.model_management
+import comfy.samplers
+import comfy.utils
+import numpy as np
+import logging
+import comfy.nested_tensor
+
+def prepare_noise_inner(latent_image, generator, noise_inds=None):
+ if noise_inds is None:
+ return torch.randn(latent_image.size(), dtype=torch.float32, layout=latent_image.layout, generator=generator, device="cpu").to(dtype=latent_image.dtype)
+
+ unique_inds, inverse = np.unique(noise_inds, return_inverse=True)
+ noises = []
+ for i in range(unique_inds[-1]+1):
+ noise = torch.randn([1] + list(latent_image.size())[1:], dtype=torch.float32, layout=latent_image.layout, generator=generator, device="cpu").to(dtype=latent_image.dtype)
+ if i in unique_inds:
+ noises.append(noise)
+ noises = [noises[i] for i in inverse]
+ return torch.cat(noises, axis=0)
+
+def prepare_noise(latent_image, seed, noise_inds=None):
+ """
+ creates random noise given a latent image and a seed.
+ optional arg skip can be used to skip and discard x number of noise generations for a given seed
+ """
+ generator = torch.manual_seed(seed)
+
+ if latent_image.is_nested:
+ tensors = latent_image.unbind()
+ noises = []
+ for t in tensors:
+ noises.append(prepare_noise_inner(t, generator, noise_inds))
+ noises = comfy.nested_tensor.NestedTensor(noises)
+ else:
+ noises = prepare_noise_inner(latent_image, generator, noise_inds)
+
+ return noises
+
+def fix_empty_latent_channels(model, latent_image, downscale_ratio_spacial=None, downscale_ratio_temporal=None):
+ if latent_image.is_nested:
+ return latent_image
+ latent_format = model.get_model_object("latent_format") #Resize the empty latent image so it has the right number of channels
+ is_empty = torch.count_nonzero(latent_image) == 0
+ if is_empty:
+ if latent_format.latent_channels != latent_image.shape[1]:
+ latent_image = comfy.utils.repeat_to_batch_size(latent_image, latent_format.latent_channels, dim=1)
+ if downscale_ratio_spacial is not None:
+ if downscale_ratio_spacial != latent_format.spacial_downscale_ratio:
+ ratio = downscale_ratio_spacial / latent_format.spacial_downscale_ratio
+ latent_image = comfy.utils.common_upscale(latent_image, round(latent_image.shape[-1] * ratio), round(latent_image.shape[-2] * ratio), "nearest-exact", crop="disabled")
+
+ if latent_format.latent_dimensions == 3 and latent_image.ndim == 4:
+ latent_image = latent_image.unsqueeze(2)
+
+ if is_empty and downscale_ratio_temporal is not None:
+ if downscale_ratio_temporal != latent_format.temporal_downscale_ratio:
+ ratio = downscale_ratio_temporal / latent_format.temporal_downscale_ratio
+ new_t = max(1, round(latent_image.shape[2] * ratio))
+ latent_image = comfy.utils.repeat_to_batch_size(latent_image, new_t, dim=2)
+
+ return latent_image
+
+def prepare_sampling(model, noise_shape, positive, negative, noise_mask):
+ logging.warning("Warning: comfy.sample.prepare_sampling isn't used anymore and can be removed")
+ return model, positive, negative, noise_mask, []
+
+def cleanup_additional_models(models):
+ logging.warning("Warning: comfy.sample.cleanup_additional_models isn't used anymore and can be removed")
+
+def sample(model, noise, steps, cfg, sampler_name, scheduler, positive, negative, latent_image, denoise=1.0, disable_noise=False, start_step=None, last_step=None, force_full_denoise=False, noise_mask=None, sigmas=None, callback=None, disable_pbar=False, seed=None):
+ sampler = comfy.samplers.KSampler(model, steps=steps, device=model.load_device, sampler=sampler_name, scheduler=scheduler, denoise=denoise, model_options=model.model_options)
+
+ samples = sampler.sample(noise, positive, negative, cfg=cfg, latent_image=latent_image, start_step=start_step, last_step=last_step, force_full_denoise=force_full_denoise, denoise_mask=noise_mask, sigmas=sigmas, callback=callback, disable_pbar=disable_pbar, seed=seed)
+ samples = samples.to(device=comfy.model_management.intermediate_device(), dtype=comfy.model_management.intermediate_dtype())
+ return samples
+
+def sample_custom(model, noise, cfg, sampler, sigmas, positive, negative, latent_image, noise_mask=None, callback=None, disable_pbar=False, seed=None):
+ samples = comfy.samplers.sample(model, noise, positive, negative, cfg, model.load_device, sampler, sigmas, model_options=model.model_options, latent_image=latent_image, denoise_mask=noise_mask, callback=callback, disable_pbar=disable_pbar, seed=seed)
+ samples = samples.to(device=comfy.model_management.intermediate_device(), dtype=comfy.model_management.intermediate_dtype())
+ return samples
diff --git a/ComfyUI/comfy/sampler_helpers.py b/ComfyUI/comfy/sampler_helpers.py
new file mode 100644
index 0000000000000000000000000000000000000000..bdce2f2d85a5ffaae59f1f6fc715bd44e47d5853
--- /dev/null
+++ b/ComfyUI/comfy/sampler_helpers.py
@@ -0,0 +1,262 @@
+from __future__ import annotations
+import torch
+import uuid
+import math
+import collections
+import comfy.model_management
+import comfy.conds
+import comfy.model_patcher
+import comfy.utils
+import comfy.hooks
+import comfy.patcher_extension
+from typing import TYPE_CHECKING
+if TYPE_CHECKING:
+ from comfy.model_base import BaseModel
+ from comfy.model_patcher import ModelPatcher
+ from comfy.controlnet import ControlBase
+
+def prepare_mask(noise_mask, shape, device):
+ return comfy.utils.reshape_mask(noise_mask, shape).to(device)
+
+def get_models_from_cond(cond, model_type):
+ models = []
+ for c in cond:
+ if model_type in c:
+ if isinstance(c[model_type], list):
+ models += c[model_type]
+ else:
+ models += [c[model_type]]
+ return models
+
+def get_hooks_from_cond(cond, full_hooks: comfy.hooks.HookGroup):
+ # get hooks from conds, and collect cnets so they can be checked for extra_hooks
+ cnets: list[ControlBase] = []
+ for c in cond:
+ if 'hooks' in c:
+ for hook in c['hooks'].hooks:
+ full_hooks.add(hook)
+ if 'control' in c:
+ cnets.append(c['control'])
+
+ def get_extra_hooks_from_cnet(cnet: ControlBase, _list: list):
+ if cnet.extra_hooks is not None:
+ _list.append(cnet.extra_hooks)
+ if cnet.previous_controlnet is None:
+ return _list
+ return get_extra_hooks_from_cnet(cnet.previous_controlnet, _list)
+
+ hooks_list = []
+ cnets = set(cnets)
+ for base_cnet in cnets:
+ get_extra_hooks_from_cnet(base_cnet, hooks_list)
+ extra_hooks = comfy.hooks.HookGroup.combine_all_hooks(hooks_list)
+ if extra_hooks is not None:
+ for hook in extra_hooks.hooks:
+ full_hooks.add(hook)
+
+ return full_hooks
+
+def convert_cond(cond):
+ out = []
+ for c in cond:
+ temp = c[1].copy()
+ model_conds = temp.get("model_conds", {})
+ if c[0] is not None:
+ temp["cross_attn"] = c[0]
+ temp["model_conds"] = model_conds
+ temp["uuid"] = uuid.uuid4()
+ out.append(temp)
+ return out
+
+def cond_has_hooks(cond):
+ for c in cond:
+ temp = c[1]
+ if "hooks" in temp:
+ return True
+ if "control" in temp:
+ control = temp["control"]
+ extra_hooks = control.get_extra_hooks()
+ if len(extra_hooks) > 0:
+ return True
+ return False
+
+def get_additional_models(conds, dtype):
+ """loads additional models in conditioning"""
+ cnets: list[ControlBase] = []
+ gligen = []
+ add_models = []
+
+ for k in conds:
+ cnets += get_models_from_cond(conds[k], "control")
+ gligen += get_models_from_cond(conds[k], "gligen")
+ add_models += get_models_from_cond(conds[k], "additional_models")
+
+ # Order-preserving dedup. A plain set() would randomize iteration order across runs
+ control_nets = list(dict.fromkeys(cnets))
+
+ inference_memory = 0
+ control_models = []
+ for m in control_nets:
+ control_models += m.get_models()
+ inference_memory += m.inference_memory_requirements(dtype)
+
+ gligen = [x[1] for x in gligen]
+ models = control_models + gligen + add_models
+
+ return models, inference_memory
+
+def get_additional_models_from_model_options(model_options: dict[str]=None):
+ """loads additional models from registered AddModels hooks"""
+ models = []
+ if model_options is not None and "registered_hooks" in model_options:
+ registered: comfy.hooks.HookGroup = model_options["registered_hooks"]
+ for hook in registered.get_type(comfy.hooks.EnumHookType.AdditionalModels):
+ hook: comfy.hooks.AdditionalModelsHook
+ models.extend(hook.models)
+ return models
+
+def cleanup_additional_models(models):
+ """cleanup additional models that were loaded"""
+ for m in models:
+ if hasattr(m, 'cleanup'):
+ m.cleanup()
+
+def preprocess_multigpu_conds(conds: dict[str, list[dict[str]]], model: ModelPatcher, model_options: dict[str]):
+ '''If multigpu acceleration required, creates deepclones of ControlNets and GLIGEN per device.'''
+ multigpu_models: list[ModelPatcher] = model.get_additional_models_with_key("multigpu")
+ if len(multigpu_models) == 0:
+ return
+ extra_devices = [x.load_device for x in multigpu_models]
+ # handle controlnets
+ controlnets: set[ControlBase] = set()
+ for k in conds:
+ for kk in conds[k]:
+ if 'control' in kk:
+ controlnets.add(kk['control'])
+ if len(controlnets) > 0:
+ # first, unload all controlnet clones
+ for cnet in list(controlnets):
+ cnet_models = cnet.get_models()
+ for cm in cnet_models:
+ comfy.model_management.unload_model_and_clones(cm, unload_additional_models=True)
+
+ # next, make sure each controlnet has a deepclone for all relevant devices
+ for cnet in controlnets:
+ curr_cnet = cnet
+ while curr_cnet is not None:
+ for device in extra_devices:
+ if device not in curr_cnet.multigpu_clones:
+ curr_cnet.deepclone_multigpu(device, autoregister=True)
+ curr_cnet = curr_cnet.previous_controlnet
+ # since all device clones are now present, recreate the linked list for cloned cnets per device
+ for cnet in controlnets:
+ curr_cnet = cnet
+ while curr_cnet is not None:
+ prev_cnet = curr_cnet.previous_controlnet
+ for device in extra_devices:
+ device_cnet = curr_cnet.get_instance_for_device(device)
+ prev_device_cnet = None
+ if prev_cnet is not None:
+ prev_device_cnet = prev_cnet.get_instance_for_device(device)
+ device_cnet.set_previous_controlnet(prev_device_cnet)
+ curr_cnet = prev_cnet
+ # potentially handle gligen - since not widely used, ignored for now
+
+def estimate_memory(model, noise_shape, conds):
+ cond_shapes = collections.defaultdict(list)
+ cond_shapes_min = {}
+ for _, cs in conds.items():
+ for cond in cs:
+ for k, v in model.model.extra_conds_shapes(**cond).items():
+ cond_shapes[k].append(v)
+ if cond_shapes_min.get(k, None) is None:
+ cond_shapes_min[k] = [v]
+ elif math.prod(v) > math.prod(cond_shapes_min[k][0]):
+ cond_shapes_min[k] = [v]
+
+ memory_required = model.model.memory_required([noise_shape[0] * 2] + list(noise_shape[1:]), cond_shapes=cond_shapes)
+ minimum_memory_required = model.model.memory_required([noise_shape[0]] + list(noise_shape[1:]), cond_shapes=cond_shapes_min)
+ return memory_required, minimum_memory_required
+
+def prepare_sampling(model: ModelPatcher, noise_shape, conds, model_options=None, force_full_load=False, force_offload=False):
+ executor = comfy.patcher_extension.WrapperExecutor.new_executor(
+ _prepare_sampling,
+ comfy.patcher_extension.get_all_wrappers(comfy.patcher_extension.WrappersMP.PREPARE_SAMPLING, model_options, is_model_options=True)
+ )
+ return executor.execute(model, noise_shape, conds, model_options=model_options, force_full_load=force_full_load, force_offload=force_offload)
+
+def _prepare_sampling(model: ModelPatcher, noise_shape, conds, model_options=None, force_full_load=False, force_offload=False):
+ model.match_multigpu_clones()
+ preprocess_multigpu_conds(conds, model, model_options)
+ models, inference_memory = get_additional_models(conds, model.model_dtype())
+ models += get_additional_models_from_model_options(model_options)
+ models += model.get_nested_additional_models() # TODO: does this require inference_memory update?
+ if force_offload: # In training + offload enabled, we want to force prepare sampling to trigger partial load
+ memory_required = 1e20
+ minimum_memory_required = None
+ else:
+ memory_required, minimum_memory_required = estimate_memory(model, noise_shape, conds)
+ memory_required += inference_memory
+ minimum_memory_required += inference_memory
+ comfy.model_management.load_models_gpu([model] + models, memory_required=memory_required, minimum_memory_required=minimum_memory_required, force_full_load=force_full_load)
+ real_model: BaseModel = model.model
+
+ return real_model, conds, models
+
+def cleanup_models(conds, models):
+ cleanup_additional_models(models)
+
+ control_cleanup = []
+ for k in conds:
+ control_cleanup += get_models_from_cond(conds[k], "control")
+
+ cleanup_additional_models(set(control_cleanup))
+
+def prepare_model_patcher(model: ModelPatcher, conds, model_options: dict):
+ '''
+ Registers hooks from conds.
+ '''
+ # check for hooks in conds - if not registered, see if can be applied
+ hooks = comfy.hooks.HookGroup()
+ for k in conds:
+ get_hooks_from_cond(conds[k], hooks)
+ # add wrappers and callbacks from ModelPatcher to transformer_options
+ comfy.patcher_extension.merge_nested_dicts(model_options["transformer_options"].setdefault("wrappers", {}), model.wrappers, copy_dict1=False)
+ comfy.patcher_extension.merge_nested_dicts(model_options["transformer_options"].setdefault("callbacks", {}), model.callbacks, copy_dict1=False)
+ # begin registering hooks
+ registered = comfy.hooks.HookGroup()
+ target_dict = comfy.hooks.create_target_dict(comfy.hooks.EnumWeightTarget.Model)
+ # handle all TransformerOptionsHooks
+ for hook in hooks.get_type(comfy.hooks.EnumHookType.TransformerOptions):
+ hook: comfy.hooks.TransformerOptionsHook
+ hook.add_hook_patches(model, model_options, target_dict, registered)
+ # handle all AddModelsHooks
+ for hook in hooks.get_type(comfy.hooks.EnumHookType.AdditionalModels):
+ hook: comfy.hooks.AdditionalModelsHook
+ hook.add_hook_patches(model, model_options, target_dict, registered)
+ # handle all WeightHooks by registering on ModelPatcher
+ model.register_all_hook_patches(hooks, target_dict, model_options, registered)
+ # add registered_hooks onto model_options for further reference
+ if len(registered) > 0:
+ model_options["registered_hooks"] = registered
+ # merge original wrappers and callbacks with hooked wrappers and callbacks
+ to_load_options: dict[str] = model_options.setdefault("to_load_options", {})
+ for wc_name in ["wrappers", "callbacks"]:
+ comfy.patcher_extension.merge_nested_dicts(to_load_options.setdefault(wc_name, {}), model_options["transformer_options"][wc_name],
+ copy_dict1=False)
+ return to_load_options
+
+def prepare_model_patcher_multigpu_clones(model_patcher: ModelPatcher, loaded_models: list[ModelPatcher], model_options: dict):
+ '''
+ In case multigpu acceleration is enabled, prep ModelPatchers for each device.
+ '''
+ multigpu_patchers: list[ModelPatcher] = [x for x in loaded_models if x.is_multigpu_base_clone]
+ if len(multigpu_patchers) > 0:
+ multigpu_dict: dict[torch.device, ModelPatcher] = {}
+ multigpu_dict[model_patcher.load_device] = model_patcher
+ for x in multigpu_patchers:
+ x.hook_patches = comfy.model_patcher.create_hook_patches_clone(model_patcher.hook_patches, copy_tuples=True)
+ x.hook_mode = model_patcher.hook_mode # match main model's hook_mode
+ multigpu_dict[x.load_device] = x
+ model_options["multigpu_clones"] = multigpu_dict
+ return multigpu_patchers
diff --git a/ComfyUI/comfy/samplers.py b/ComfyUI/comfy/samplers.py
new file mode 100644
index 0000000000000000000000000000000000000000..a280f3bb69fc6302802a6504f282965642a92a48
--- /dev/null
+++ b/ComfyUI/comfy/samplers.py
@@ -0,0 +1,1461 @@
+from __future__ import annotations
+
+import comfy.model_management
+from .k_diffusion import sampling as k_diffusion_sampling
+from .extra_samplers import uni_pc
+from typing import TYPE_CHECKING, Callable, NamedTuple, Any
+if TYPE_CHECKING:
+ from comfy.model_patcher import ModelPatcher
+ from comfy.model_base import BaseModel
+ from comfy.controlnet import ControlBase
+import torch
+from functools import partial
+import collections
+import math
+import logging
+import comfy.sampler_helpers
+import comfy.model_patcher
+import comfy.patcher_extension
+import comfy.hooks
+import comfy.context_windows
+import comfy.multigpu
+import comfy.utils
+from comfy.internal_logging import detail
+import scipy.stats
+import numpy
+
+
+def add_area_dims(area, num_dims):
+ while (len(area) // 2) < num_dims:
+ area = [2147483648] + area[:len(area) // 2] + [0] + area[len(area) // 2:]
+ return area
+
+def get_area_and_mult(conds, x_in, timestep_in):
+ dims = tuple(x_in.shape[2:])
+ area = None
+ strength = 1.0
+
+ if 'timestep_start' in conds:
+ timestep_start = conds['timestep_start']
+ if timestep_in[0] > timestep_start:
+ return None
+ if 'timestep_end' in conds:
+ timestep_end = conds['timestep_end']
+ if timestep_in[0] < timestep_end:
+ return None
+ if 'area' in conds:
+ area = list(conds['area'])
+ area = add_area_dims(area, len(dims))
+ if (len(area) // 2) > len(dims):
+ area = area[:len(dims)] + area[len(area) // 2:(len(area) // 2) + len(dims)]
+
+ if 'strength' in conds:
+ strength = conds['strength']
+
+ input_x = x_in
+ if area is not None:
+ for i in range(len(dims)):
+ area[i] = min(input_x.shape[i + 2] - area[len(dims) + i], area[i])
+ input_x = input_x.narrow(i + 2, area[len(dims) + i], area[i])
+
+ if 'mask' in conds:
+ # Scale the mask to the size of the input
+ # The mask should have been resized as we began the sampling process
+ mask_strength = 1.0
+ if "mask_strength" in conds:
+ mask_strength = conds["mask_strength"]
+ mask = conds['mask']
+ # assert (mask.shape[1:] == x_in.shape[2:])
+
+ mask = mask[:input_x.shape[0]]
+ if area is not None:
+ for i in range(len(dims)):
+ mask = mask.narrow(i + 1, area[len(dims) + i], area[i])
+
+ mask = mask * mask_strength
+ mask = mask.unsqueeze(1).repeat((input_x.shape[0] // mask.shape[0], input_x.shape[1]) + (1, ) * (mask.ndim - 1))
+ else:
+ mask = torch.ones_like(input_x)
+ mult = mask * strength
+
+ if 'mask' not in conds and area is not None:
+ fuzz = 8
+ for i in range(len(dims)):
+ rr = min(fuzz, mult.shape[2 + i] // 4)
+ if area[len(dims) + i] != 0:
+ for t in range(rr):
+ m = mult.narrow(i + 2, t, 1)
+ m *= ((1.0 / rr) * (t + 1))
+ if (area[i] + area[len(dims) + i]) < x_in.shape[i + 2]:
+ for t in range(rr):
+ m = mult.narrow(i + 2, area[i] - 1 - t, 1)
+ m *= ((1.0 / rr) * (t + 1))
+
+ conditioning = {}
+ model_conds = conds["model_conds"]
+ for c in model_conds:
+ conditioning[c] = model_conds[c].process_cond(batch_size=x_in.shape[0], area=area)
+
+ hooks = conds.get('hooks', None)
+ control = conds.get('control', None)
+
+ patches = None
+ if 'gligen' in conds:
+ gligen = conds['gligen']
+ patches = {}
+ gligen_type = gligen[0]
+ gligen_model = gligen[1]
+ if gligen_type == "position":
+ gligen_patch = gligen_model.model.set_position(input_x.shape, gligen[2], input_x.device)
+ else:
+ gligen_patch = gligen_model.model.set_empty(input_x.shape, input_x.device)
+
+ patches['middle_patch'] = [gligen_patch]
+
+ cond_obj = collections.namedtuple('cond_obj', ['input_x', 'mult', 'conditioning', 'area', 'control', 'patches', 'uuid', 'hooks'])
+ return cond_obj(input_x, mult, conditioning, area, control, patches, conds['uuid'], hooks)
+
+def cond_equal_size(c1, c2):
+ if c1 is c2:
+ return True
+ if c1.keys() != c2.keys():
+ return False
+ for k in c1:
+ if not c1[k].can_concat(c2[k]):
+ return False
+ return True
+
+def can_concat_cond(c1, c2):
+ if c1.input_x.shape != c2.input_x.shape:
+ return False
+
+ def objects_concatable(obj1, obj2):
+ if (obj1 is None) != (obj2 is None):
+ return False
+ if obj1 is not None:
+ if obj1 is not obj2:
+ return False
+ return True
+
+ if not objects_concatable(c1.control, c2.control):
+ return False
+
+ if not objects_concatable(c1.patches, c2.patches):
+ return False
+
+ return cond_equal_size(c1.conditioning, c2.conditioning)
+
+def cond_cat(c_list, device=None):
+ temp = {}
+ for x in c_list:
+ for k in x:
+ cur = temp.get(k, [])
+ cur.append(x[k])
+ temp[k] = cur
+
+ out = {}
+ for k in temp:
+ conds = temp[k]
+ out[k] = conds[0].concat(conds[1:])
+ if device is not None and hasattr(out[k], 'to'):
+ out[k] = out[k].to(device)
+
+ return out
+
+def finalize_default_conds(model: 'BaseModel', hooked_to_run: dict[comfy.hooks.HookGroup,list[tuple[tuple,int]]], default_conds: list[list[dict]], x_in, timestep, model_options):
+ # need to figure out remaining unmasked area for conds
+ default_mults = []
+ for _ in default_conds:
+ default_mults.append(torch.ones_like(x_in))
+ # look through each finalized cond in hooked_to_run for 'mult' and subtract it from each cond
+ for lora_hooks, to_run in hooked_to_run.items():
+ for cond_obj, i in to_run:
+ # if no default_cond for cond_type, do nothing
+ if len(default_conds[i]) == 0:
+ continue
+ area: list[int] = cond_obj.area
+ if area is not None:
+ curr_default_mult: torch.Tensor = default_mults[i]
+ dims = len(area) // 2
+ for i in range(dims):
+ curr_default_mult = curr_default_mult.narrow(i + 2, area[i + dims], area[i])
+ curr_default_mult -= cond_obj.mult
+ else:
+ default_mults[i] -= cond_obj.mult
+ # for each default_mult, ReLU to make negatives=0, and then check for any nonzeros
+ for i, mult in enumerate(default_mults):
+ # if no default_cond for cond type, do nothing
+ if len(default_conds[i]) == 0:
+ continue
+ torch.nn.functional.relu(mult, inplace=True)
+ # if mult is all zeros, then don't add default_cond
+ if torch.max(mult) == 0.0:
+ continue
+
+ cond = default_conds[i]
+ for x in cond:
+ # do get_area_and_mult to get all the expected values
+ p = get_area_and_mult(x, x_in, timestep)
+ if p is None:
+ continue
+ # replace p's mult with calculated mult
+ p = p._replace(mult=mult)
+ if p.hooks is not None:
+ model.current_patcher.prepare_hook_patches_current_keyframe(timestep, p.hooks, model_options)
+ hooked_to_run.setdefault(p.hooks, list())
+ hooked_to_run[p.hooks] += [(p, i)]
+
+def calc_cond_batch(model: BaseModel, conds: list[list[dict]], x_in: torch.Tensor, timestep, model_options: dict[str]):
+ handler: comfy.context_windows.ContextHandlerABC = model_options.get("context_handler", None)
+ if handler is None or not handler.should_use_context(model, conds, x_in, timestep, model_options):
+ return _calc_cond_batch_outer(model, conds, x_in, timestep, model_options)
+ return handler.execute(_calc_cond_batch_outer, model, conds, x_in, timestep, model_options)
+
+def _calc_cond_batch_outer(model: BaseModel, conds: list[list[dict]], x_in: torch.Tensor, timestep, model_options):
+ executor = comfy.patcher_extension.WrapperExecutor.new_executor(
+ _calc_cond_batch,
+ comfy.patcher_extension.get_all_wrappers(comfy.patcher_extension.WrappersMP.CALC_COND_BATCH, model_options, is_model_options=True)
+ )
+ return executor.execute(model, conds, x_in, timestep, model_options)
+
+def _calc_cond_batch(model: BaseModel, conds: list[list[dict]], x_in: torch.Tensor, timestep: torch.Tensor, model_options: dict[str]):
+ # NOTE: keep in sync with _calc_cond_batch_multigpu below. Shared logic
+ # (hooked_to_run accumulation, memory-fit batching, per-chunk output
+ # aggregation) is duplicated there with per-device scheduling layered on top.
+ if 'multigpu_clones' in model_options:
+ return _calc_cond_batch_multigpu(model, conds, x_in, timestep, model_options)
+ out_conds = []
+ out_counts = []
+ # separate conds by matching hooks
+ hooked_to_run: dict[comfy.hooks.HookGroup,list[tuple[tuple,int]]] = {}
+ default_conds = []
+ has_default_conds = False
+
+ for i in range(len(conds)):
+ out_conds.append(torch.zeros_like(x_in))
+ out_counts.append(torch.ones_like(x_in) * 1e-37)
+
+ cond = conds[i]
+ default_c = []
+ if cond is not None:
+ for x in cond:
+ if 'default' in x:
+ default_c.append(x)
+ has_default_conds = True
+ continue
+ p = get_area_and_mult(x, x_in, timestep)
+ if p is None:
+ continue
+ if p.hooks is not None:
+ model.current_patcher.prepare_hook_patches_current_keyframe(timestep, p.hooks, model_options)
+ hooked_to_run.setdefault(p.hooks, list())
+ hooked_to_run[p.hooks] += [(p, i)]
+ default_conds.append(default_c)
+
+ if has_default_conds:
+ finalize_default_conds(model, hooked_to_run, default_conds, x_in, timestep, model_options)
+
+ model.current_patcher.prepare_state(timestep, model_options)
+
+ # run every hooked_to_run separately
+ for hooks, to_run in hooked_to_run.items():
+ while len(to_run) > 0:
+ first = to_run[0]
+ first_shape = first[0][0].shape
+ to_batch_temp = []
+ for x in range(len(to_run)):
+ if can_concat_cond(to_run[x][0], first[0]):
+ to_batch_temp += [x]
+
+ to_batch_temp.reverse()
+ to_batch = to_batch_temp[:1]
+
+ free_memory = model.current_patcher.get_free_memory(x_in.device)
+ for i in range(1, len(to_batch_temp) + 1):
+ batch_amount = to_batch_temp[:len(to_batch_temp)//i]
+ input_shape = [len(batch_amount) * first_shape[0]] + list(first_shape)[1:]
+ cond_shapes = collections.defaultdict(list)
+ for tt in batch_amount:
+ for k, v in to_run[tt][0].conditioning.items():
+ cond_shapes[k].append(v.size())
+
+ if model.memory_required(input_shape, cond_shapes=cond_shapes) * 1.5 < free_memory:
+ to_batch = batch_amount
+ break
+
+ input_x = []
+ mult = []
+ c = []
+ cond_or_uncond = []
+ uuids = []
+ area = []
+ control = None
+ patches = None
+ for x in to_batch:
+ o = to_run.pop(x)
+ p = o[0]
+ input_x.append(p.input_x)
+ mult.append(p.mult)
+ c.append(p.conditioning)
+ area.append(p.area)
+ cond_or_uncond.append(o[1])
+ uuids.append(p.uuid)
+ control = p.control
+ patches = p.patches
+
+ batch_chunks = len(cond_or_uncond)
+ input_x = torch.cat(input_x)
+ c = cond_cat(c)
+ timestep_ = torch.cat([timestep] * batch_chunks)
+
+ transformer_options = model.current_patcher.apply_hooks(hooks=hooks)
+ if 'transformer_options' in model_options:
+ transformer_options = comfy.patcher_extension.merge_nested_dicts(transformer_options,
+ model_options['transformer_options'],
+ copy_dict1=False)
+
+ if patches is not None:
+ transformer_options["patches"] = comfy.patcher_extension.merge_nested_dicts(
+ transformer_options.get("patches", {}),
+ patches
+ )
+
+ transformer_options["cond_or_uncond"] = cond_or_uncond[:]
+ transformer_options["uuids"] = uuids[:]
+ transformer_options["sigmas"] = timestep
+
+ c['transformer_options'] = transformer_options
+
+ if control is not None:
+ c['control'] = control.get_control(input_x, timestep_, c, len(cond_or_uncond), transformer_options)
+
+ if 'model_function_wrapper' in model_options:
+ output = model_options['model_function_wrapper'](model.apply_model, {"input": input_x, "timestep": timestep_, "c": c, "cond_or_uncond": cond_or_uncond}).chunk(batch_chunks)
+ else:
+ output = model.apply_model(input_x, timestep_, **c).chunk(batch_chunks)
+
+ for o in range(batch_chunks):
+ cond_index = cond_or_uncond[o]
+ a = area[o]
+ if a is None:
+ out_conds[cond_index] += output[o] * mult[o]
+ out_counts[cond_index] += mult[o]
+ else:
+ out_c = out_conds[cond_index]
+ out_cts = out_counts[cond_index]
+ dims = len(a) // 2
+ for i in range(dims):
+ out_c = out_c.narrow(i + 2, a[i + dims], a[i])
+ out_cts = out_cts.narrow(i + 2, a[i + dims], a[i])
+ out_c += output[o] * mult[o]
+ out_cts += mult[o]
+
+ for i in range(len(out_conds)):
+ out_conds[i] /= out_counts[i]
+
+ return out_conds
+
+def _calc_cond_batch_multigpu(model: BaseModel, conds: list[list[dict]], x_in: torch.Tensor, timestep: torch.Tensor, model_options: dict[str]):
+ # NOTE: keep in sync with _calc_cond_batch above. Same conds-by-hooks
+ # accumulation, memory-fit batching, and output aggregation, but adds a
+ # per-device scheduler, per-device patcher/control lookup, tensor .to(device)
+ # placement, and MultiGPUThreadPool dispatch around the inner loop.
+ out_conds = []
+ out_counts = []
+ # separate conds by matching hooks
+ hooked_to_run: dict[comfy.hooks.HookGroup,list[tuple[tuple,int]]] = {}
+ default_conds = []
+ has_default_conds = False
+
+ output_device = x_in.device
+
+ for i in range(len(conds)):
+ out_conds.append(torch.zeros_like(x_in))
+ out_counts.append(torch.ones_like(x_in) * 1e-37)
+
+ cond = conds[i]
+ default_c = []
+ if cond is not None:
+ for x in cond:
+ if 'default' in x:
+ default_c.append(x)
+ has_default_conds = True
+ continue
+ p = get_area_and_mult(x, x_in, timestep)
+ if p is None:
+ continue
+ if p.hooks is not None:
+ model.current_patcher.prepare_hook_patches_current_keyframe(timestep, p.hooks, model_options)
+ hooked_to_run.setdefault(p.hooks, list())
+ hooked_to_run[p.hooks] += [(p, i)]
+ default_conds.append(default_c)
+
+ if has_default_conds:
+ finalize_default_conds(model, hooked_to_run, default_conds, x_in, timestep, model_options)
+
+ model.current_patcher.prepare_state(timestep, model_options)
+
+ devices = list(model_options['multigpu_clones'].keys())
+ device_batched_hooked_to_run: dict[torch.device, list[tuple[comfy.hooks.HookGroup, tuple]]] = {}
+ # Track conds currently scheduled per device; single source of truth for capacity checks.
+ device_load: dict[torch.device, int] = {d: 0 for d in devices}
+
+ total_conds = sum(len(to_run) for to_run in hooked_to_run.values())
+ conds_per_device = max(1, math.ceil(total_conds / len(devices)))
+
+ def next_available_device(start: int) -> tuple[int, torch.device]:
+ """Return (index, device) for the next device with remaining capacity, starting at `start`.
+
+ Scans at most len(devices) positions, so this always terminates. Raises if no device
+ has remaining capacity, which would indicate a bug in conds_per_device accounting.
+ """
+ for offset in range(len(devices)):
+ i = (start + offset) % len(devices)
+ if device_load[devices[i]] < conds_per_device:
+ return i, devices[i]
+ raise RuntimeError(
+ f"MultiGPU scheduler: all {len(devices)} devices at capacity "
+ f"({conds_per_device}) but conds remain to schedule"
+ )
+
+ # run every hooked_to_run separately
+ index_device = 0
+ for hooks, to_run in hooked_to_run.items():
+ while len(to_run) > 0:
+ index_device, current_device = next_available_device(index_device)
+ remaining_capacity = conds_per_device - device_load[current_device]
+
+ first = to_run[0]
+ first_shape = first[0][0].shape
+ # collect candidate indices that can be concatenated with `first`, up to remaining capacity
+ to_batch_temp = []
+ for x in range(len(to_run)):
+ if can_concat_cond(to_run[x][0], first[0]) and len(to_batch_temp) < remaining_capacity:
+ to_batch_temp += [x]
+
+ to_batch_temp.reverse()
+ to_batch = to_batch_temp[:1]
+
+ free_memory = comfy.model_management.get_free_memory(current_device)
+ for i in range(1, len(to_batch_temp) + 1):
+ batch_amount = to_batch_temp[:len(to_batch_temp)//i]
+ input_shape = [len(batch_amount) * first_shape[0]] + list(first_shape)[1:]
+ cond_shapes = collections.defaultdict(list)
+ for tt in batch_amount:
+ for k, v in to_run[tt][0].conditioning.items():
+ cond_shapes[k].append(v.size())
+ if model.memory_required(input_shape, cond_shapes=cond_shapes) * 1.5 < free_memory:
+ to_batch = batch_amount
+ break
+
+ conds_to_batch = [to_run.pop(x) for x in to_batch]
+ device_load[current_device] += len(conds_to_batch)
+ device_batched_hooked_to_run.setdefault(current_device, []).append((hooks, conds_to_batch))
+
+ if device_load[current_device] >= conds_per_device:
+ index_device += 1
+
+ class thread_result(NamedTuple):
+ output: Any
+ mult: Any
+ area: Any
+ batch_chunks: int
+ cond_or_uncond: Any
+ error: Exception = None
+
+ def _handle_batch(device: torch.device, batch_tuple: tuple[comfy.hooks.HookGroup, tuple], results: list[thread_result]):
+ try:
+ comfy.model_management.set_torch_device(device)
+ model_current: BaseModel = model_options["multigpu_clones"][device].model
+ # run every hooked_to_run separately
+ with torch.no_grad():
+ for hooks, to_batch in batch_tuple:
+ input_x = []
+ mult = []
+ c = []
+ cond_or_uncond = []
+ uuids = []
+ area = []
+ control: ControlBase = None
+ patches = None
+ for x in to_batch:
+ o = x
+ p = o[0]
+ input_x.append(p.input_x)
+ mult.append(p.mult)
+ c.append(p.conditioning)
+ area.append(p.area)
+ cond_or_uncond.append(o[1])
+ uuids.append(p.uuid)
+ control = p.control
+ patches = p.patches
+
+ batch_chunks = len(cond_or_uncond)
+ input_x = torch.cat(input_x).to(device)
+ c = cond_cat(c, device=device)
+ timestep_ = torch.cat([timestep.to(device)] * batch_chunks)
+
+ transformer_options = model_current.current_patcher.apply_hooks(hooks=hooks)
+ if 'transformer_options' in model_options:
+ transformer_options = comfy.patcher_extension.merge_nested_dicts(transformer_options,
+ model_options['transformer_options'],
+ copy_dict1=False)
+
+ if patches is not None:
+ transformer_options["patches"] = comfy.patcher_extension.merge_nested_dicts(
+ transformer_options.get("patches", {}),
+ patches
+ )
+
+ transformer_options["cond_or_uncond"] = cond_or_uncond[:]
+ transformer_options["uuids"] = uuids[:]
+ transformer_options["sigmas"] = timestep.to(device)
+ transformer_options["sample_sigmas"] = transformer_options["sample_sigmas"].to(device)
+ transformer_options["multigpu_thread_device"] = device
+
+ cast_transformer_options(transformer_options, device=device)
+ c['transformer_options'] = transformer_options
+
+ if control is not None:
+ device_control = control.get_instance_for_device(device)
+ c['control'] = device_control.get_control(input_x, timestep_, c, len(cond_or_uncond), transformer_options)
+
+ if 'model_function_wrapper' in model_options:
+ output = model_options['model_function_wrapper'](model_current.apply_model, {"input": input_x, "timestep": timestep_, "c": c, "cond_or_uncond": cond_or_uncond}).to(output_device).chunk(batch_chunks)
+ else:
+ output = model_current.apply_model(input_x, timestep_, **c).to(output_device).chunk(batch_chunks)
+ # TODO: non-NVIDIA support -- the `.to(output_device)` copies
+ # above are async on CUDA, so the main thread's aggregation
+ # could race with in-flight transfers. CUDA-only QA has not
+ # surfaced this in practice, but before extending multigpu
+ # beyond NVIDIA add a `torch.cuda.synchronize(output_device)`
+ # here (guarded by `output_device.type == "cuda"`).
+ results.append(thread_result(output, mult, area, batch_chunks, cond_or_uncond))
+ except Exception as e:
+ results.append(thread_result(None, None, None, None, None, error=e))
+ raise
+
+
+ def _handle_batch_pooled(device, batch_tuple):
+ worker_results = []
+ _handle_batch(device, batch_tuple, worker_results)
+ return worker_results
+
+ results: list[thread_result] = []
+ thread_pool: comfy.multigpu.MultiGPUThreadPool = model_options.get("multigpu_thread_pool")
+
+ # Submit all GPU work to pool threads
+ pool_devices = []
+ for device, batch_tuple in device_batched_hooked_to_run.items():
+ if thread_pool is not None:
+ thread_pool.submit(device, _handle_batch_pooled, device, batch_tuple)
+ pool_devices.append(device)
+ else:
+ # Fallback: no pool, run everything on main thread
+ _handle_batch(device, batch_tuple, results)
+
+ # Collect results from pool workers
+ for device in pool_devices:
+ worker_results, error = thread_pool.get_result(device)
+ if error is not None:
+ raise error
+ results.extend(worker_results)
+
+ for output, mult, area, batch_chunks, cond_or_uncond, error in results:
+ if error is not None:
+ raise error
+ for o in range(batch_chunks):
+ cond_index = cond_or_uncond[o]
+ a = area[o]
+ if a is None:
+ out_conds[cond_index] += output[o] * mult[o]
+ out_counts[cond_index] += mult[o]
+ else:
+ out_c = out_conds[cond_index]
+ out_cts = out_counts[cond_index]
+ dims = len(a) // 2
+ for i in range(dims):
+ out_c = out_c.narrow(i + 2, a[i + dims], a[i])
+ out_cts = out_cts.narrow(i + 2, a[i + dims], a[i])
+ out_c += output[o] * mult[o]
+ out_cts += mult[o]
+
+ for i in range(len(out_conds)):
+ out_conds[i] /= out_counts[i]
+
+ return out_conds
+
+def calc_cond_uncond_batch(model, cond, uncond, x_in, timestep, model_options): #TODO: remove
+ logging.warning("WARNING: The comfy.samplers.calc_cond_uncond_batch function is deprecated please use the calc_cond_batch one instead.")
+ return tuple(calc_cond_batch(model, [cond, uncond], x_in, timestep, model_options))
+
+def cfg_function(model, cond_pred, uncond_pred, cond_scale, x, timestep, model_options={}, cond=None, uncond=None):
+ if "sampler_cfg_function" in model_options:
+ args = {"cond": x - cond_pred, "uncond": x - uncond_pred, "cond_scale": cond_scale, "timestep": timestep, "input": x, "sigma": timestep,
+ "cond_denoised": cond_pred, "uncond_denoised": uncond_pred, "model": model, "model_options": model_options, "input_cond": cond, "input_uncond": uncond}
+ cfg_result = x - model_options["sampler_cfg_function"](args)
+ else:
+ cfg_result = uncond_pred + (cond_pred - uncond_pred) * cond_scale
+
+ for fn in model_options.get("sampler_post_cfg_function", []):
+ args = {"denoised": cfg_result, "cond": cond, "uncond": uncond, "cond_scale": cond_scale, "model": model, "uncond_denoised": uncond_pred, "cond_denoised": cond_pred,
+ "sigma": timestep, "model_options": model_options, "input": x}
+ cfg_result = fn(args)
+
+ return cfg_result
+
+#The main sampling function shared by all the samplers
+#Returns denoised
+def sampling_function(model, x, timestep, uncond, cond, cond_scale, model_options={}, seed=None):
+ if math.isclose(cond_scale, 1.0) and model_options.get("disable_cfg1_optimization", False) == False:
+ uncond_ = None
+ else:
+ uncond_ = uncond
+
+ conds = [cond, uncond_]
+ if "sampler_calc_cond_batch_function" in model_options:
+ args = {"conds": conds, "input": x, "sigma": timestep, "model": model, "model_options": model_options}
+ out = model_options["sampler_calc_cond_batch_function"](args)
+ else:
+ out = calc_cond_batch(model, conds, x, timestep, model_options)
+
+ for fn in model_options.get("sampler_pre_cfg_function", []):
+ args = {"conds":conds, "conds_out": out, "cond_scale": cond_scale, "timestep": timestep,
+ "input": x, "sigma": timestep, "model": model, "model_options": model_options}
+ out = fn(args)
+
+ return cfg_function(model, out[0], out[1], cond_scale, x, timestep, model_options=model_options, cond=cond, uncond=uncond_)
+
+
+class KSamplerX0Inpaint:
+ def __init__(self, model, sigmas):
+ self.inner_model = model
+ self.sigmas = sigmas
+ def __call__(self, x, sigma, denoise_mask, model_options={}, seed=None):
+ if denoise_mask is not None:
+ if "denoise_mask_function" in model_options:
+ denoise_mask = model_options["denoise_mask_function"](sigma, denoise_mask, extra_options={"model": self.inner_model, "sigmas": self.sigmas})
+ latent_mask = 1. - denoise_mask
+ x = x * denoise_mask + self.inner_model.inner_model.scale_latent_inpaint(x=x, sigma=sigma, noise=self.noise, latent_image=self.latent_image) * latent_mask
+ out = self.inner_model(x, sigma, model_options=model_options, seed=seed)
+ if denoise_mask is not None:
+ out = out * denoise_mask + self.latent_image * latent_mask
+ return out
+
+def simple_scheduler(model_sampling, steps):
+ s = model_sampling
+ sigs = []
+ ss = len(s.sigmas) / steps
+ for x in range(steps):
+ sigs += [float(s.sigmas[-(1 + int(x * ss))])]
+ sigs += [0.0]
+ return torch.FloatTensor(sigs)
+
+def ddim_scheduler(model_sampling, steps):
+ s = model_sampling
+ sigs = []
+ x = 1
+ if math.isclose(float(s.sigmas[x]), 0, abs_tol=0.00001):
+ steps += 1
+ sigs = []
+ else:
+ sigs = [0.0]
+
+ ss = max(len(s.sigmas) // steps, 1)
+ while x < len(s.sigmas):
+ sigs += [float(s.sigmas[x])]
+ x += ss
+ sigs = sigs[::-1]
+ return torch.FloatTensor(sigs)
+
+def normal_scheduler(model_sampling, steps, sgm=False, floor=False):
+ s = model_sampling
+ start = s.timestep(s.sigma_max)
+ end = s.timestep(s.sigma_min)
+
+ append_zero = True
+ if sgm:
+ timesteps = torch.linspace(start, end, steps + 1)[:-1]
+ else:
+ if math.isclose(float(s.sigma(end)), 0, abs_tol=0.00001):
+ steps += 1
+ append_zero = False
+ timesteps = torch.linspace(start, end, steps)
+
+ sigs = []
+ for x in range(len(timesteps)):
+ ts = timesteps[x]
+ sigs.append(float(s.sigma(ts)))
+
+ if append_zero:
+ sigs += [0.0]
+
+ return torch.FloatTensor(sigs)
+
+# Implemented based on: https://arxiv.org/abs/2407.12173
+def beta_scheduler(model_sampling, steps, alpha=0.6, beta=0.6):
+ total_timesteps = (len(model_sampling.sigmas) - 1)
+ ts = 1 - numpy.linspace(0, 1, steps, endpoint=False)
+ ts = numpy.rint(scipy.stats.beta.ppf(ts, alpha, beta) * total_timesteps)
+
+ sigs = []
+ last_t = -1
+ for t in ts:
+ if t != last_t:
+ sigs += [float(model_sampling.sigmas[int(t)])]
+ last_t = t
+ sigs += [0.0]
+ return torch.FloatTensor(sigs)
+
+# from: https://github.com/genmoai/models/blob/main/src/mochi_preview/infer.py#L41
+def linear_quadratic_schedule(model_sampling, steps, threshold_noise=0.025, linear_steps=None):
+ if steps == 1:
+ sigma_schedule = [1.0, 0.0]
+ else:
+ if linear_steps is None:
+ linear_steps = steps // 2
+ linear_sigma_schedule = [i * threshold_noise / linear_steps for i in range(linear_steps)]
+ threshold_noise_step_diff = linear_steps - threshold_noise * steps
+ quadratic_steps = steps - linear_steps
+ quadratic_coef = threshold_noise_step_diff / (linear_steps * quadratic_steps ** 2)
+ linear_coef = threshold_noise / linear_steps - 2 * threshold_noise_step_diff / (quadratic_steps ** 2)
+ const = quadratic_coef * (linear_steps ** 2)
+ quadratic_sigma_schedule = [
+ quadratic_coef * (i ** 2) + linear_coef * i + const
+ for i in range(linear_steps, steps)
+ ]
+ sigma_schedule = linear_sigma_schedule + quadratic_sigma_schedule + [1.0]
+ sigma_schedule = [1.0 - x for x in sigma_schedule]
+ return torch.FloatTensor(sigma_schedule) * model_sampling.sigma_max.cpu()
+
+# Referenced from https://github.com/AUTOMATIC1111/stable-diffusion-webui/pull/15608
+def kl_optimal_scheduler(n: int, sigma_min: float, sigma_max: float) -> torch.Tensor:
+ adj_idxs = torch.arange(n, dtype=torch.float).div_(n - 1)
+ sigmas = adj_idxs.new_zeros(n + 1)
+ sigmas[:-1] = (adj_idxs * math.atan(sigma_min) + (1 - adj_idxs) * math.atan(sigma_max)).tan_()
+ return sigmas
+
+def get_mask_aabb(masks):
+ if masks.numel() == 0:
+ return torch.zeros((0, 4), device=masks.device, dtype=torch.int)
+
+ b = masks.shape[0]
+
+ bounding_boxes = torch.zeros((b, 4), device=masks.device, dtype=torch.int)
+ is_empty = torch.zeros((b), device=masks.device, dtype=torch.bool)
+ for i in range(b):
+ mask = masks[i]
+ if mask.numel() == 0:
+ continue
+ if torch.max(mask != 0) == False:
+ is_empty[i] = True
+ continue
+ y, x = torch.where(mask)
+ bounding_boxes[i, 0] = torch.min(x)
+ bounding_boxes[i, 1] = torch.min(y)
+ bounding_boxes[i, 2] = torch.max(x)
+ bounding_boxes[i, 3] = torch.max(y)
+
+ return bounding_boxes, is_empty
+
+def resolve_areas_and_cond_masks_multidim(conditions, dims, device):
+ # We need to decide on an area outside the sampling loop in order to properly generate opposite areas of equal sizes.
+ # While we're doing this, we can also resolve the mask device and scaling for performance reasons
+ for i in range(len(conditions)):
+ c = conditions[i]
+ if 'area' in c:
+ area = c['area']
+ if area[0] == "percentage":
+ modified = c.copy()
+ a = area[1:]
+ a_len = len(a) // 2
+ area = ()
+ for d in range(len(dims)):
+ area += (max(1, round(a[d] * dims[d])),)
+ for d in range(len(dims)):
+ area += (round(a[d + a_len] * dims[d]),)
+
+ modified['area'] = area
+ c = modified
+ conditions[i] = c
+
+ if 'mask' in c:
+ mask = c['mask']
+ mask = mask.to(device=device)
+ modified = c.copy()
+ if len(mask.shape) == len(dims):
+ mask = mask.unsqueeze(0)
+ if mask.shape[1:] != dims:
+ if mask.ndim < 4:
+ mask = comfy.utils.common_upscale(mask.unsqueeze(1), dims[-1], dims[-2], 'bilinear', 'none').squeeze(1)
+ else:
+ mask = comfy.utils.common_upscale(mask, dims[-1], dims[-2], 'bilinear', 'none')
+
+ if modified.get("set_area_to_bounds", False): #TODO: handle dim != 2
+ bounds = torch.max(torch.abs(mask),dim=0).values.unsqueeze(0)
+ boxes, is_empty = get_mask_aabb(bounds)
+ if is_empty[0]:
+ # Use the minimum possible size for efficiency reasons. (Since the mask is all-0, this becomes a noop anyway)
+ modified['area'] = (8, 8, 0, 0)
+ else:
+ box = boxes[0]
+ H, W, Y, X = (box[3] - box[1] + 1, box[2] - box[0] + 1, box[1], box[0])
+ H = max(8, H)
+ W = max(8, W)
+ area = (int(H), int(W), int(Y), int(X))
+ modified['area'] = area
+
+ modified['mask'] = mask
+ conditions[i] = modified
+
+def resolve_areas_and_cond_masks(conditions, h, w, device):
+ logging.warning("WARNING: The comfy.samplers.resolve_areas_and_cond_masks function is deprecated please use the resolve_areas_and_cond_masks_multidim one instead.")
+ return resolve_areas_and_cond_masks_multidim(conditions, [h, w], device)
+
+def create_cond_with_same_area_if_none(conds, c):
+ if 'area' not in c:
+ return
+
+ def area_inside(a, area_cmp):
+ a = add_area_dims(a, len(area_cmp) // 2)
+ area_cmp = add_area_dims(area_cmp, len(a) // 2)
+
+ a_l = len(a) // 2
+ area_cmp_l = len(area_cmp) // 2
+ for i in range(min(a_l, area_cmp_l)):
+ if a[a_l + i] < area_cmp[area_cmp_l + i]:
+ return False
+ for i in range(min(a_l, area_cmp_l)):
+ if (a[i] + a[a_l + i]) > (area_cmp[i] + area_cmp[area_cmp_l + i]):
+ return False
+ return True
+
+ c_area = c['area']
+ smallest = None
+ for x in conds:
+ if 'area' in x:
+ a = x['area']
+ if area_inside(c_area, a):
+ if smallest is None:
+ smallest = x
+ elif 'area' not in smallest:
+ smallest = x
+ else:
+ if math.prod(smallest['area'][:len(smallest['area']) // 2]) > math.prod(a[:len(a) // 2]):
+ smallest = x
+ else:
+ if smallest is None:
+ smallest = x
+ if smallest is None:
+ return
+ if 'area' in smallest:
+ if smallest['area'] == c_area:
+ return
+
+ out = c.copy()
+ out['model_conds'] = smallest['model_conds'].copy() #TODO: which fields should be copied?
+ conds += [out]
+
+def calculate_start_end_timesteps(model, conds):
+ s = model.model_sampling
+ for t in range(len(conds)):
+ x = conds[t]
+
+ timestep_start = None
+ timestep_end = None
+ # handle clip hook schedule, if needed
+ if 'clip_start_percent' in x:
+ timestep_start = s.percent_to_sigma(max(x['clip_start_percent'], x.get('start_percent', 0.0)))
+ timestep_end = s.percent_to_sigma(min(x['clip_end_percent'], x.get('end_percent', 1.0)))
+ else:
+ if 'start_percent' in x:
+ timestep_start = s.percent_to_sigma(x['start_percent'])
+ if 'end_percent' in x:
+ timestep_end = s.percent_to_sigma(x['end_percent'])
+
+ if (timestep_start is not None) or (timestep_end is not None):
+ n = x.copy()
+ if (timestep_start is not None):
+ n['timestep_start'] = timestep_start
+ if (timestep_end is not None):
+ n['timestep_end'] = timestep_end
+ conds[t] = n
+
+def pre_run_control(model, conds):
+ s = model.model_sampling
+ # Per-device model lookup so multigpu control clones get the matching
+ # diffusion_model (e.g. QwenFunControlNet stashes it into extra_args).
+ device_models: dict = {}
+ patcher = getattr(model, "current_patcher", None)
+ if patcher is not None:
+ for p in patcher.get_additional_models_with_key("multigpu"):
+ device_models[p.load_device] = p.model
+ for t in range(len(conds)):
+ x = conds[t]
+
+ percent_to_timestep_function = lambda a: s.percent_to_sigma(a)
+ if 'control' in x:
+ x['control'].pre_run(model, percent_to_timestep_function)
+ for device, device_cnet in x['control'].multigpu_clones.items():
+ device_cnet.pre_run(device_models.get(device, model), percent_to_timestep_function)
+
+def apply_empty_x_to_equal_area(conds, uncond, name, uncond_fill_func):
+ cond_cnets = []
+ cond_other = []
+ uncond_cnets = []
+ uncond_other = []
+ for t in range(len(conds)):
+ x = conds[t]
+ if 'area' not in x:
+ if name in x and x[name] is not None:
+ cond_cnets.append(x[name])
+ else:
+ cond_other.append((x, t))
+ for t in range(len(uncond)):
+ x = uncond[t]
+ if 'area' not in x:
+ if name in x and x[name] is not None:
+ uncond_cnets.append(x[name])
+ else:
+ uncond_other.append((x, t))
+
+ if len(uncond_cnets) > 0:
+ return
+
+ for x in range(len(cond_cnets)):
+ temp = uncond_other[x % len(uncond_other)]
+ o = temp[0]
+ if name in o and o[name] is not None:
+ n = o.copy()
+ n[name] = uncond_fill_func(cond_cnets, x)
+ uncond += [n]
+ else:
+ n = o.copy()
+ n[name] = uncond_fill_func(cond_cnets, x)
+ uncond[temp[1]] = n
+
+def encode_model_conds(model_function, conds, noise, device, prompt_type, **kwargs):
+ for t in range(len(conds)):
+ x = conds[t]
+ params = x.copy()
+ params["device"] = device
+ params["noise"] = noise
+ default_width = None
+ if len(noise.shape) >= 4: #TODO: 8 multiple should be set by the model
+ default_width = noise.shape[3] * 8
+ params["width"] = params.get("width", default_width)
+ params["height"] = params.get("height", noise.shape[2] * 8)
+ params["prompt_type"] = params.get("prompt_type", prompt_type)
+ for k in kwargs:
+ if k not in params:
+ params[k] = kwargs[k]
+
+ out = model_function(**params)
+ x = x.copy()
+ model_conds = x['model_conds'].copy()
+ for k in out:
+ model_conds[k] = out[k]
+ x['model_conds'] = model_conds
+ conds[t] = x
+ return conds
+
+class Sampler:
+ def sample(self):
+ pass
+
+ def max_denoise(self, model_wrap, sigmas):
+ max_sigma = float(model_wrap.inner_model.model_sampling.sigma_max)
+ sigma = float(sigmas[0])
+ return math.isclose(max_sigma, sigma, rel_tol=1e-05) or sigma > max_sigma
+
+KSAMPLER_NAMES = ["euler", "euler_cfg_pp", "euler_ancestral", "euler_ancestral_cfg_pp", "heun", "heunpp2", "exp_heun_2_x0", "exp_heun_2_x0_sde", "dpm_2", "dpm_2_ancestral",
+ "lms", "dpm_fast", "dpm_adaptive", "dpmpp_2s_ancestral", "dpmpp_2s_ancestral_cfg_pp", "dpmpp_sde", "dpmpp_sde_gpu",
+ "dpmpp_2m", "dpmpp_2m_cfg_pp", "dpmpp_2m_sde", "dpmpp_2m_sde_gpu", "dpmpp_2m_sde_heun", "dpmpp_2m_sde_heun_gpu", "dpmpp_3m_sde", "dpmpp_3m_sde_gpu", "ddpm", "lcm",
+ "ipndm", "ipndm_v", "deis", "res_multistep", "res_multistep_cfg_pp", "res_multistep_ancestral", "res_multistep_ancestral_cfg_pp",
+ "gradient_estimation", "gradient_estimation_cfg_pp", "er_sde", "seeds_2", "seeds_3", "sa_solver", "sa_solver_pece"]
+
+class KSAMPLER(Sampler):
+ def __init__(self, sampler_function, extra_options={}, inpaint_options={}):
+ self.sampler_function = sampler_function
+ self.extra_options = extra_options
+ self.inpaint_options = inpaint_options
+
+ def sample(self, model_wrap, sigmas, extra_args, callback, noise, latent_image=None, denoise_mask=None, disable_pbar=False):
+ extra_args["denoise_mask"] = denoise_mask
+ model_k = KSamplerX0Inpaint(model_wrap, sigmas)
+ model_k.latent_image = latent_image
+ if self.inpaint_options.get("random", False): #TODO: Should this be the default?
+ generator = torch.manual_seed(extra_args.get("seed", 41) + 1)
+ model_k.noise = torch.randn(noise.shape, generator=generator, device="cpu").to(noise.dtype).to(noise.device)
+ else:
+ model_k.noise = noise
+
+ noise = model_wrap.inner_model.model_sampling.noise_scaling(sigmas[0], noise, latent_image, self.max_denoise(model_wrap, sigmas))
+
+ total_steps = len(sigmas) - 1
+ first_step = True
+ def k_callback(x):
+ nonlocal first_step
+ if first_step:
+ detail("First sampler step: model=%s sampler=%s step=%s total_steps=%s cfg=%s seed=%s sigma=%s sigma_hat=%s latent_shape=%s denoised_shape=%s", model_wrap.model_patcher.model.__class__.__name__, getattr(self.sampler_function, "__name__", "unknown"), x["i"], total_steps, model_wrap.cfg, extra_args.get("seed"), x.get("sigma"), x.get("sigma_hat"), tuple(x["x"].shape), tuple(x["denoised"].shape))
+ first_step = False
+ if callback is not None:
+ callback(x["i"], x["denoised"], x["x"], total_steps)
+
+ samples = self.sampler_function(model_k, noise, sigmas, extra_args=extra_args, callback=k_callback, disable=disable_pbar, **self.extra_options)
+ samples = model_wrap.inner_model.model_sampling.inverse_noise_scaling(sigmas[-1], samples)
+ return samples
+
+
+def ksampler(sampler_name, extra_options={}, inpaint_options={}):
+ if sampler_name == "dpm_fast":
+ def dpm_fast_function(model, noise, sigmas, extra_args, callback, disable):
+ if len(sigmas) <= 1:
+ return noise
+
+ sigma_min = sigmas[-1]
+ if sigma_min == 0:
+ sigma_min = sigmas[-2]
+ total_steps = len(sigmas) - 1
+ return k_diffusion_sampling.sample_dpm_fast(model, noise, sigma_min, sigmas[0], total_steps, extra_args=extra_args, callback=callback, disable=disable)
+ sampler_function = dpm_fast_function
+ elif sampler_name == "dpm_adaptive":
+ def dpm_adaptive_function(model, noise, sigmas, extra_args, callback, disable, **extra_options):
+ if len(sigmas) <= 1:
+ return noise
+
+ sigma_min = sigmas[-1]
+ if sigma_min == 0:
+ sigma_min = sigmas[-2]
+ return k_diffusion_sampling.sample_dpm_adaptive(model, noise, sigma_min, sigmas[0], extra_args=extra_args, callback=callback, disable=disable, **extra_options)
+ sampler_function = dpm_adaptive_function
+ else:
+ sampler_function = getattr(k_diffusion_sampling, "sample_{}".format(sampler_name))
+
+ return KSAMPLER(sampler_function, extra_options, inpaint_options)
+
+
+def process_conds(model, noise, conds, device, latent_image=None, denoise_mask=None, seed=None, latent_shapes=None):
+ for k in conds:
+ conds[k] = conds[k][:]
+ resolve_areas_and_cond_masks_multidim(conds[k], noise.shape[2:], device)
+
+ for k in conds:
+ calculate_start_end_timesteps(model, conds[k])
+
+ if hasattr(model, 'extra_conds'):
+ for k in conds:
+ conds[k] = encode_model_conds(model.extra_conds, conds[k], noise, device, k, latent_image=latent_image, denoise_mask=denoise_mask, seed=seed, latent_shapes=latent_shapes)
+
+ #make sure each cond area has an opposite one with the same area
+ for k in conds:
+ for c in conds[k]:
+ for kk in conds:
+ if k != kk:
+ create_cond_with_same_area_if_none(conds[kk], c)
+
+ for k in conds:
+ for c in conds[k]:
+ if 'hooks' in c:
+ for hook in c['hooks'].hooks:
+ hook.initialize_timesteps(model)
+
+ for k in conds:
+ pre_run_control(model, conds[k])
+
+ if "positive" in conds:
+ positive = conds["positive"]
+ for k in conds:
+ if k != "positive":
+ apply_empty_x_to_equal_area(list(filter(lambda c: c.get('control_apply_to_uncond', False) == True, positive)), conds[k], 'control', lambda cond_cnets, x: cond_cnets[x])
+ apply_empty_x_to_equal_area(positive, conds[k], 'gligen', lambda cond_cnets, x: cond_cnets[x])
+
+ return conds
+
+
+def preprocess_conds_hooks(conds: dict[str, list[dict[str]]]):
+ # determine which ControlNets have extra_hooks that should be combined with normal hooks
+ hook_replacement: dict[tuple[ControlBase, comfy.hooks.HookGroup], list[dict]] = {}
+ for k in conds:
+ for kk in conds[k]:
+ if 'control' in kk:
+ control: 'ControlBase' = kk['control']
+ extra_hooks = control.get_extra_hooks()
+ if len(extra_hooks) > 0:
+ hooks: comfy.hooks.HookGroup = kk.get('hooks', None)
+ to_replace = hook_replacement.setdefault((control, hooks), [])
+ to_replace.append(kk)
+ # if nothing to replace, do nothing
+ if len(hook_replacement) == 0:
+ return
+
+ # for optimal sampling performance, common ControlNets + hook combos should have identical hooks
+ # on the cond dicts
+ for key, conds_to_modify in hook_replacement.items():
+ control = key[0]
+ hooks = key[1]
+ hooks = comfy.hooks.HookGroup.combine_all_hooks(control.get_extra_hooks() + [hooks])
+ # if combined hooks are not None, set as new hooks for all relevant conds
+ if hooks is not None:
+ for cond in conds_to_modify:
+ cond['hooks'] = hooks
+
+def filter_registered_hooks_on_conds(conds: dict[str, list[dict[str]]], model_options: dict[str]):
+ '''Modify 'hooks' on conds so that only hooks that were registered remain. Properly accounts for
+ HookGroups that have the same reference.'''
+ registered: comfy.hooks.HookGroup = model_options.get('registered_hooks', None)
+ # if None were registered, make sure all hooks are cleaned from conds
+ if registered is None:
+ for k in conds:
+ for kk in conds[k]:
+ kk.pop('hooks', None)
+ return
+ # find conds that contain hooks to be replaced - group by common HookGroup refs
+ hook_replacement: dict[comfy.hooks.HookGroup, list[dict]] = {}
+ for k in conds:
+ for kk in conds[k]:
+ hooks: comfy.hooks.HookGroup = kk.get('hooks', None)
+ if hooks is not None:
+ if not hooks.is_subset_of(registered):
+ to_replace = hook_replacement.setdefault(hooks, [])
+ to_replace.append(kk)
+ # for each hook to replace, create a new proper HookGroup and assign to all common conds
+ for hooks, conds_to_modify in hook_replacement.items():
+ new_hooks = hooks.new_with_common_hooks(registered)
+ if len(new_hooks) == 0:
+ new_hooks = None
+ for kk in conds_to_modify:
+ kk['hooks'] = new_hooks
+
+
+def get_total_hook_groups_in_conds(conds: dict[str, list[dict[str]]]):
+ hooks_set = set()
+ for k in conds:
+ for kk in conds[k]:
+ hooks_set.add(kk.get('hooks', None))
+ return len(hooks_set)
+
+
+def cast_to_load_options(model_options: dict[str], device=None, dtype=None):
+ '''
+ If any patches from hooks, wrappers, or callbacks have .to to be called, call it.
+ '''
+ if model_options is None:
+ return
+ to_load_options = model_options.get("to_load_options", None)
+ if to_load_options is None:
+ return
+ cast_transformer_options(to_load_options, device, dtype)
+
+def cast_transformer_options(transformer_options: dict[str], device=None, dtype=None):
+ casts = []
+ if device is not None:
+ casts.append(device)
+ if dtype is not None:
+ casts.append(dtype)
+ # if nothing to apply, do nothing
+ if len(casts) == 0:
+ return
+ # try to call .to on patches
+ if "patches" in transformer_options:
+ patches = transformer_options["patches"]
+ for name in patches:
+ patch_list = patches[name]
+ for i in range(len(patch_list)):
+ if hasattr(patch_list[i], "to"):
+ for cast in casts:
+ patch_list[i] = patch_list[i].to(cast)
+ if "patches_replace" in transformer_options:
+ patches = transformer_options["patches_replace"]
+ for name in patches:
+ patch_list = patches[name]
+ for k in patch_list:
+ if hasattr(patch_list[k], "to"):
+ for cast in casts:
+ patch_list[k] = patch_list[k].to(cast)
+ # try to call .to on any wrappers/callbacks
+ wrappers_and_callbacks = ["wrappers", "callbacks"]
+ for wc_name in wrappers_and_callbacks:
+ if wc_name in transformer_options:
+ wc: dict[str, list] = transformer_options[wc_name]
+ for wc_dict in wc.values():
+ for wc_list in wc_dict.values():
+ for i in range(len(wc_list)):
+ if hasattr(wc_list[i], "to"):
+ for cast in casts:
+ wc_list[i] = wc_list[i].to(cast)
+
+class CFGGuider:
+ def __init__(self, model_patcher: ModelPatcher):
+ self.model_patcher = model_patcher
+ self.model_options = model_patcher.model_options
+ self.original_conds = {}
+ self.cfg = 1.0
+
+ def set_conds(self, positive, negative):
+ self.inner_set_conds({"positive": positive, "negative": negative})
+
+ def set_cfg(self, cfg):
+ self.cfg = cfg
+
+ def inner_set_conds(self, conds):
+ for k in conds:
+ if self.model_patcher.is_dynamic() and comfy.sampler_helpers.cond_has_hooks(conds[k]):
+ self.model_patcher = self.model_patcher.get_non_dynamic_delegate()
+ self.original_conds[k] = comfy.sampler_helpers.convert_cond(conds[k])
+
+ def __call__(self, *args, **kwargs):
+ return self.outer_predict_noise(*args, **kwargs)
+
+ def outer_predict_noise(self, x, timestep, model_options={}, seed=None):
+ return comfy.patcher_extension.WrapperExecutor.new_class_executor(
+ self.predict_noise,
+ self,
+ comfy.patcher_extension.get_all_wrappers(comfy.patcher_extension.WrappersMP.PREDICT_NOISE, self.model_options, is_model_options=True)
+ ).execute(x, timestep, model_options, seed)
+
+ def predict_noise(self, x, timestep, model_options={}, seed=None):
+ return sampling_function(self.inner_model, x, timestep, self.conds.get("negative", None), self.conds.get("positive", None), self.cfg, model_options=model_options, seed=seed)
+
+ def inner_sample(self, noise, latent_image, device, sampler, sigmas, denoise_mask, callback, disable_pbar, seed, latent_shapes=None):
+ if latent_image is not None and torch.count_nonzero(latent_image) > 0: #Don't shift the empty latent image.
+ latent_image = self.inner_model.process_latent_in(latent_image)
+
+ self.conds = process_conds(self.inner_model, noise, self.conds, device, latent_image, denoise_mask, seed, latent_shapes=latent_shapes)
+
+ extra_model_options = comfy.model_patcher.create_model_options_clone(self.model_options)
+ extra_model_options.setdefault("transformer_options", {})["sample_sigmas"] = sigmas
+ extra_args = {"model_options": extra_model_options, "seed": seed}
+
+ executor = comfy.patcher_extension.WrapperExecutor.new_class_executor(
+ sampler.sample,
+ sampler,
+ comfy.patcher_extension.get_all_wrappers(comfy.patcher_extension.WrappersMP.SAMPLER_SAMPLE, extra_args["model_options"], is_model_options=True)
+ )
+ samples = executor.execute(self, sigmas, extra_args, callback, noise, latent_image, denoise_mask, disable_pbar)
+ return self.inner_model.process_latent_out(samples.to(torch.float32))
+
+ def outer_sample(self, noise, latent_image, sampler, sigmas, denoise_mask=None, callback=None, disable_pbar=False, seed=None, latent_shapes=None):
+ self.inner_model, self.conds, self.loaded_models = comfy.sampler_helpers.prepare_sampling(self.model_patcher, noise.shape, self.conds, self.model_options)
+ device = self.model_patcher.load_device
+
+ multigpu_patchers = comfy.sampler_helpers.prepare_model_patcher_multigpu_clones(self.model_patcher, self.loaded_models, self.model_options)
+
+ # Create persistent thread pool for all GPU devices (main + extras)
+ if multigpu_patchers:
+ extra_devices = [p.load_device for p in multigpu_patchers]
+ all_devices = [device] + extra_devices
+ self.model_options["multigpu_thread_pool"] = comfy.multigpu.MultiGPUThreadPool(all_devices)
+
+ with comfy.model_management.cuda_device_context(device):
+ try:
+ noise = noise.to(device=device, dtype=torch.float32)
+ latent_image = latent_image.to(device=device, dtype=torch.float32)
+ sigmas = sigmas.to(device)
+ cast_to_load_options(self.model_options, device=device, dtype=self.model_patcher.model_dtype())
+
+ self.model_patcher.pre_run()
+ for multigpu_patcher in multigpu_patchers:
+ multigpu_patcher.pre_run()
+ output = self.inner_sample(noise, latent_image, device, sampler, sigmas, denoise_mask, callback, disable_pbar, seed, latent_shapes=latent_shapes)
+ finally:
+ thread_pool = self.model_options.pop("multigpu_thread_pool", None)
+ if thread_pool is not None:
+ thread_pool.shutdown()
+ self.model_patcher.cleanup()
+ for multigpu_patcher in multigpu_patchers:
+ multigpu_patcher.cleanup()
+
+ comfy.sampler_helpers.cleanup_models(self.conds, self.loaded_models)
+ del self.inner_model
+ del self.loaded_models
+ return output
+
+ def sample(self, noise, latent_image, sampler, sigmas, denoise_mask=None, callback=None, disable_pbar=False, seed=None):
+ if sigmas.shape[-1] == 0:
+ return latent_image
+
+ if latent_image.is_nested:
+ sampler_shapes = [tuple(x.shape) for x in latent_image.unbind()]
+ latent_image, latent_shapes = comfy.utils.pack_latents(latent_image.unbind())
+ noise, _ = comfy.utils.pack_latents(noise.unbind())
+ else:
+ latent_shapes = [latent_image.shape]
+ sampler_shapes = [tuple(latent_image.shape)]
+ detail("Sampler: model=%s latent_shapes=%s", self.model_patcher.model.__class__.__name__, sampler_shapes)
+
+ if len(latent_shapes) > 1 and callback is not None:
+ # samplers run on the flat pack, hand callbacks (previews, x0 output) the nested view
+ packed_callback = callback
+ def callback(step, x0, x, total_steps):
+ x0 = comfy.nested_tensor.NestedTensor(comfy.utils.unpack_latents(x0, latent_shapes))
+ x = comfy.nested_tensor.NestedTensor(comfy.utils.unpack_latents(x, latent_shapes))
+ return packed_callback(step, x0, x, total_steps)
+
+ if denoise_mask is not None:
+ if denoise_mask.is_nested:
+ denoise_masks = denoise_mask.unbind()
+ denoise_masks = denoise_masks[:len(latent_shapes)]
+ else:
+ denoise_masks = [denoise_mask]
+
+ for i in range(len(denoise_masks), len(latent_shapes)):
+ denoise_masks.append(torch.ones(latent_shapes[i]))
+
+ for i in range(len(denoise_masks)):
+ denoise_masks[i] = comfy.sampler_helpers.prepare_mask(denoise_masks[i], latent_shapes[i], self.model_patcher.load_device)
+
+ if len(denoise_masks) > 1:
+ denoise_mask, _ = comfy.utils.pack_latents(denoise_masks)
+ else:
+ denoise_mask = denoise_masks[0]
+ denoise_mask = denoise_mask.float()
+
+ self.conds = {}
+ for k in self.original_conds:
+ self.conds[k] = list(map(lambda a: a.copy(), self.original_conds[k]))
+ preprocess_conds_hooks(self.conds)
+
+ try:
+ orig_model_options = self.model_options
+ self.model_options = comfy.model_patcher.create_model_options_clone(self.model_options)
+ # if one hook type (or just None), then don't bother caching weights for hooks (will never change after first step)
+ orig_hook_mode = self.model_patcher.hook_mode
+ if get_total_hook_groups_in_conds(self.conds) <= 1:
+ self.model_patcher.hook_mode = comfy.hooks.EnumHookMode.MinVram
+ comfy.sampler_helpers.prepare_model_patcher(self.model_patcher, self.conds, self.model_options)
+ filter_registered_hooks_on_conds(self.conds, self.model_options)
+ executor = comfy.patcher_extension.WrapperExecutor.new_class_executor(
+ self.outer_sample,
+ self,
+ comfy.patcher_extension.get_all_wrappers(comfy.patcher_extension.WrappersMP.OUTER_SAMPLE, self.model_options, is_model_options=True)
+ )
+ output = executor.execute(noise, latent_image, sampler, sigmas, denoise_mask, callback, disable_pbar, seed, latent_shapes=latent_shapes)
+ finally:
+ cast_to_load_options(self.model_options, device=self.model_patcher.offload_device)
+ self.model_options = orig_model_options
+ self.model_patcher.hook_mode = orig_hook_mode
+ self.model_patcher.restore_hook_patches()
+
+ del self.conds
+
+ if len(latent_shapes) > 1:
+ output = comfy.nested_tensor.NestedTensor(comfy.utils.unpack_latents(output, latent_shapes))
+ return output
+
+
+def sample(model, noise, positive, negative, cfg, device, sampler, sigmas, model_options={}, latent_image=None, denoise_mask=None, callback=None, disable_pbar=False, seed=None):
+ cfg_guider = CFGGuider(model)
+ cfg_guider.set_conds(positive, negative)
+ cfg_guider.set_cfg(cfg)
+ return cfg_guider.sample(noise, latent_image, sampler, sigmas, denoise_mask, callback, disable_pbar, seed)
+
+
+SAMPLER_NAMES = KSAMPLER_NAMES + ["ddim", "uni_pc", "uni_pc_bh2"]
+
+class SchedulerHandler(NamedTuple):
+ handler: Callable[..., torch.Tensor]
+ # Boolean indicates whether to call the handler like:
+ # scheduler_function(model_sampling, steps) or
+ # scheduler_function(n, sigma_min: float, sigma_max: float)
+ use_ms: bool = True
+
+SCHEDULER_HANDLERS = {
+ "simple": SchedulerHandler(simple_scheduler),
+ "sgm_uniform": SchedulerHandler(partial(normal_scheduler, sgm=True)),
+ "karras": SchedulerHandler(k_diffusion_sampling.get_sigmas_karras, use_ms=False),
+ "exponential": SchedulerHandler(k_diffusion_sampling.get_sigmas_exponential, use_ms=False),
+ "ddim_uniform": SchedulerHandler(ddim_scheduler),
+ "beta": SchedulerHandler(beta_scheduler),
+ "normal": SchedulerHandler(normal_scheduler),
+ "linear_quadratic": SchedulerHandler(linear_quadratic_schedule),
+ "kl_optimal": SchedulerHandler(kl_optimal_scheduler, use_ms=False),
+}
+SCHEDULER_NAMES = list(SCHEDULER_HANDLERS)
+
+def calculate_sigmas(model_sampling: object, scheduler_name: str, steps: int) -> torch.Tensor:
+ handler = SCHEDULER_HANDLERS.get(scheduler_name)
+ if handler is None:
+ err = f"error invalid scheduler {scheduler_name}"
+ logging.error(err)
+ raise ValueError(err)
+ if handler.use_ms:
+ return handler.handler(model_sampling, steps)
+ return handler.handler(n=steps, sigma_min=float(model_sampling.sigma_min), sigma_max=float(model_sampling.sigma_max))
+
+def sampler_object(name):
+ if name == "uni_pc":
+ sampler = KSAMPLER(uni_pc.sample_unipc)
+ elif name == "uni_pc_bh2":
+ sampler = KSAMPLER(uni_pc.sample_unipc_bh2)
+ elif name == "ddim":
+ sampler = ksampler("euler", inpaint_options={"random": True})
+ else:
+ sampler = ksampler(name)
+ return sampler
+
+class KSampler:
+ SCHEDULERS = SCHEDULER_NAMES
+ SAMPLERS = SAMPLER_NAMES
+ DISCARD_PENULTIMATE_SIGMA_SAMPLERS = set(('dpm_2', 'dpm_2_ancestral', 'uni_pc', 'uni_pc_bh2'))
+
+ def __init__(self, model, steps, device, sampler=None, scheduler=None, denoise=None, model_options={}):
+ self.model = model
+ self.device = device
+ if scheduler not in self.SCHEDULERS:
+ scheduler = self.SCHEDULERS[0]
+ if sampler not in self.SAMPLERS:
+ sampler = self.SAMPLERS[0]
+ self.scheduler = scheduler
+ self.sampler = sampler
+ self.set_steps(steps, denoise)
+ self.denoise = denoise
+ self.model_options = model_options
+
+ def calculate_sigmas(self, steps):
+ sigmas = None
+
+ discard_penultimate_sigma = False
+ if self.sampler in self.DISCARD_PENULTIMATE_SIGMA_SAMPLERS:
+ steps += 1
+ discard_penultimate_sigma = True
+
+ sigmas = calculate_sigmas(self.model.get_model_object("model_sampling"), self.scheduler, steps)
+
+ if discard_penultimate_sigma:
+ sigmas = torch.cat([sigmas[:-2], sigmas[-1:]])
+ return sigmas
+
+ def set_steps(self, steps, denoise=None):
+ self.steps = steps
+ if denoise is None or denoise > 0.9999:
+ self.sigmas = self.calculate_sigmas(steps).to(self.device)
+ else:
+ if denoise <= 0.0:
+ self.sigmas = torch.FloatTensor([])
+ else:
+ new_steps = int(steps/denoise)
+ sigmas = self.calculate_sigmas(new_steps).to(self.device)
+ self.sigmas = sigmas[-(steps + 1):]
+
+ def sample(self, noise, positive, negative, cfg, latent_image=None, start_step=None, last_step=None, force_full_denoise=False, denoise_mask=None, sigmas=None, callback=None, disable_pbar=False, seed=None):
+ if sigmas is None:
+ sigmas = self.sigmas
+
+ if last_step is not None and last_step < (len(sigmas) - 1):
+ sigmas = sigmas[:last_step + 1]
+ if force_full_denoise:
+ sigmas[-1] = 0
+
+ if start_step is not None:
+ if start_step < (len(sigmas) - 1):
+ sigmas = sigmas[start_step:]
+ else:
+ if latent_image is not None:
+ return latent_image
+ else:
+ return torch.zeros_like(noise)
+
+ sampler = sampler_object(self.sampler)
+
+ return sample(self.model, noise, positive, negative, cfg, self.device, sampler, sigmas, self.model_options, latent_image=latent_image, denoise_mask=denoise_mask, callback=callback, disable_pbar=disable_pbar, seed=seed)
diff --git a/ComfyUI/comfy/sd.py b/ComfyUI/comfy/sd.py
new file mode 100644
index 0000000000000000000000000000000000000000..8d670106e712f042c9d05f5b5f98292e1878babb
--- /dev/null
+++ b/ComfyUI/comfy/sd.py
@@ -0,0 +1,2270 @@
+import json
+import torch
+from enum import Enum
+import logging
+
+from comfy import model_management
+from comfy.utils import ProgressBar
+from .ldm.models.autoencoder import AutoencoderKL, AutoencodingEngine
+from .ldm.cascade.stage_a import StageA
+from .ldm.cascade.stage_c_coder import StageC_coder
+from .ldm.audio.autoencoder import AudioOobleckVAE
+import comfy.ldm.genmo.vae.model
+import comfy.ldm.lightricks.vae.causal_video_autoencoder
+import comfy.ldm.lightricks.vae.audio_vae
+import comfy.ldm.cosmos.vae
+import comfy.ldm.wan.vae
+import comfy.ldm.wan.vae2_2
+import comfy.ldm.hunyuan3d.vae
+import comfy.ldm.seedvr.vae
+import comfy.ldm.mage_flow.vae
+import comfy.ldm.triposplat.vae
+import comfy.ldm.ace.vae.music_dcae_pipeline
+import comfy.ldm.cogvideo.vae
+import comfy.ldm.hunyuan_video.vae
+import comfy.ldm.mmaudio.vae.autoencoder
+import comfy.ldm.audio.vae_sa3
+import comfy.pixel_space_convert
+import comfy.weight_adapter
+import yaml
+import math
+import os
+
+import comfy.utils
+
+from . import clip_vision
+from . import gligen
+from . import diffusers_convert
+from . import model_detection
+
+from . import sd1_clip
+from . import sdxl_clip
+import comfy.text_encoders.sd2_clip
+import comfy.text_encoders.sd3_clip
+import comfy.text_encoders.sa_t5
+import comfy.text_encoders.aura_t5
+import comfy.text_encoders.pixart_t5
+import comfy.text_encoders.hydit
+import comfy.text_encoders.flux
+import comfy.text_encoders.long_clipl
+import comfy.text_encoders.genmo
+import comfy.text_encoders.lt
+import comfy.text_encoders.hunyuan_video
+import comfy.text_encoders.cosmos
+import comfy.text_encoders.lumina2
+import comfy.text_encoders.pixeldit
+import comfy.text_encoders.wan
+import comfy.text_encoders.hidream
+import comfy.text_encoders.ace
+import comfy.text_encoders.omnigen2
+import comfy.text_encoders.qwen_image
+import comfy.text_encoders.hunyuan_image
+import comfy.text_encoders.z_image
+import comfy.text_encoders.krea2
+import comfy.text_encoders.mage_flow
+import comfy.text_encoders.ideogram4
+import comfy.text_encoders.ovis
+import comfy.text_encoders.kandinsky5
+import comfy.text_encoders.jina_clip_2
+import comfy.text_encoders.newbie
+import comfy.text_encoders.anima
+import comfy.text_encoders.ace15
+import comfy.text_encoders.longcat_image
+import comfy.text_encoders.qwen35
+import comfy.text_encoders.qwen3vl
+import comfy.text_encoders.minimax
+import comfy.ldm.minimax.vae
+import comfy.ldm.minimax.audio_vae
+import comfy.text_encoders.boogu
+import comfy.text_encoders.ernie
+import comfy.text_encoders.gemma4
+import comfy.text_encoders.cogvideo
+import comfy.text_encoders.sa3
+import comfy.text_encoders.gpt_oss
+import comfy.text_encoders.joyimage
+
+import comfy.model_patcher
+import comfy.lora
+import comfy.lora_convert
+import comfy.hooks
+import comfy.t2i_adapter.adapter
+import comfy.taesd.taesd
+import comfy.taesd.taehv
+import comfy.latent_formats
+
+import comfy.ldm.flux.redux
+
+def load_lora_for_models(model, clip, lora, strength_model, strength_clip, lora_metadata=None):
+ key_map = {}
+ if model is not None:
+ key_map = comfy.lora.model_lora_keys_unet(model.model, key_map)
+ if clip is not None:
+ key_map = comfy.lora.model_lora_keys_clip(clip.cond_stage_model, key_map)
+
+ lora = comfy.lora_convert.convert_lora(lora)
+ loaded = comfy.lora.load_lora(lora, key_map)
+ if model is not None:
+ new_modelpatcher = model.clone()
+ k = new_modelpatcher.add_patches(loaded, strength_model)
+ if lora_metadata:
+ new_modelpatcher.set_attachments("lora_metadata", lora_metadata)
+ else:
+ k = ()
+ new_modelpatcher = None
+
+ if clip is not None:
+ new_clip = clip.clone()
+ k1 = new_clip.add_patches(loaded, strength_clip)
+ if lora_metadata:
+ new_clip.patcher.set_attachments("lora_metadata", lora_metadata)
+ else:
+ k1 = ()
+ new_clip = None
+ k = set(k)
+ k1 = set(k1)
+ for x in loaded:
+ if (x not in k) and (x not in k1):
+ logging.warning("NOT LOADED {}".format(x))
+
+ return (new_modelpatcher, new_clip)
+
+
+def load_bypass_lora_for_models(model, clip, lora, strength_model, strength_clip):
+ """
+ Load LoRA in bypass mode without modifying base model weights.
+
+ Instead of patching weights, this injects the LoRA computation into the
+ forward pass: output = base_forward(x) + lora_path(x)
+
+ Non-adapter patches (bias diff, weight diff, etc.) are applied as regular patches.
+
+ This is useful for training and when model weights are offloaded.
+ """
+ key_map = {}
+ if model is not None:
+ key_map = comfy.lora.model_lora_keys_unet(model.model, key_map)
+ if clip is not None:
+ key_map = comfy.lora.model_lora_keys_clip(clip.cond_stage_model, key_map)
+
+ logging.debug(f"[BypassLoRA] key_map has {len(key_map)} entries")
+
+ lora = comfy.lora_convert.convert_lora(lora)
+ loaded = comfy.lora.load_lora(lora, key_map)
+
+ logging.debug(f"[BypassLoRA] loaded has {len(loaded)} entries")
+
+ # Separate adapters (for bypass) from other patches (for regular patching)
+ bypass_patches = {} # WeightAdapterBase instances -> bypass mode
+ regular_patches = {} # diff, set, bias patches -> regular weight patching
+
+ for key, patch_data in loaded.items():
+ if isinstance(patch_data, comfy.weight_adapter.WeightAdapterBase):
+ bypass_patches[key] = patch_data
+ else:
+ regular_patches[key] = patch_data
+
+ logging.debug(f"[BypassLoRA] {len(bypass_patches)} bypass adapters, {len(regular_patches)} regular patches")
+
+ k = set()
+ k1 = set()
+
+ if model is not None:
+ new_modelpatcher = model.clone()
+
+ # Apply regular patches (bias diff, weight diff, etc.) via normal patching
+ if regular_patches:
+ patched_keys = new_modelpatcher.add_patches(regular_patches, strength_model)
+ k.update(patched_keys)
+
+ # Apply adapter patches via bypass injection
+ manager = comfy.weight_adapter.BypassInjectionManager()
+ model_sd_keys = set(new_modelpatcher.model.state_dict().keys())
+
+ for key, adapter in bypass_patches.items():
+ if key in model_sd_keys:
+ manager.add_adapter(key, adapter, strength=strength_model)
+ k.add(key)
+ else:
+ logging.warning(f"[BypassLoRA] Adapter key not in model state_dict: {key}")
+
+ injections = manager.create_injections(new_modelpatcher.model)
+
+ if manager.get_hook_count() > 0:
+ new_modelpatcher.set_injections("bypass_lora", injections)
+ else:
+ new_modelpatcher = None
+
+ if clip is not None:
+ new_clip = clip.clone()
+
+ # Apply regular patches to clip
+ if regular_patches:
+ patched_keys = new_clip.add_patches(regular_patches, strength_clip)
+ k1.update(patched_keys)
+
+ # Apply adapter patches via bypass injection
+ clip_manager = comfy.weight_adapter.BypassInjectionManager()
+ clip_sd_keys = set(new_clip.cond_stage_model.state_dict().keys())
+
+ for key, adapter in bypass_patches.items():
+ if key in clip_sd_keys:
+ clip_manager.add_adapter(key, adapter, strength=strength_clip)
+ k1.add(key)
+
+ clip_injections = clip_manager.create_injections(new_clip.cond_stage_model)
+ if clip_manager.get_hook_count() > 0:
+ new_clip.patcher.set_injections("bypass_lora", clip_injections)
+ else:
+ new_clip = None
+
+ for x in loaded:
+ if (x not in k) and (x not in k1):
+ patch_data = loaded[x]
+ patch_type = type(patch_data).__name__
+ if isinstance(patch_data, tuple):
+ patch_type = f"tuple({patch_data[0]})"
+ logging.warning(f"NOT LOADED: {x} (type={patch_type})")
+
+ return (new_modelpatcher, new_clip)
+
+
+class CLIP:
+ def __init__(self, target=None, embedding_directory=None, no_init=False, tokenizer_data={}, parameters=0, state_dict=[], model_options={}, disable_dynamic=False):
+ if no_init:
+ return
+ params = target.params.copy()
+ clip = target.clip
+ tokenizer = target.tokenizer
+
+ load_device = model_options.get("load_device", model_management.text_encoder_device())
+ offload_device = model_options.get("offload_device", model_management.text_encoder_offload_device())
+ dtype = model_options.get("dtype", None)
+ if dtype is None:
+ dtype = model_management.text_encoder_dtype(load_device)
+
+ params['dtype'] = dtype
+ params['device'] = model_options.get("initial_device", model_management.text_encoder_initial_device(load_device, offload_device, parameters * model_management.dtype_size(dtype)))
+ params['model_options'] = model_options
+
+ self.cond_stage_model = clip(**(params))
+
+ for dt in self.cond_stage_model.dtypes:
+ if not model_management.supports_cast(load_device, dt):
+ load_device = offload_device
+ if params['device'] != offload_device:
+ self.cond_stage_model.to(offload_device)
+ logging.warning("Had to shift TE back.")
+
+ model_management.archive_model_dtypes(self.cond_stage_model)
+
+ self.tokenizer = tokenizer(embedding_directory=embedding_directory, tokenizer_data=tokenizer_data)
+ te_disable_dynamic = disable_dynamic or getattr(self.cond_stage_model, "disable_offload", False)
+ ModelPatcher = comfy.model_patcher.ModelPatcher if te_disable_dynamic else comfy.model_patcher.CoreModelPatcher
+ self.patcher = ModelPatcher(self.cond_stage_model, load_device=load_device, offload_device=offload_device)
+ #Match torch.float32 hardcode upcast in TE implemention
+ self.patcher.set_model_compute_dtype(torch.float32)
+ self.patcher.hook_mode = comfy.hooks.EnumHookMode.MinVram
+ self.patcher.is_clip = True
+ self.apply_hooks_to_conds = None
+ if len(state_dict) > 0:
+ if isinstance(state_dict, list):
+ for c in state_dict:
+ m, u = self.load_sd(c)
+ if len(m) > 0:
+ logging.warning("clip missing: {}".format(m))
+
+ if len(u) > 0:
+ logging.debug("clip unexpected: {}".format(u))
+ else:
+ m, u = self.load_sd(state_dict, full_model=True)
+ if len(m) > 0:
+ m_filter = list(filter(lambda a: ".logit_scale" not in a and ".transformer.text_projection.weight" not in a, m))
+ if len(m_filter) > 0:
+ logging.warning("clip missing: {}".format(m))
+ else:
+ logging.debug("clip missing: {}".format(m))
+
+ if len(u) > 0:
+ logging.debug("clip unexpected {}:".format(u))
+
+ if params['device'] == load_device:
+ model_management.load_models_gpu([self.patcher], force_full_load=True)
+ self.layer_idx = None
+ self.use_clip_schedule = False
+ logging.info("CLIP/text encoder model load device: {}, offload device: {}, current: {}, dtype: {}".format(load_device, offload_device, params['device'], dtype))
+ self.tokenizer_options = {}
+
+ def clone(self, disable_dynamic=False):
+ n = CLIP(no_init=True)
+ n.patcher = self.patcher.clone(disable_dynamic=disable_dynamic)
+ n.cond_stage_model = self.cond_stage_model
+ n.tokenizer = self.tokenizer
+ n.layer_idx = self.layer_idx
+ n.tokenizer_options = self.tokenizer_options.copy()
+ n.use_clip_schedule = self.use_clip_schedule
+ n.apply_hooks_to_conds = self.apply_hooks_to_conds
+ return n
+
+ def add_patches(self, patches, strength_patch=1.0, strength_model=1.0):
+ return self.patcher.add_patches(patches, strength_patch, strength_model)
+
+ def set_tokenizer_option(self, option_name, value):
+ self.tokenizer_options[option_name] = value
+
+ def clip_layer(self, layer_idx):
+ self.layer_idx = layer_idx
+
+ def tokenize(self, text, return_word_ids=False, **kwargs):
+ tokenizer_options = kwargs.get("tokenizer_options", {})
+ if len(self.tokenizer_options) > 0:
+ tokenizer_options = {**self.tokenizer_options, **tokenizer_options}
+ if len(tokenizer_options) > 0:
+ kwargs["tokenizer_options"] = tokenizer_options
+ return self.tokenizer.tokenize_with_weights(text, return_word_ids, **kwargs)
+
+ def add_hooks_to_dict(self, pooled_dict: dict[str]):
+ if self.apply_hooks_to_conds:
+ pooled_dict["hooks"] = self.apply_hooks_to_conds
+ return pooled_dict
+
+ def encode_from_tokens_scheduled(self, tokens, unprojected=False, add_dict: dict[str]={}, show_pbar=True):
+ all_cond_pooled: list[tuple[torch.Tensor, dict[str]]] = []
+ all_hooks = self.patcher.forced_hooks
+ if all_hooks is None or not self.use_clip_schedule:
+ # if no hooks or shouldn't use clip schedule, do unscheduled encode_from_tokens and perform add_dict
+ return_pooled = "unprojected" if unprojected else True
+ pooled_dict = self.encode_from_tokens(tokens, return_pooled=return_pooled, return_dict=True)
+ cond = pooled_dict.pop("cond")
+ # add/update any keys with the provided add_dict
+ pooled_dict.update(add_dict)
+ all_cond_pooled.append([cond, pooled_dict])
+ else:
+ scheduled_keyframes = all_hooks.get_hooks_for_clip_schedule()
+
+ self.cond_stage_model.reset_clip_options()
+ if self.layer_idx is not None:
+ self.cond_stage_model.set_clip_options({"layer": self.layer_idx})
+ if unprojected:
+ self.cond_stage_model.set_clip_options({"projected_pooled": False})
+
+ self.load_model(tokens)
+ device = self.patcher.load_device
+ self.cond_stage_model.set_clip_options({"execution_device": device})
+ all_hooks.reset()
+ self.patcher.patch_hooks(None)
+ if show_pbar:
+ pbar = ProgressBar(len(scheduled_keyframes))
+
+ with model_management.cuda_device_context(device):
+ for scheduled_opts in scheduled_keyframes:
+ t_range = scheduled_opts[0]
+ # don't bother encoding any conds outside of start_percent and end_percent bounds
+ if "start_percent" in add_dict:
+ if t_range[1] < add_dict["start_percent"]:
+ continue
+ if "end_percent" in add_dict:
+ if t_range[0] > add_dict["end_percent"]:
+ continue
+ hooks_keyframes = scheduled_opts[1]
+ for hook, keyframe in hooks_keyframes:
+ hook.hook_keyframe._current_keyframe = keyframe
+ # apply appropriate hooks with values that match new hook_keyframe
+ self.patcher.patch_hooks(all_hooks)
+ # perform encoding as normal
+ o = self.cond_stage_model.encode_token_weights(tokens)
+ cond, pooled = o[:2]
+ pooled_dict = {"pooled_output": pooled}
+ # add clip_start_percent and clip_end_percent in pooled
+ pooled_dict["clip_start_percent"] = t_range[0]
+ pooled_dict["clip_end_percent"] = t_range[1]
+ # add/update any keys with the provided add_dict
+ pooled_dict.update(add_dict)
+ # add hooks stored on clip
+ self.add_hooks_to_dict(pooled_dict)
+ all_cond_pooled.append([cond, pooled_dict])
+ if show_pbar:
+ pbar.update(1)
+ model_management.throw_exception_if_processing_interrupted()
+ all_hooks.reset()
+ return all_cond_pooled
+
+ def encode_from_tokens(self, tokens, return_pooled=False, return_dict=False):
+ self.cond_stage_model.reset_clip_options()
+
+ if self.layer_idx is not None:
+ self.cond_stage_model.set_clip_options({"layer": self.layer_idx})
+
+ if return_pooled == "unprojected":
+ self.cond_stage_model.set_clip_options({"projected_pooled": False})
+
+ self.load_model(tokens)
+ device = self.patcher.load_device
+ self.cond_stage_model.set_clip_options({"execution_device": device})
+
+ with model_management.cuda_device_context(device):
+ o = self.cond_stage_model.encode_token_weights(tokens)
+
+ cond, pooled = o[:2]
+ if return_dict:
+ out = {"cond": cond, "pooled_output": pooled}
+ if len(o) > 2:
+ for k in o[2]:
+ out[k] = o[2][k]
+ self.add_hooks_to_dict(out)
+ return out
+
+ if return_pooled:
+ return cond, pooled
+ return cond
+
+ def encode(self, text):
+ tokens = self.tokenize(text)
+ return self.encode_from_tokens(tokens)
+
+ def load_sd(self, sd, full_model=False):
+ if full_model:
+ return self.cond_stage_model.load_state_dict(sd, strict=False, assign=self.patcher.is_dynamic())
+ else:
+ can_assign = self.patcher.is_dynamic()
+ self.cond_stage_model.can_assign_sd = can_assign
+
+ # The CLIP models are a pretty complex web of wrappers and its
+ # a bit of an API change to plumb this all the way through.
+ # So spray paint the model with this flag that the loading
+ # nn.Module can then inspect for itself.
+ for m in self.cond_stage_model.modules():
+ m.can_assign_sd = can_assign
+
+ return self.cond_stage_model.load_sd(sd)
+
+ def get_sd(self):
+ sd_clip = self.cond_stage_model.state_dict()
+ sd_tokenizer = self.tokenizer.state_dict()
+ for k in sd_tokenizer:
+ sd_clip[k] = sd_tokenizer[k]
+ return sd_clip
+
+ def state_dict_for_saving(self):
+ sd_clip = self.patcher.model_state_dict_for_saving()
+ sd_tokenizer = self.tokenizer.state_dict()
+ for k in sd_tokenizer:
+ sd_clip[k] = sd_tokenizer[k]
+ return sd_clip
+
+ def load_model(self, tokens={}):
+ memory_used = 0
+ if hasattr(self.cond_stage_model, "memory_estimation_function"):
+ memory_used = self.cond_stage_model.memory_estimation_function(tokens, device=self.patcher.load_device)
+ model_management.load_models_gpu([self.patcher], memory_required=memory_used)
+ return self.patcher
+
+ def get_key_patches(self):
+ return self.patcher.get_key_patches()
+
+ def generate(self, tokens, do_sample=True, max_length=256, temperature=1.0, top_k=50, top_p=0.95, min_p=0.0, repetition_penalty=1.0, seed=None, presence_penalty=0.0):
+ self.cond_stage_model.reset_clip_options()
+
+ self.load_model(tokens)
+ device = self.patcher.load_device
+ self.cond_stage_model.set_clip_options({"layer": None})
+ self.cond_stage_model.set_clip_options({"execution_device": device})
+
+ with model_management.cuda_device_context(device):
+ return self.cond_stage_model.generate(tokens, do_sample=do_sample, max_length=max_length, temperature=temperature, top_k=top_k, top_p=top_p, min_p=min_p, repetition_penalty=repetition_penalty, seed=seed, presence_penalty=presence_penalty)
+
+ def decode(self, token_ids, skip_special_tokens=True):
+ return self.tokenizer.decode(token_ids, skip_special_tokens=skip_special_tokens)
+
+ def is_dynamic(self):
+ return self.patcher.is_dynamic()
+
+class VAE:
+ def __init__(self, sd=None, device=None, config=None, dtype=None, metadata=None):
+ is_seedvr2_vae = "decoder.up_blocks.2.upsamplers.0.upscale_conv.weight" in sd
+ if not is_seedvr2_vae and 'decoder.up_blocks.0.resnets.0.norm1.weight' in sd.keys(): #diffusers format
+ sd = diffusers_convert.convert_vae_state_dict(sd)
+
+ if model_management.is_amd():
+ VAE_KL_MEM_RATIO = 2.73
+ else:
+ VAE_KL_MEM_RATIO = 1.0
+
+ self.memory_used_encode = lambda shape, dtype: (1767 * shape[2] * shape[3]) * model_management.dtype_size(dtype) * VAE_KL_MEM_RATIO #These are for AutoencoderKL and need tweaking (should be lower)
+ self.memory_used_decode = lambda shape, dtype: (2178 * shape[2] * shape[3] * 64) * model_management.dtype_size(dtype) * VAE_KL_MEM_RATIO
+ self.downscale_ratio = 8
+ self.upscale_ratio = 8
+ self.latent_channels = 4
+ self.latent_dim = 2
+ self.output_channels = 3
+ self.pad_channel_value = None
+ self.process_input = lambda image: image * 2.0 - 1.0
+ self.process_output = lambda image: image.add_(1.0).div_(2.0).clamp_(0.0, 1.0)
+ self.working_dtypes = [torch.bfloat16, torch.float32]
+ self.disable_offload = False
+ self.not_video = False
+ self.size = None
+
+ self.downscale_index_formula = None
+ self.upscale_index_formula = None
+ self.extra_1d_channel = None
+ self.crop_input = True
+ self.handles_tiling = False
+ self.format_encoded = None
+
+ self.audio_sample_rate = 44100
+
+ if config is None:
+ if "decoder.mid.block_1.mix_factor" in sd:
+ encoder_config = {'double_z': True, 'z_channels': 4, 'resolution': 256, 'in_channels': 3, 'out_ch': 3, 'ch': 128, 'ch_mult': [1, 2, 4, 4], 'num_res_blocks': 2, 'attn_resolutions': [], 'dropout': 0.0}
+ decoder_config = encoder_config.copy()
+ decoder_config["video_kernel_size"] = [3, 1, 1]
+ decoder_config["alpha"] = 0.0
+ self.first_stage_model = AutoencodingEngine(regularizer_config={'target': "comfy.ldm.models.autoencoder.DiagonalGaussianRegularizer"},
+ encoder_config={'target': "comfy.ldm.modules.diffusionmodules.model.Encoder", 'params': encoder_config},
+ decoder_config={'target': "comfy.ldm.modules.temporal_ae.VideoDecoder", 'params': decoder_config})
+ elif "taesd_decoder.1.weight" in sd:
+ if isinstance(metadata, dict) and "tae_latent_channels" in metadata:
+ self.latent_channels = metadata["tae_latent_channels"]
+ else:
+ self.latent_channels = sd["taesd_decoder.1.weight"].shape[1]
+ self.first_stage_model = comfy.taesd.taesd.TAESD(latent_channels=self.latent_channels)
+ elif "vquantizer.codebook.weight" in sd: #VQGan: stage a of stable cascade
+ self.first_stage_model = StageA()
+ self.downscale_ratio = 4
+ self.upscale_ratio = 4
+ #TODO
+ #self.memory_used_encode
+ #self.memory_used_decode
+ self.process_input = lambda image: image
+ self.process_output = lambda image: image
+ elif "backbone.1.0.block.0.1.num_batches_tracked" in sd: #effnet: encoder for stage c latent of stable cascade
+ self.first_stage_model = StageC_coder()
+ self.downscale_ratio = 32
+ self.latent_channels = 16
+ new_sd = {}
+ for k in sd:
+ new_sd["encoder.{}".format(k)] = sd[k]
+ sd = new_sd
+ elif "blocks.11.num_batches_tracked" in sd: #previewer: decoder for stage c latent of stable cascade
+ self.first_stage_model = StageC_coder()
+ self.latent_channels = 16
+ new_sd = {}
+ for k in sd:
+ new_sd["previewer.{}".format(k)] = sd[k]
+ sd = new_sd
+ elif "encoder.backbone.1.0.block.0.1.num_batches_tracked" in sd: #combined effnet and previewer for stable cascade
+ self.first_stage_model = StageC_coder()
+ self.downscale_ratio = 32
+ self.latent_channels = 16
+ elif "decoder.up_blocks.2.upsamplers.0.upscale_conv.weight" in sd: # seedvr2
+ self.first_stage_model = comfy.ldm.seedvr.vae.VideoAutoencoderKLWrapper()
+ self.latent_channels = comfy.ldm.seedvr.vae.SEEDVR2_LATENT_CHANNELS
+ self.latent_dim = 3
+ self.disable_offload = True
+ self.memory_used_decode = lambda shape, dtype: self.first_stage_model.comfy_memory_used_decode(shape)
+ self.memory_used_encode = lambda shape, dtype: (max(shape[2], 5) * shape[3] * shape[4] * 64) * model_management.dtype_size(dtype)
+ self.working_dtypes = [torch.float16, torch.bfloat16, torch.float32]
+ self.handles_tiling = True
+ self.format_encoded = self.first_stage_model.comfy_format_encoded
+ self.downscale_ratio = (lambda a: max(0, math.floor((a + 3) / 4)), 8, 8)
+ self.downscale_index_formula = (4, 8, 8)
+ self.upscale_ratio = (lambda a: max(0, a * 4 - 3), 8, 8)
+ self.upscale_index_formula = (4, 8, 8)
+ self.process_input = lambda image: image * 2.0 - 1.0
+ self.crop_input = False
+ elif "student.dconv_encoder.proj_out.weight" in sd: # Mage-VAE (one-step diffusion codec, Flux2-anchored 128ch/16x latents)
+ sd = comfy.utils.state_dict_prefix_replace(sd, {"student.dconv_encoder.": "dconv_encoder.", "pipeline.": "decoder_model."})
+ # Drop the unused Flux2-VAE anchor encoder carried in the checkpoint.
+ sd = {k: v for k, v in sd.items() if not k.startswith("decoder_model.y_embedder.encoder.") and not k.startswith("decoder_model.y_embedder.bottleneck.")}
+ self.first_stage_model = comfy.ldm.mage_flow.vae.MageVAE()
+ self.latent_channels = 128
+ self.downscale_ratio = 16
+ self.upscale_ratio = 16
+ self.working_dtypes = [torch.bfloat16, torch.float32]
+ self.memory_used_encode = lambda shape, dtype: (400 * shape[2] * shape[3]) * model_management.dtype_size(dtype)
+ self.memory_used_decode = lambda shape, dtype: (1000 * shape[2] * shape[3] * 16 * 16) * model_management.dtype_size(dtype)
+ elif "decoder.conv_in.weight" in sd:
+ if sd['decoder.conv_in.weight'].shape[1] == 64:
+ ddconfig = {"block_out_channels": [128, 256, 512, 512, 1024, 1024], "in_channels": 3, "out_channels": 3, "num_res_blocks": 2, "ffactor_spatial": 32, "downsample_match_channel": True, "upsample_match_channel": True}
+ self.latent_channels = ddconfig['z_channels'] = sd["decoder.conv_in.weight"].shape[1]
+ self.downscale_ratio = 32
+ self.upscale_ratio = 32
+ self.working_dtypes = [torch.float16, torch.bfloat16, torch.float32]
+ self.first_stage_model = AutoencodingEngine(regularizer_config={'target': "comfy.ldm.models.autoencoder.DiagonalGaussianRegularizer"},
+ encoder_config={'target': "comfy.ldm.hunyuan_video.vae.Encoder", 'params': ddconfig},
+ decoder_config={'target': "comfy.ldm.hunyuan_video.vae.Decoder", 'params': ddconfig})
+
+ self.memory_used_encode = lambda shape, dtype: (700 * shape[2] * shape[3]) * model_management.dtype_size(dtype)
+ self.memory_used_decode = lambda shape, dtype: (700 * shape[2] * shape[3] * 32 * 32) * model_management.dtype_size(dtype)
+ elif sd['decoder.conv_in.weight'].shape[1] == 32 and sd['decoder.conv_in.weight'].ndim == 5:
+ ddconfig = {"block_out_channels": [128, 256, 512, 1024, 1024], "in_channels": 3, "out_channels": 3, "num_res_blocks": 2, "ffactor_spatial": 16, "ffactor_temporal": 4, "downsample_match_channel": True, "upsample_match_channel": True, "refiner_vae": False}
+ self.latent_channels = ddconfig['z_channels'] = sd["decoder.conv_in.weight"].shape[1]
+ self.working_dtypes = [torch.float16, torch.bfloat16, torch.float32]
+ self.upscale_ratio = (lambda a: max(0, a * 4 - 3), 16, 16)
+ self.upscale_index_formula = (4, 16, 16)
+ self.downscale_ratio = (lambda a: max(0, math.floor((a + 3) / 4)), 16, 16)
+ self.downscale_index_formula = (4, 16, 16)
+ self.latent_dim = 3
+ self.not_video = True
+ self.first_stage_model = AutoencodingEngine(regularizer_config={'target': "comfy.ldm.models.autoencoder.DiagonalGaussianRegularizer"},
+ encoder_config={'target': "comfy.ldm.hunyuan_video.vae_refiner.Encoder", 'params': ddconfig},
+ decoder_config={'target': "comfy.ldm.hunyuan_video.vae_refiner.Decoder", 'params': ddconfig})
+
+ self.memory_used_encode = lambda shape, dtype: (2800 * shape[-2] * shape[-1]) * model_management.dtype_size(dtype)
+ self.memory_used_decode = lambda shape, dtype: (2800 * shape[-3] * shape[-2] * shape[-1] * 16 * 16) * model_management.dtype_size(dtype)
+ else:
+ #default SD1.x/SD2.x VAE parameters
+ ddconfig = {'double_z': True, 'z_channels': 4, 'resolution': 256, 'in_channels': 3, 'out_ch': 3, 'ch': 128, 'ch_mult': [1, 2, 4, 4], 'num_res_blocks': 2, 'attn_resolutions': [], 'dropout': 0.0}
+
+ if 'encoder.down.2.downsample.conv.weight' not in sd and 'decoder.up.3.upsample.conv.weight' not in sd: #Stable diffusion x4 upscaler VAE
+ ddconfig['ch_mult'] = [1, 2, 4]
+ self.downscale_ratio = 4
+ self.upscale_ratio = 4
+
+ self.latent_channels = ddconfig['z_channels'] = sd["decoder.conv_in.weight"].shape[1]
+ if 'decoder.post_quant_conv.weight' in sd:
+ sd = comfy.utils.state_dict_prefix_replace(sd, {"decoder.post_quant_conv.": "post_quant_conv.", "encoder.quant_conv.": "quant_conv."})
+
+ if 'bn.running_mean' in sd:
+ ddconfig["batch_norm_latent"] = True
+ self.downscale_ratio *= 2
+ self.upscale_ratio *= 2
+ self.latent_channels *= 4
+ old_memory_used_decode = self.memory_used_decode
+ self.memory_used_decode = lambda shape, dtype: old_memory_used_decode(shape, dtype) * 4.0
+
+ decoder_ch = sd['decoder.conv_in.weight'].shape[0] // ddconfig['ch_mult'][-1]
+ if decoder_ch != ddconfig['ch']:
+ decoder_ddconfig = ddconfig.copy()
+ decoder_ddconfig['ch'] = decoder_ch
+ else:
+ decoder_ddconfig = None
+
+ if 'post_quant_conv.weight' in sd:
+ self.first_stage_model = AutoencoderKL(ddconfig=ddconfig, embed_dim=sd['post_quant_conv.weight'].shape[1], **({"decoder_ddconfig": decoder_ddconfig} if decoder_ddconfig is not None else {}))
+ else:
+ self.first_stage_model = AutoencodingEngine(regularizer_config={'target': "comfy.ldm.models.autoencoder.DiagonalGaussianRegularizer"},
+ encoder_config={'target': "comfy.ldm.modules.diffusionmodules.model.Encoder", 'params': ddconfig},
+ decoder_config={'target': "comfy.ldm.modules.diffusionmodules.model.Decoder", 'params': decoder_ddconfig if decoder_ddconfig is not None else ddconfig})
+ elif "decoder.layers.1.layers.0.beta" in sd:
+ config = {}
+ param_key = None
+ self.upscale_ratio = 2048
+ self.downscale_ratio = 2048
+ if "decoder.layers.2.layers.1.weight_v" in sd:
+ param_key = "decoder.layers.2.layers.1.weight_v"
+ if "decoder.layers.2.layers.1.parametrizations.weight.original1" in sd:
+ param_key = "decoder.layers.2.layers.1.parametrizations.weight.original1"
+ if param_key is not None:
+ if sd[param_key].shape[-1] == 12:
+ config["strides"] = [2, 4, 4, 6, 10]
+ self.audio_sample_rate = 48000
+ self.upscale_ratio = 1920
+ self.downscale_ratio = 1920
+
+ self.first_stage_model = AudioOobleckVAE(**config)
+ self.memory_used_encode = lambda shape, dtype: (1000 * shape[2]) * model_management.dtype_size(dtype)
+ self.memory_used_decode = lambda shape, dtype: (1000 * shape[2] * 2048) * model_management.dtype_size(dtype)
+ self.latent_channels = 64
+ self.output_channels = 2
+ self.pad_channel_value = "replicate"
+ self.latent_dim = 1
+ self.process_output = lambda audio: audio
+ self.process_input = lambda audio: audio
+ self.working_dtypes = [torch.float16, torch.bfloat16, torch.float32]
+ self.disable_offload = True
+ elif "blocks.2.blocks.3.stack.5.weight" in sd or "decoder.blocks.2.blocks.3.stack.5.weight" in sd or "layers.4.layers.1.attn_block.attn.qkv.weight" in sd or "encoder.layers.4.layers.1.attn_block.attn.qkv.weight" in sd: #genmo mochi vae
+ if "blocks.2.blocks.3.stack.5.weight" in sd:
+ sd = comfy.utils.state_dict_prefix_replace(sd, {"": "decoder."})
+ if "layers.4.layers.1.attn_block.attn.qkv.weight" in sd:
+ sd = comfy.utils.state_dict_prefix_replace(sd, {"": "encoder."})
+ self.first_stage_model = comfy.ldm.genmo.vae.model.VideoVAE()
+ self.latent_channels = 12
+ self.latent_dim = 3
+ self.memory_used_decode = lambda shape, dtype: (1000 * shape[2] * shape[3] * shape[4] * (6 * 8 * 8)) * model_management.dtype_size(dtype)
+ self.memory_used_encode = lambda shape, dtype: (1.5 * max(shape[2], 7) * shape[3] * shape[4] * (6 * 8 * 8)) * model_management.dtype_size(dtype)
+ self.upscale_ratio = (lambda a: max(0, a * 6 - 5), 8, 8)
+ self.upscale_index_formula = (6, 8, 8)
+ self.downscale_ratio = (lambda a: max(0, math.floor((a + 5) / 6)), 8, 8)
+ self.downscale_index_formula = (6, 8, 8)
+ self.working_dtypes = [torch.float16, torch.float32]
+ elif "decoder.up_blocks.0.res_blocks.0.conv1.conv.weight" in sd: #lightricks ltxv
+ tensor_conv1 = sd["decoder.up_blocks.0.res_blocks.0.conv1.conv.weight"]
+ version = 0
+ if tensor_conv1.shape[0] == 512:
+ version = 0
+ elif tensor_conv1.shape[0] == 1024:
+ version = 1
+ if "encoder.down_blocks.1.conv.conv.bias" in sd:
+ version = 2
+ vae_config = None
+ if metadata is not None and "config" in metadata:
+ vae_config = json.loads(metadata["config"]).get("vae", None)
+ self.first_stage_model = comfy.ldm.lightricks.vae.causal_video_autoencoder.VideoVAE(version=version, config=vae_config)
+ self.latent_channels = 128
+ self.latent_dim = 3
+ self.memory_used_decode = lambda shape, dtype: (1200 * shape[2] * shape[3] * shape[4] * (8 * 8 * 8)) * model_management.dtype_size(dtype)
+ self.memory_used_encode = lambda shape, dtype: (80 * max(shape[2], 7) * shape[3] * shape[4]) * model_management.dtype_size(dtype)
+ self.upscale_ratio = (lambda a: max(0, a * 8 - 7), 32, 32)
+ self.upscale_index_formula = (8, 32, 32)
+ self.downscale_ratio = (lambda a: max(0, math.floor((a + 7) / 8)), 32, 32)
+ self.downscale_index_formula = (8, 32, 32)
+ self.working_dtypes = [torch.bfloat16, torch.float32]
+ elif "decoder.conv_in.conv.weight" in sd and sd['decoder.conv_in.conv.weight'].shape[1] == 32:
+ ddconfig = {"block_out_channels": [128, 256, 512, 1024, 1024], "in_channels": 3, "out_channels": 3, "num_res_blocks": 2, "ffactor_spatial": 16, "ffactor_temporal": 4, "downsample_match_channel": True, "upsample_match_channel": True}
+ ddconfig['z_channels'] = sd["decoder.conv_in.conv.weight"].shape[1]
+ self.latent_channels = 32
+ self.upscale_ratio = (lambda a: max(0, a * 4 - 3), 16, 16)
+ self.upscale_index_formula = (4, 16, 16)
+ self.downscale_ratio = (lambda a: max(0, math.floor((a + 3) / 4)), 16, 16)
+ self.downscale_index_formula = (4, 16, 16)
+ self.latent_dim = 3
+ self.not_video = False
+ self.working_dtypes = [torch.float16, torch.bfloat16, torch.float32]
+ self.first_stage_model = AutoencodingEngine(regularizer_config={'target': "comfy.ldm.models.autoencoder.EmptyRegularizer"},
+ encoder_config={'target': "comfy.ldm.hunyuan_video.vae_refiner.Encoder", 'params': ddconfig},
+ decoder_config={'target': "comfy.ldm.hunyuan_video.vae_refiner.Decoder", 'params': ddconfig})
+
+ self.memory_used_encode = lambda shape, dtype: (1400 * 9 * shape[-2] * shape[-1]) * model_management.dtype_size(dtype)
+ self.memory_used_decode = lambda shape, dtype: (3600 * 4 * shape[-2] * shape[-1] * 16 * 16) * model_management.dtype_size(dtype)
+ elif "decoder.conv_in.conv.weight" in sd and "decoder.mid_block.resnets.0.norm1.norm_layer.weight" in sd: # CogVideoX VAE
+ self.upscale_ratio = (lambda a: max(0, a * 4 - 3), 8, 8)
+ self.upscale_index_formula = (4, 8, 8)
+ self.downscale_ratio = (lambda a: max(0, math.floor((a + 3) / 4)), 8, 8)
+ self.downscale_index_formula = (4, 8, 8)
+ self.latent_dim = 3
+ self.latent_channels = sd["encoder.conv_out.conv.weight"].shape[0] // 2
+ self.first_stage_model = comfy.ldm.cogvideo.vae.AutoencoderKLCogVideoX(latent_channels=self.latent_channels)
+ self.memory_used_decode = lambda shape, dtype: (2800 * max(2, ((shape[2] - 1) * 4) + 1) * shape[3] * shape[4] * (8 * 8)) * model_management.dtype_size(dtype)
+ self.memory_used_encode = lambda shape, dtype: (1400 * max(1, shape[2]) * shape[3] * shape[4]) * model_management.dtype_size(dtype)
+ self.working_dtypes = [torch.bfloat16, torch.float16, torch.float32]
+ elif "decoder.conv_in.conv.weight" in sd:
+ ddconfig = {'double_z': True, 'z_channels': 4, 'resolution': 256, 'in_channels': 3, 'out_ch': 3, 'ch': 128, 'ch_mult': [1, 2, 4, 4], 'num_res_blocks': 2, 'attn_resolutions': [], 'dropout': 0.0}
+ ddconfig["conv3d"] = True
+ ddconfig["time_compress"] = 4
+ self.upscale_ratio = (lambda a: max(0, a * 4 - 3), 8, 8)
+ self.upscale_index_formula = (4, 8, 8)
+ self.downscale_ratio = (lambda a: max(0, math.floor((a + 3) / 4)), 8, 8)
+ self.downscale_index_formula = (4, 8, 8)
+ self.latent_dim = 3
+ self.latent_channels = ddconfig['z_channels'] = sd["decoder.conv_in.conv.weight"].shape[1]
+ self.first_stage_model = AutoencoderKL(ddconfig=ddconfig, embed_dim=sd['post_quant_conv.weight'].shape[1])
+ #This is likely to significantly over-estimate with single image or low frame counts as the
+ #implementation is able to completely skip caching. Rework if used as an image only VAE
+ self.memory_used_decode = lambda shape, dtype: (2800 * min(8, ((shape[2] - 1) * 4) + 1) * shape[3] * shape[4] * (8 * 8)) * model_management.dtype_size(dtype)
+ self.memory_used_encode = lambda shape, dtype: (1400 * min(9, shape[2]) * shape[3] * shape[4]) * model_management.dtype_size(dtype)
+ self.working_dtypes = [torch.bfloat16, torch.float16, torch.float32]
+ elif "decoder.unpatcher3d.wavelets" in sd:
+ self.upscale_ratio = (lambda a: max(0, a * 8 - 7), 8, 8)
+ self.upscale_index_formula = (8, 8, 8)
+ self.downscale_ratio = (lambda a: max(0, math.floor((a + 7) / 8)), 8, 8)
+ self.downscale_index_formula = (8, 8, 8)
+ self.latent_dim = 3
+ self.latent_channels = 16
+ ddconfig = {'z_channels': 16, 'latent_channels': self.latent_channels, 'z_factor': 1, 'resolution': 1024, 'in_channels': 3, 'out_channels': 3, 'channels': 128, 'channels_mult': [2, 4, 4], 'num_res_blocks': 2, 'attn_resolutions': [32], 'dropout': 0.0, 'patch_size': 4, 'num_groups': 1, 'temporal_compression': 8, 'spacial_compression': 8}
+ self.first_stage_model = comfy.ldm.cosmos.vae.CausalContinuousVideoTokenizer(**ddconfig)
+ #TODO: these values are a bit off because this is not a standard VAE
+ self.memory_used_decode = lambda shape, dtype: (50 * shape[2] * shape[3] * shape[4] * (8 * 8 * 8)) * model_management.dtype_size(dtype)
+ self.memory_used_encode = lambda shape, dtype: (50 * (round((shape[2] + 7) / 8) * 8) * shape[3] * shape[4]) * model_management.dtype_size(dtype)
+ self.working_dtypes = [torch.bfloat16, torch.float32]
+ elif "decoder.middle.0.residual.0.gamma" in sd:
+ if "decoder.upsamples.0.upsamples.0.residual.2.weight" in sd: # Wan 2.2 VAE
+ self.upscale_ratio = (lambda a: max(0, a * 4 - 3), 16, 16)
+ self.upscale_index_formula = (4, 16, 16)
+ self.downscale_ratio = (lambda a: max(0, math.floor((a + 3) / 4)), 16, 16)
+ self.downscale_index_formula = (4, 16, 16)
+ self.latent_dim = 3
+ self.latent_channels = 48
+ ddconfig = {"dim": 160, "z_dim": self.latent_channels, "dim_mult": [1, 2, 4, 4], "num_res_blocks": 2, "attn_scales": [], "temperal_downsample": [False, True, True], "dropout": 0.0}
+ self.first_stage_model = comfy.ldm.wan.vae2_2.WanVAE(**ddconfig)
+ self.working_dtypes = [torch.bfloat16, torch.float16, torch.float32]
+ self.memory_used_encode = lambda shape, dtype: 3300 * shape[3] * shape[4] * model_management.dtype_size(dtype)
+ self.memory_used_decode = lambda shape, dtype: 8000 * shape[3] * shape[4] * (16 * 16) * model_management.dtype_size(dtype)
+ else: # Wan 2.1 VAE
+ dim = sd["decoder.head.0.gamma"].shape[0]
+ self.upscale_ratio = (lambda a: max(0, a * 4 - 3), 8, 8)
+ self.upscale_index_formula = (4, 8, 8)
+ self.downscale_ratio = (lambda a: max(0, math.floor((a + 3) / 4)), 8, 8)
+ self.downscale_index_formula = (4, 8, 8)
+ self.latent_dim = 3
+ self.latent_channels = 16
+ self.output_channels = sd["encoder.conv1.weight"].shape[1]
+ self.conv_out_channels = sd["decoder.head.2.weight"].shape[0]
+ self.pad_channel_value = 1.0
+ ddconfig = {"dim": dim, "z_dim": self.latent_channels, "dim_mult": [1, 2, 4, 4], "num_res_blocks": 2, "attn_scales": [], "temperal_downsample": [False, True, True], "image_channels": self.output_channels, "conv_out_channels": self.conv_out_channels, "dropout": 0.0}
+ self.first_stage_model = comfy.ldm.wan.vae.WanVAE(**ddconfig)
+ self.working_dtypes = [torch.bfloat16, torch.float16, torch.float32]
+ self.memory_used_encode = lambda shape, dtype: (1500 if shape[2]<=4 else 6000) * shape[3] * shape[4] * model_management.dtype_size(dtype)
+ self.memory_used_decode = lambda shape, dtype: (2200 if shape[2]<=4 else 7000) * shape[3] * shape[4] * (8*8) * model_management.dtype_size(dtype)
+
+
+ # Hunyuan 3d v2 2.0 & 2.1
+ elif "geo_decoder.cross_attn_decoder.ln_1.bias" in sd:
+
+ self.latent_dim = 1
+
+ def estimate_memory(shape, dtype, num_layers = 16, kv_cache_multiplier = 2):
+ batch, num_tokens, hidden_dim = shape
+ dtype_size = model_management.dtype_size(dtype)
+
+ total_mem = batch * num_tokens * hidden_dim * dtype_size * (1 + kv_cache_multiplier * num_layers)
+ return total_mem
+
+ # better memory estimations
+ self.memory_used_encode = lambda shape, dtype, num_layers = 8, kv_cache_multiplier = 0:\
+ estimate_memory(shape, dtype, num_layers, kv_cache_multiplier)
+
+ self.memory_used_decode = lambda shape, dtype, num_layers = 16, kv_cache_multiplier = 2: \
+ estimate_memory(shape, dtype, num_layers, kv_cache_multiplier)
+
+ self.first_stage_model = comfy.ldm.hunyuan3d.vae.ShapeVAE()
+ self.working_dtypes = [torch.float16, torch.bfloat16, torch.float32]
+
+
+ elif "vocoder.backbone.channel_layers.0.0.bias" in sd: #Ace Step Audio
+ self.first_stage_model = comfy.ldm.ace.vae.music_dcae_pipeline.MusicDCAE(source_sample_rate=44100)
+ self.memory_used_encode = lambda shape, dtype: (shape[2] * 330) * model_management.dtype_size(dtype)
+ self.memory_used_decode = lambda shape, dtype: (shape[2] * shape[3] * 87000) * model_management.dtype_size(dtype)
+ self.latent_channels = 8
+ self.output_channels = 2
+ self.pad_channel_value = "replicate"
+ self.upscale_ratio = 4096
+ self.downscale_ratio = 4096
+ self.latent_dim = 2
+ self.process_output = lambda audio: audio
+ self.process_input = lambda audio: audio
+ self.working_dtypes = [torch.bfloat16, torch.float16, torch.float32]
+ self.disable_offload = True
+ self.extra_1d_channel = 16
+ elif "pixel_space_vae" in sd:
+ self.first_stage_model = comfy.pixel_space_convert.PixelspaceConversionVAE()
+ self.memory_used_encode = lambda shape, dtype: (1 * shape[2] * shape[3]) * model_management.dtype_size(dtype)
+ self.memory_used_decode = lambda shape, dtype: (1 * shape[2] * shape[3]) * model_management.dtype_size(dtype)
+ self.downscale_ratio = 1
+ self.upscale_ratio = 1
+ self.latent_channels = 3
+ self.latent_dim = 2
+ self.output_channels = 3
+ self.disable_offload = True
+ elif "vocoder.activation_post.downsample.lowpass.filter" in sd: #MMAudio VAE
+ sample_rate = 16000
+ if sample_rate == 16000:
+ mode = '16k'
+ else:
+ mode = '44k'
+
+ self.first_stage_model = comfy.ldm.mmaudio.vae.autoencoder.AudioAutoencoder(mode=mode)
+ self.memory_used_encode = lambda shape, dtype: (30 * shape[2]) * model_management.dtype_size(dtype)
+ self.memory_used_decode = lambda shape, dtype: (90 * shape[2] * 1411.2) * model_management.dtype_size(dtype)
+ self.latent_channels = 20
+ self.output_channels = 2
+ self.upscale_ratio = 512 * (44100 / sample_rate)
+ self.downscale_ratio = 512 * (44100 / sample_rate)
+ self.latent_dim = 1
+ self.process_output = lambda audio: audio
+ self.process_input = lambda audio: audio
+ self.working_dtypes = [torch.float32]
+ self.crop_input = False
+ elif "decoder.22.bias" in sd: # taehv, taew and lighttae
+ self.latent_channels = sd["decoder.1.weight"].shape[1]
+ self.latent_dim = 3
+ self.upscale_ratio = (lambda a: max(0, a * 4 - 3), 16, 16)
+ self.upscale_index_formula = (4, 16, 16)
+ self.downscale_ratio = (lambda a: max(0, math.floor((a + 3) / 4)), 16, 16)
+ self.downscale_index_formula = (4, 16, 16)
+ if self.latent_channels in [48, 128]: # Wan 2.2 and LTX2
+ self.first_stage_model = comfy.taesd.taehv.TAEHV(latent_channels=self.latent_channels, latent_format=None) # taehv doesn't need scaling
+ self.process_input = self.process_output = lambda image: image
+ self.process_output = lambda image: image
+ self.memory_used_decode = lambda shape, dtype: (1800 * (max(1, (shape[-3] ** 0.7 * 0.1)) * shape[-2] * shape[-1] * 16 * 16) * model_management.dtype_size(dtype))
+ elif self.latent_channels == 32 and sd["decoder.22.bias"].shape[0] == 12: # lighttae_hv15
+ self.first_stage_model = comfy.taesd.taehv.TAEHV(latent_channels=self.latent_channels, latent_format=comfy.latent_formats.HunyuanVideo15)
+ self.memory_used_decode = lambda shape, dtype: (1200 * (max(1, (shape[-3] ** 0.7 * 0.05)) * shape[-2] * shape[-1] * 32 * 32) * model_management.dtype_size(dtype))
+ else:
+ if sd["decoder.1.weight"].dtype == torch.float16: # taehv currently only available in float16, so assume it's not lighttaew2_1 as otherwise state dicts are identical
+ latent_format=comfy.latent_formats.HunyuanVideo
+ else:
+ latent_format=None # lighttaew2_1 doesn't need scaling
+ self.first_stage_model = comfy.taesd.taehv.TAEHV(latent_channels=self.latent_channels, latent_format=latent_format)
+ self.process_input = self.process_output = lambda image: image
+ self.upscale_ratio = (lambda a: max(0, a * 4 - 3), 8, 8)
+ self.upscale_index_formula = (4, 8, 8)
+ self.downscale_ratio = (lambda a: max(0, math.floor((a + 3) / 4)), 8, 8)
+ self.downscale_index_formula = (4, 8, 8)
+ self.memory_used_encode = lambda shape, dtype: (700 * (max(1, (shape[-3] ** 0.66 * 0.11)) * shape[-2] * shape[-1]) * model_management.dtype_size(dtype))
+ self.memory_used_decode = lambda shape, dtype: (50 * (max(1, (shape[-3] ** 0.65 * 0.26)) * shape[-2] * shape[-1] * 32 * 32) * model_management.dtype_size(dtype))
+ elif "vocoder.resblocks.0.convs1.0.weight" in sd or "vocoder.vocoder.resblocks.0.convs1.0.weight" in sd: # LTX Audio
+ sd = comfy.utils.state_dict_prefix_replace(sd, {"audio_vae.": "autoencoder."})
+ self.first_stage_model = comfy.ldm.lightricks.vae.audio_vae.AudioVAE(metadata=metadata)
+ self.memory_used_encode = lambda shape, dtype: (shape[2] * 330) * model_management.dtype_size(dtype)
+ self.memory_used_decode = lambda shape, dtype: (shape[2] * shape[3] * 87000) * model_management.dtype_size(dtype)
+ self.latent_channels = self.first_stage_model.latent_channels
+ self.audio_sample_rate_output = self.first_stage_model.output_sample_rate
+ self.autoencoder = self.first_stage_model.autoencoder # TODO: remove hack for ltxv custom nodes
+ self.output_channels = 2
+ self.pad_channel_value = "replicate"
+ self.upscale_ratio = 4096
+ self.downscale_ratio = 4096
+ self.latent_dim = 2
+ self.process_output = lambda audio: audio
+ self.process_input = lambda audio: audio
+ self.working_dtypes = [torch.float32]
+ self.disable_offload = True
+ self.extra_1d_channel = 16
+ elif "decoder.layers.3.transformers.0.pre_norm.alpha" in sd: # Stable Audio 3 VAE
+ if "decoder.layers.3.transformers.11.self_attn.to_out.weight" in sd:
+ config = {"channels": 256, "transformer_depths": 12, "sinusoidal_blocks": 8,
+ "sliding_window": [1, 1], "decoder_conv_mapping": False,
+ "chunk_size": 128, "chunk_midpoint_shift": False}
+ self.memory_used_encode = lambda shape, dtype: (1500 * shape[2]) * model_management.dtype_size(dtype)
+ self.memory_used_decode = lambda shape, dtype: (1500 * shape[2] * 4096) * model_management.dtype_size(dtype)
+ else:
+ config = {"channels": 128, "transformer_depths": 6, "sinusoidal_blocks": 0,
+ "sliding_window": None, "decoder_conv_mapping": True,
+ "chunk_size": 32, "chunk_midpoint_shift": True}
+ self.memory_used_encode = lambda shape, dtype: (72 * shape[2]) * model_management.dtype_size(dtype)
+ self.memory_used_decode = lambda shape, dtype: (72 * shape[2] * 4096) * model_management.dtype_size(dtype)
+
+ self.first_stage_model = comfy.ldm.audio.vae_sa3.SA3AudioVAE(**config)
+ self.latent_channels = 256
+ self.output_channels = 2
+ self.upscale_ratio = 4096
+ self.downscale_ratio = 4096
+ self.latent_dim = 1
+ self.audio_sample_rate = 44100
+ self.process_output = lambda audio: audio
+ self.process_input = lambda audio: audio
+ self.working_dtypes = [torch.bfloat16, torch.float16, torch.float32]
+ #This VAE has Parameters and Buffers the non-dynamic caster cannot handle
+ #Force cast it for --disable-dynamic-vram users until there is a true core fix.
+ if not comfy.memory_management.aimdo_enabled:
+ self.disable_offload = True
+ elif "decoder.transformer_blocks.0.scale1" in sd and "encoder.down.5.block.0.conv1.weight" in sd: # MiniMax H3 video VAE
+ self.first_stage_model = comfy.ldm.minimax.vae.MiniMaxH3VideoVAE()
+ self.latent_channels = 24
+ self.latent_dim = 3
+ # frames 17k+5 <-> latents 5k+2, 16x spatial
+ self.upscale_ratio = (lambda a: max(1, (a - 2) // 5 * 17 + 5), 16, 16)
+ self.upscale_index_formula = (4, 16, 16)
+ self.downscale_ratio = (lambda a: max(1, (a - 5) // 17 * 5 + 2) if a > 1 else 1, 16, 16)
+ self.downscale_index_formula = (4, 16, 16)
+ self.working_dtypes = [torch.float16, torch.float32]
+ # the model tiles internally (256px spatial, 17-frame temporal chunks)
+ self.handles_tiling = True
+ def estimate_encode_memory(frames, height, width, dtype):
+ fixed = 110_000_000 if frames == 1 else 1_300_000_000
+ elements_per_pixel = 7 if frames == 1 else 9.5
+ return (elements_per_pixel * frames * height * width + fixed) * model_management.dtype_size(dtype) * 1.03
+
+ def estimate_decode_memory(frames, height, width, dtype):
+ fixed = 110_000_000 if frames <= 22 else 270_000_000
+ return (9.5 * frames * height * width + fixed) * model_management.dtype_size(dtype) * 1.03
+
+ self.memory_used_encode = lambda shape, dtype: estimate_encode_memory(shape[2], shape[3], shape[4], dtype)
+ self.memory_used_decode = lambda shape, dtype: estimate_decode_memory(self.upscale_ratio[0](shape[2]), shape[3] * self.upscale_ratio[1], shape[4] * self.upscale_ratio[2], dtype)
+ elif "pre_block.attn.zero_k_bias" in sd: # MiniMax H3 audio VAE (DAC encoder + BigVGAN decoder)
+ self.first_stage_model = comfy.ldm.minimax.audio_vae.MiniMaxH3AudioVAE()
+ self.latent_channels = 32
+ self.output_channels = 2
+ self.pad_channel_value = "replicate"
+ self.audio_sample_rate = 32000
+ self.upscale_ratio = 800
+ self.downscale_ratio = 800
+ self.latent_dim = 2 # [B, 32, stereo 2, T]
+ self.process_output = lambda audio: audio
+ self.process_input = lambda audio: audio
+ self.working_dtypes = [torch.float32]
+ # encode gets the waveform shape [B, 2, samples], decode the latent shape [B, 32, 2, T]
+ def estimate_encode_memory(samples, dtype):
+ return (900 * samples + 105_000_000) * model_management.dtype_size(dtype) * 1.03
+
+ def estimate_decode_memory(samples, dtype):
+ return max(42_000_000, 220 * samples + 20_000_000) * model_management.dtype_size(dtype) * 1.03
+
+ self.memory_used_encode = lambda shape, dtype: estimate_encode_memory(shape[2], dtype)
+ self.memory_used_decode = lambda shape, dtype: estimate_decode_memory(shape[-1] * self.upscale_ratio, dtype)
+ elif "gs.base_offset_scale" in sd and "octree.out_proj.weight" in sd: # TripoSplat octree gaussian decoder
+ self.first_stage_model = comfy.ldm.triposplat.vae.OctreeGaussianDecoder()
+ self.latent_channels = 16
+ self.latent_dim = 1
+ self.working_dtypes = [torch.float16, torch.bfloat16, torch.float32]
+ # The generic VAE.encode/decode path isn't used: VAEDecodeTripoSplat calls the gaussian
+ # decoder directly (structured GaussianSplat objects, not a tensor and reserves VRAM itself from num_gaussians.
+ def _no_generic_io(*args, **kwargs):
+ raise RuntimeError("TripoSplat gaussian decoder: use the 'TripoSplat Decode' (VAEDecodeTripoSplat)")
+ self.memory_used_encode = self.memory_used_decode = _no_generic_io
+ else:
+ logging.warning("WARNING: No VAE weights detected, VAE not initalized.")
+ self.first_stage_model = None
+ return
+ else:
+ self.first_stage_model = AutoencoderKL(**(config['params']))
+ self.first_stage_model = self.first_stage_model.eval()
+
+ if device is None:
+ device = model_management.vae_device()
+ self.device = device
+ offload_device = model_management.vae_offload_device()
+ if dtype is None:
+ dtype = model_management.vae_dtype(self.device, self.working_dtypes)
+ self.vae_dtype = dtype
+ self.first_stage_model.to(self.vae_dtype)
+ model_management.archive_model_dtypes(self.first_stage_model)
+ self.output_device = model_management.intermediate_device()
+
+ mp = comfy.model_patcher.CoreModelPatcher
+ if self.disable_offload:
+ mp = comfy.model_patcher.ModelPatcher
+ self.patcher = mp(self.first_stage_model, load_device=self.device, offload_device=offload_device)
+
+ m, u = self.first_stage_model.load_state_dict(sd, strict=False, assign=self.patcher.is_dynamic())
+ if len(m) > 0:
+ logging.warning("Missing VAE keys {}".format(m))
+
+ if len(u) > 0:
+ logging.debug("Leftover VAE keys {}".format(u))
+
+ logging.info("VAE load device: {}, offload device: {}, dtype: {}".format(self.device, offload_device, self.vae_dtype))
+ self.model_size()
+
+ def model_size(self):
+ if self.size is not None:
+ return self.size
+ self.size = comfy.model_management.module_size(self.first_stage_model)
+ return self.size
+
+ def throw_exception_if_invalid(self):
+ if self.first_stage_model is None:
+ raise RuntimeError("ERROR: VAE is invalid: None\n\nIf the VAE is from a checkpoint loader node your checkpoint does not contain a valid VAE.")
+
+ def vae_encode_crop_pixels(self, pixels):
+ if self.crop_input:
+ downscale_ratio = self.spacial_compression_encode()
+
+ dims = pixels.shape[1:-1]
+ for d in range(len(dims)):
+ x = (dims[d] // downscale_ratio) * downscale_ratio
+ x_offset = (dims[d] % downscale_ratio) // 2
+ if x != dims[d]:
+ pixels = pixels.narrow(d + 1, x_offset, x)
+
+ if pixels.shape[-1] > self.output_channels:
+ pixels = pixels[..., :self.output_channels]
+ elif pixels.shape[-1] < self.output_channels:
+ if self.pad_channel_value is not None:
+ if isinstance(self.pad_channel_value, str):
+ mode = self.pad_channel_value
+ value = None
+ else:
+ mode = "constant"
+ value = self.pad_channel_value
+
+ pixels = torch.nn.functional.pad(pixels, (0, self.output_channels - pixels.shape[-1]), mode=mode, value=value)
+ return pixels
+
+ def vae_output_dtype(self):
+ return model_management.intermediate_dtype()
+
+ def decode_tiled_(self, samples, tile_x=64, tile_y=64, overlap = 16):
+ steps = samples.shape[0] * comfy.utils.get_tiled_scale_steps(samples.shape[3], samples.shape[2], tile_x, tile_y, overlap)
+ steps += samples.shape[0] * comfy.utils.get_tiled_scale_steps(samples.shape[3], samples.shape[2], tile_x // 2, tile_y * 2, overlap)
+ steps += samples.shape[0] * comfy.utils.get_tiled_scale_steps(samples.shape[3], samples.shape[2], tile_x * 2, tile_y // 2, overlap)
+ pbar = comfy.utils.ProgressBar(steps)
+
+ decode_fn = lambda a: self.first_stage_model.decode(a.to(self.vae_dtype).to(self.device)).to(dtype=self.vae_output_dtype())
+ output = self.process_output(
+ (comfy.utils.tiled_scale(samples, decode_fn, tile_x // 2, tile_y * 2, overlap, upscale_amount = self.upscale_ratio, output_device=self.output_device, pbar = pbar) +
+ comfy.utils.tiled_scale(samples, decode_fn, tile_x * 2, tile_y // 2, overlap, upscale_amount = self.upscale_ratio, output_device=self.output_device, pbar = pbar) +
+ comfy.utils.tiled_scale(samples, decode_fn, tile_x, tile_y, overlap, upscale_amount = self.upscale_ratio, output_device=self.output_device, pbar = pbar))
+ / 3.0)
+ return output
+
+ def decode_tiled_1d(self, samples, tile_x=256, overlap=32):
+ if samples.ndim == 3:
+ decode_fn = lambda a: self.first_stage_model.decode(a.to(self.vae_dtype).to(self.device)).to(dtype=self.vae_output_dtype())
+ else:
+ og_shape = samples.shape
+ samples = samples.reshape((og_shape[0], og_shape[1] * og_shape[2], -1))
+ decode_fn = lambda a: self.first_stage_model.decode(a.reshape((-1, og_shape[1], og_shape[2], a.shape[-1])).to(self.vae_dtype).to(self.device)).to(dtype=self.vae_output_dtype())
+
+ return self.process_output(comfy.utils.tiled_scale_multidim(samples, decode_fn, tile=(tile_x,), overlap=overlap, upscale_amount=self.upscale_ratio, out_channels=self.output_channels, output_device=self.output_device))
+
+ def decode_tiled_3d(self, samples, tile_t=999, tile_x=32, tile_y=32, overlap=(1, 8, 8)):
+ decode_fn = lambda a: self.first_stage_model.decode(a.to(self.vae_dtype).to(self.device)).to(dtype=self.vae_output_dtype())
+ return self.process_output(comfy.utils.tiled_scale_multidim(samples, decode_fn, tile=(tile_t, tile_x, tile_y), overlap=overlap, upscale_amount=self.upscale_ratio, out_channels=self.output_channels, index_formulas=self.upscale_index_formula, output_device=self.output_device))
+
+ def _decode_tiled_owned(self, samples, **kwargs):
+ out = self.first_stage_model.decode_tiled(samples.to(self.vae_dtype).to(self.device), **kwargs)
+ return self.process_output(out.to(device=self.output_device, dtype=self.vae_output_dtype(), copy=True))
+
+ def encode_tiled_(self, pixel_samples, tile_x=512, tile_y=512, overlap = 64):
+ steps = pixel_samples.shape[0] * comfy.utils.get_tiled_scale_steps(pixel_samples.shape[3], pixel_samples.shape[2], tile_x, tile_y, overlap)
+ steps += pixel_samples.shape[0] * comfy.utils.get_tiled_scale_steps(pixel_samples.shape[3], pixel_samples.shape[2], tile_x // 2, tile_y * 2, overlap)
+ steps += pixel_samples.shape[0] * comfy.utils.get_tiled_scale_steps(pixel_samples.shape[3], pixel_samples.shape[2], tile_x * 2, tile_y // 2, overlap)
+ pbar = comfy.utils.ProgressBar(steps)
+
+ encode_fn = lambda a: self.first_stage_model.encode((self.process_input(a)).to(self.vae_dtype).to(self.device)).to(dtype=self.vae_output_dtype())
+ samples = comfy.utils.tiled_scale(pixel_samples, encode_fn, tile_x, tile_y, overlap, upscale_amount = (1/self.downscale_ratio), out_channels=self.latent_channels, output_device=self.output_device, pbar=pbar)
+ samples += comfy.utils.tiled_scale(pixel_samples, encode_fn, tile_x * 2, tile_y // 2, overlap, upscale_amount = (1/self.downscale_ratio), out_channels=self.latent_channels, output_device=self.output_device, pbar=pbar)
+ samples += comfy.utils.tiled_scale(pixel_samples, encode_fn, tile_x // 2, tile_y * 2, overlap, upscale_amount = (1/self.downscale_ratio), out_channels=self.latent_channels, output_device=self.output_device, pbar=pbar)
+ samples /= 3.0
+ return samples
+
+ def encode_tiled_1d(self, samples, tile_x=256 * 2048, overlap=64 * 2048):
+ if self.latent_dim == 1:
+ encode_fn = lambda a: self.first_stage_model.encode((self.process_input(a)).to(self.vae_dtype).to(self.device)).to(dtype=self.vae_output_dtype())
+ out_channels = self.latent_channels
+ upscale_amount = 1 / self.downscale_ratio
+ else:
+ extra_channel_size = self.extra_1d_channel
+ out_channels = self.latent_channels * extra_channel_size
+ tile_x = tile_x // extra_channel_size
+ overlap = overlap // extra_channel_size
+ upscale_amount = 1 / self.downscale_ratio
+ encode_fn = lambda a: self.first_stage_model.encode((self.process_input(a)).to(self.vae_dtype).to(self.device)).reshape(1, out_channels, -1).to(dtype=self.vae_output_dtype())
+
+ out = comfy.utils.tiled_scale_multidim(samples, encode_fn, tile=(tile_x,), overlap=overlap, upscale_amount=upscale_amount, out_channels=out_channels, output_device=self.output_device)
+ if self.latent_dim == 1:
+ return out
+ else:
+ return out.reshape(samples.shape[0], self.latent_channels, extra_channel_size, -1)
+
+ def encode_tiled_3d(self, samples, tile_t=9999, tile_x=512, tile_y=512, overlap=(1, 64, 64)):
+ encode_fn = lambda a: self.first_stage_model.encode((self.process_input(a)).to(self.vae_dtype).to(self.device)).to(dtype=self.vae_output_dtype())
+ return comfy.utils.tiled_scale_multidim(samples, encode_fn, tile=(tile_t, tile_x, tile_y), overlap=overlap, upscale_amount=self.downscale_ratio, out_channels=self.latent_channels, downscale=True, index_formulas=self.downscale_index_formula, output_device=self.output_device)
+
+ def _encode_tiled_owned(self, pixel_samples, **kwargs):
+ x = self.process_input(pixel_samples).to(self.vae_dtype).to(self.device)
+ out = self.first_stage_model.encode_tiled(x, **kwargs)
+ return out.to(device=self.output_device, dtype=self.vae_output_dtype())
+
+ def _owned_tiled_args(self, tile_x=None, tile_y=None, overlap=None, tile_t=None, overlap_t=None):
+ args = {}
+ if tile_x is not None:
+ args["tile_x"] = tile_x
+ if tile_y is not None:
+ args["tile_y"] = tile_y
+ if overlap is not None:
+ args["overlap"] = overlap
+ if tile_t is not None:
+ args["tile_t"] = tile_t
+ if overlap_t is not None:
+ args["overlap_t"] = overlap_t
+ return args
+
+ def decode(self, samples_in, vae_options={}):
+ self.throw_exception_if_invalid()
+ pixel_samples = None
+ do_tile = False
+ if self.latent_dim == 2 and samples_in.ndim == 5:
+ samples_in = samples_in[:, :, 0]
+
+ with model_management.cuda_device_context(self.device):
+ try:
+ memory_used = self.memory_used_decode(samples_in.shape, self.vae_dtype)
+ model_management.load_models_gpu([self.patcher], memory_required=memory_used, force_full_load=self.disable_offload)
+ free_memory = self.patcher.get_free_memory(self.device)
+ batch_number = int(free_memory / memory_used)
+ batch_number = max(1, batch_number)
+
+ # Pre-allocate output for VAEs that support direct buffer writes
+ preallocated = False
+ if getattr(self.first_stage_model, 'comfy_has_chunked_io', False):
+ pixel_samples = torch.empty(self.first_stage_model.decode_output_shape(samples_in.shape), device=self.output_device, dtype=self.vae_output_dtype())
+ preallocated = True
+
+ for x in range(0, samples_in.shape[0], batch_number):
+ samples = samples_in[x:x + batch_number].to(device=self.device, dtype=self.vae_dtype)
+ if preallocated:
+ self.first_stage_model.decode(samples, output_buffer=pixel_samples[x:x+batch_number], **vae_options)
+ else:
+ out = self.first_stage_model.decode(samples, **vae_options).to(device=self.output_device, dtype=self.vae_output_dtype(), copy=True)
+ if pixel_samples is None:
+ pixel_samples = torch.empty((samples_in.shape[0],) + tuple(out.shape[1:]), device=self.output_device, dtype=self.vae_output_dtype())
+ pixel_samples[x:x+batch_number].copy_(out)
+ del out
+ self.process_output(pixel_samples[x:x+batch_number])
+ except Exception as e:
+ model_management.raise_non_oom(e)
+ logging.warning("Warning: Ran out of memory when regular VAE decoding, retrying with tiled VAE decoding.")
+ #NOTE: We don't know what tensors were allocated to stack variables at the time of the
+ #exception and the exception itself refs them all until we get out of this except block.
+ #So we just set a flag for tiler fallback so that tensor gc can happen once the
+ #exception is fully off the books.
+ do_tile = True
+
+ if do_tile:
+ comfy.model_management.soft_empty_cache()
+ dims = samples_in.ndim - 2
+ if dims == 1 or self.extra_1d_channel is not None:
+ pixel_samples = self.decode_tiled_1d(samples_in)
+ elif dims == 2:
+ if self.handles_tiling:
+ tile = 256 // self.spacial_compression_decode()
+ overlap = tile // 4
+ pixel_samples = self._decode_tiled_owned(samples_in, tile_x=tile, tile_y=tile, overlap=overlap)
+ else:
+ pixel_samples = self.decode_tiled_(samples_in)
+ elif dims == 3:
+ tile = 256 // self.spacial_compression_decode()
+ overlap = tile // 4
+ if self.handles_tiling:
+ pixel_samples = self._decode_tiled_owned(samples_in, tile_x=tile, tile_y=tile, overlap=overlap)
+ else:
+ pixel_samples = self.decode_tiled_3d(samples_in, tile_x=tile, tile_y=tile, overlap=(1, overlap, overlap))
+
+ pixel_samples = pixel_samples.to(self.output_device).movedim(1,-1)
+ return pixel_samples
+
+ def decode_tiled(self, samples, tile_x=None, tile_y=None, overlap=None, tile_t=None, overlap_t=None):
+ self.throw_exception_if_invalid()
+ memory_used = self.memory_used_decode(samples.shape, self.vae_dtype) #TODO: calculate mem required for tile
+ model_management.load_models_gpu([self.patcher], memory_required=memory_used, force_full_load=self.disable_offload)
+ dims = samples.ndim - 2
+ args = {}
+ if tile_x is not None:
+ args["tile_x"] = tile_x
+ if tile_y is not None:
+ args["tile_y"] = tile_y
+ if overlap is not None:
+ args["overlap"] = overlap
+
+ with model_management.cuda_device_context(self.device):
+ if self.handles_tiling and dims in (2, 3):
+ output = self._decode_tiled_owned(samples, **self._owned_tiled_args(tile_x, tile_y, overlap, tile_t, overlap_t))
+ elif dims == 1 or self.extra_1d_channel is not None:
+ args.pop("tile_y")
+ output = self.decode_tiled_1d(samples, **args)
+ elif dims == 2:
+ output = self.decode_tiled_(samples, **args)
+ elif dims == 3:
+ if overlap_t is None:
+ args["overlap"] = (1, overlap, overlap)
+ else:
+ args["overlap"] = (max(1, overlap_t), overlap, overlap)
+ if tile_t is not None:
+ args["tile_t"] = max(2, tile_t)
+
+ output = self.decode_tiled_3d(samples, **args)
+ return output.movedim(1, -1)
+
+ def encode(self, pixel_samples):
+ self.throw_exception_if_invalid()
+ pixel_samples = self.vae_encode_crop_pixels(pixel_samples)
+ pixel_samples = pixel_samples.movedim(-1, 1)
+ do_tile = False
+ if self.latent_dim == 3 and pixel_samples.ndim < 5:
+ if not self.not_video:
+ pixel_samples = pixel_samples.movedim(1, 0).unsqueeze(0)
+ else:
+ pixel_samples = pixel_samples.unsqueeze(2)
+
+ with model_management.cuda_device_context(self.device):
+ try:
+ memory_used = self.memory_used_encode(pixel_samples.shape, self.vae_dtype)
+ model_management.load_models_gpu([self.patcher], memory_required=memory_used, force_full_load=self.disable_offload)
+ free_memory = self.patcher.get_free_memory(self.device)
+ batch_number = int(free_memory / max(1, memory_used))
+ batch_number = max(1, batch_number)
+ samples = None
+ for x in range(0, pixel_samples.shape[0], batch_number):
+ pixels_in = self.process_input(pixel_samples[x:x + batch_number]).to(self.vae_dtype)
+ if getattr(self.first_stage_model, 'comfy_has_chunked_io', False):
+ out = self.first_stage_model.encode(pixels_in, device=self.device)
+ else:
+ pixels_in = pixels_in.to(self.device)
+ out = self.first_stage_model.encode(pixels_in)
+ out = out.to(self.output_device).to(dtype=self.vae_output_dtype())
+ if samples is None:
+ samples = torch.empty((pixel_samples.shape[0],) + tuple(out.shape[1:]), device=self.output_device, dtype=self.vae_output_dtype())
+ samples[x:x + batch_number] = out
+
+ except Exception as e:
+ model_management.raise_non_oom(e)
+ logging.warning("Warning: Ran out of memory when regular VAE encoding, retrying with tiled VAE encoding.")
+ #NOTE: We don't know what tensors were allocated to stack variables at the time of the
+ #exception and the exception itself refs them all until we get out of this except block.
+ #So we just set a flag for tiler fallback so that tensor gc can happen once the
+ #exception is fully off the books.
+ do_tile = True
+
+ if do_tile:
+ comfy.model_management.soft_empty_cache()
+ if self.latent_dim == 3:
+ tile = 256
+ overlap = tile // 4
+ if self.handles_tiling:
+ samples = self._encode_tiled_owned(pixel_samples, tile_x=tile, tile_y=tile, overlap=overlap)
+ else:
+ samples = self.encode_tiled_3d(pixel_samples, tile_x=tile, tile_y=tile, overlap=(1, overlap, overlap))
+ elif self.latent_dim == 1 or self.extra_1d_channel is not None:
+ samples = self.encode_tiled_1d(pixel_samples)
+ else:
+ samples = self.encode_tiled_(pixel_samples)
+
+ if self.format_encoded is not None:
+ samples = self.format_encoded(samples)
+ return samples
+
+ def encode_tiled(self, pixel_samples, tile_x=None, tile_y=None, overlap=None, tile_t=None, overlap_t=None):
+ self.throw_exception_if_invalid()
+ pixel_samples = self.vae_encode_crop_pixels(pixel_samples)
+ dims = self.latent_dim
+ pixel_samples = pixel_samples.movedim(-1, 1)
+ if dims == 3 and pixel_samples.ndim < 5:
+ if not self.not_video:
+ pixel_samples = pixel_samples.movedim(1, 0).unsqueeze(0)
+ else:
+ pixel_samples = pixel_samples.unsqueeze(2)
+
+ memory_used = self.memory_used_encode(pixel_samples.shape, self.vae_dtype) # TODO: calculate mem required for tile
+ model_management.load_models_gpu([self.patcher], memory_required=memory_used, force_full_load=self.disable_offload)
+
+ args = {}
+ if tile_x is not None:
+ args["tile_x"] = tile_x
+ if tile_y is not None:
+ args["tile_y"] = tile_y
+ if overlap is not None:
+ args["overlap"] = overlap
+
+ with model_management.cuda_device_context(self.device):
+ if dims == 1:
+ args.pop("tile_y")
+ samples = self.encode_tiled_1d(pixel_samples, **args)
+ elif dims == 2:
+ samples = self.encode_tiled_(pixel_samples, **args)
+ elif dims == 3:
+ if self.handles_tiling:
+ samples = self._encode_tiled_owned(pixel_samples, **self._owned_tiled_args(tile_x, tile_y, overlap, tile_t, overlap_t))
+ else:
+ if tile_t is not None:
+ tile_t_latent = max(2, self.downscale_ratio[0](tile_t))
+ else:
+ tile_t_latent = 9999
+ args["tile_t"] = self.upscale_ratio[0](tile_t_latent)
+
+ spatial_overlap = overlap if overlap is not None else 64
+ if overlap_t is None:
+ args["overlap"] = (1, spatial_overlap, spatial_overlap)
+ else:
+ args["overlap"] = (self.upscale_ratio[0](max(1, min(tile_t_latent // 2, self.downscale_ratio[0](overlap_t)))), spatial_overlap, spatial_overlap)
+ maximum = pixel_samples.shape[2]
+ maximum = self.upscale_ratio[0](self.downscale_ratio[0](maximum))
+
+ samples = self.encode_tiled_3d(pixel_samples[:,:,:maximum], **args)
+
+ if self.format_encoded is not None:
+ samples = self.format_encoded(samples)
+ return samples
+
+ def get_sd(self):
+ return self.first_stage_model.state_dict()
+
+ def spacial_compression_decode(self):
+ try:
+ return self.upscale_ratio[-1]
+ except:
+ return self.upscale_ratio
+
+ def spacial_compression_encode(self):
+ try:
+ return self.downscale_ratio[-1]
+ except:
+ return self.downscale_ratio
+
+ def temporal_compression_decode(self):
+ try:
+ return round(self.upscale_ratio[0](8192) / 8192)
+ except:
+ return None
+
+ def is_dynamic(self):
+ # A VAE built from a state dict with no detectable VAE weights returns early
+ # from __init__ ("No VAE weights detected") before self.patcher is assigned.
+ patcher = getattr(self, "patcher", None)
+ return patcher is not None and patcher.is_dynamic()
+
+class StyleModel:
+ def __init__(self, model, device="cpu"):
+ self.model = model
+
+ def get_cond(self, input):
+ return self.model(input.last_hidden_state)
+
+
+def load_style_model(ckpt_path):
+ model_data = comfy.utils.load_torch_file(ckpt_path, safe_load=True)
+ keys = model_data.keys()
+ if "style_embedding" in keys:
+ model = comfy.t2i_adapter.adapter.StyleAdapter(width=1024, context_dim=768, num_head=8, n_layes=3, num_token=8)
+ elif "redux_down.weight" in keys:
+ model = comfy.ldm.flux.redux.ReduxImageEncoder()
+ else:
+ raise Exception("invalid style model {}".format(ckpt_path))
+ model.load_state_dict(model_data)
+ return StyleModel(model)
+
+class CLIPType(Enum):
+ STABLE_DIFFUSION = 1
+ STABLE_CASCADE = 2
+ SD3 = 3
+ STABLE_AUDIO = 4
+ HUNYUAN_DIT = 5
+ FLUX = 6
+ MOCHI = 7
+ LTXV = 8
+ HUNYUAN_VIDEO = 9
+ PIXART = 10
+ COSMOS = 11
+ LUMINA2 = 12
+ WAN = 13
+ HIDREAM = 14
+ CHROMA = 15
+ ACE = 16
+ OMNIGEN2 = 17
+ QWEN_IMAGE = 18
+ HUNYUAN_IMAGE = 19
+ HUNYUAN_VIDEO_15 = 20
+ OVIS = 21
+ KANDINSKY5 = 22
+ KANDINSKY5_IMAGE = 23
+ NEWBIE = 24
+ FLUX2 = 25
+ LONGCAT_IMAGE = 26
+ COGVIDEOX = 27
+ LENS = 28
+ PIXELDIT = 29
+ IDEOGRAM4 = 30
+ BOOGU = 31
+ KREA2 = 32
+ JOYIMAGE = 33
+ MAGE = 34
+ MINIMAX = 35
+
+
+
+def load_clip_model_patcher(ckpt_paths, embedding_directory=None, clip_type=CLIPType.STABLE_DIFFUSION, model_options={}, disable_dynamic=False):
+ clip = load_clip(ckpt_paths, embedding_directory, clip_type, model_options, disable_dynamic)
+ return clip.patcher
+
+def load_clip(ckpt_paths, embedding_directory=None, clip_type=CLIPType.STABLE_DIFFUSION, model_options={}, disable_dynamic=False):
+ clip_data = []
+ for p in ckpt_paths:
+ sd, metadata = comfy.utils.load_torch_file(p, safe_load=True, return_metadata=True)
+ if model_options.get("custom_operations", None) is None:
+ sd, metadata = comfy.utils.convert_old_quants(sd, model_prefix="", metadata=metadata)
+ clip_data.append(sd)
+ clip = load_text_encoder_state_dicts(clip_data, embedding_directory=embedding_directory, clip_type=clip_type, model_options=model_options, disable_dynamic=disable_dynamic)
+ clip.patcher.cached_patcher_init = (load_clip_model_patcher, (ckpt_paths, embedding_directory, clip_type, model_options))
+ return clip
+
+
+class TEModel(Enum):
+ CLIP_L = 1
+ CLIP_H = 2
+ CLIP_G = 3
+ T5_XXL = 4
+ T5_XL = 5
+ T5_BASE = 6
+ LLAMA3_8 = 7
+ T5_XXL_OLD = 8
+ GEMMA_2_2B = 9
+ QWEN25_3B = 10
+ QWEN25_7B = 11
+ BYT5_SMALL_GLYPH = 12
+ GEMMA_3_4B = 13
+ MISTRAL3_24B = 14
+ MISTRAL3_24B_PRUNED_FLUX2 = 15
+ QWEN3_4B = 16
+ QWEN3_2B = 17
+ GEMMA_3_12B = 18
+ JINA_CLIP_2 = 19
+ QWEN3_8B = 20
+ QWEN3_06B = 21
+ GEMMA_3_4B_VISION = 22
+ QWEN35_08B = 23
+ QWEN35_2B = 24
+ QWEN35_4B = 25
+ QWEN35_9B = 26
+ QWEN35_27B = 27
+ MINISTRAL_3_3B = 28
+ GEMMA_4_E4B = 29
+ GEMMA_4_E2B = 30
+ GEMMA_4_31B = 31
+ T5_GEMMA = 32
+ GPT_OSS_20B = 33
+ QWEN3VL_4B = 34
+ QWEN3VL_8B = 35
+ GEMMA_4_12B = 36
+ QWEN3VL_32B = 37
+
+
+def detect_te_model(sd):
+ if "text_model.encoder.layers.30.mlp.fc1.weight" in sd:
+ return TEModel.CLIP_G
+ if "text_model.encoder.layers.22.mlp.fc1.weight" in sd:
+ return TEModel.CLIP_H
+ if "text_model.encoder.layers.0.mlp.fc1.weight" in sd:
+ return TEModel.CLIP_L
+ if "model.encoder.layers.0.mixer.Wqkv.weight" in sd:
+ return TEModel.JINA_CLIP_2
+ if "encoder.block.23.layer.1.DenseReluDense.wi_1.weight" in sd:
+ weight = sd["encoder.block.23.layer.1.DenseReluDense.wi_1.weight"]
+ if weight.shape[0] == 10240:
+ return TEModel.T5_XXL
+ elif weight.shape[0] == 5120:
+ return TEModel.T5_XL
+ if 'encoder.block.23.layer.1.DenseReluDense.wi.weight' in sd:
+ return TEModel.T5_XXL_OLD
+ if "encoder.block.0.layer.0.SelfAttention.k.weight" in sd:
+ weight = sd['encoder.block.0.layer.0.SelfAttention.k.weight']
+ if weight.shape[0] == 384:
+ return TEModel.BYT5_SMALL_GLYPH
+ return TEModel.T5_BASE
+ if "model.encoder.layers.0.pre_self_attn_layernorm.weight" in sd:
+ return TEModel.T5_GEMMA
+ if 'model.layers.0.post_feedforward_layernorm.weight' in sd:
+ if 'model.layers.59.self_attn.q_norm.weight' in sd:
+ return TEModel.GEMMA_4_31B
+ # Gemma4 12B Unified: 48 layers, encoder-free; global layers drop v_proj (attention_k_eq_v).
+ if 'model.layers.47.self_attn.q_norm.weight' in sd and 'model.layers.5.self_attn.v_proj.weight' not in sd:
+ return TEModel.GEMMA_4_12B
+ if 'model.layers.41.self_attn.q_norm.weight' in sd and 'model.layers.47.self_attn.q_norm.weight' not in sd:
+ return TEModel.GEMMA_4_E4B
+ if 'model.layers.34.self_attn.q_norm.weight' in sd and 'model.layers.41.self_attn.q_norm.weight' not in sd:
+ return TEModel.GEMMA_4_E2B
+ if 'model.layers.47.self_attn.q_norm.weight' in sd:
+ return TEModel.GEMMA_3_12B
+ if 'model.layers.0.self_attn.q_norm.weight' in sd:
+ if 'vision_model.embeddings.patch_embedding.weight' in sd:
+ return TEModel.GEMMA_3_4B_VISION
+ else:
+ return TEModel.GEMMA_3_4B
+ return TEModel.GEMMA_2_2B
+ # Must precede the Qwen2.5-7B k_proj.bias=512 check (GPT-OSS also has 8*64=512).
+ if "layers.0.self_attn.sinks" in sd and "layers.0.mlp.experts.gate_up_proj.weight" in sd:
+ return TEModel.GPT_OSS_20B
+ if 'model.layers.0.self_attn.k_proj.bias' in sd:
+ weight = sd['model.layers.0.self_attn.k_proj.bias']
+ if weight.shape[0] == 256:
+ return TEModel.QWEN25_3B
+ if weight.shape[0] == 512:
+ return TEModel.QWEN25_7B
+ if "model.language_model.layers.0.linear_attn.A_log" in sd and "model.language_model.layers.0.input_layernorm.weight" in sd:
+ weight = sd['model.language_model.layers.0.input_layernorm.weight']
+ if weight.shape[0] == 1024:
+ return TEModel.QWEN35_08B
+ if weight.shape[0] == 2560:
+ return TEModel.QWEN35_4B
+ if weight.shape[0] == 4096:
+ return TEModel.QWEN35_9B
+ if weight.shape[0] == 5120:
+ return TEModel.QWEN35_27B
+ return TEModel.QWEN35_2B
+ if "model.visual.deepstack_merger_list.0.norm.weight" in sd: # DeepStack is unique to Qwen3-VL
+ return TEModel.QWEN3VL_4B if sd["model.visual.merger.linear_fc2.weight"].shape[0] == 2560 else TEModel.QWEN3VL_8B
+ if "visual.deepstack_merger_list.0.norm.weight" in sd and "model.layers.49.self_attn.q_proj.weight" in sd:
+ # MiniMax H3 conditioning encoder: Qwen3-VL-32B, truncated to 50 layers
+ return TEModel.QWEN3VL_32B
+ if "model.layers.0.post_attention_layernorm.weight" in sd:
+ weight = sd['model.layers.0.post_attention_layernorm.weight']
+ if 'model.layers.0.self_attn.q_norm.weight' in sd:
+ if weight.shape[0] == 2560:
+ return TEModel.QWEN3_4B
+ elif weight.shape[0] == 2048:
+ return TEModel.QWEN3_2B
+ elif weight.shape[0] == 4096:
+ return TEModel.QWEN3_8B
+ elif weight.shape[0] == 1024:
+ return TEModel.QWEN3_06B
+ if weight.shape[0] == 5120:
+ if "model.layers.39.post_attention_layernorm.weight" in sd:
+ return TEModel.MISTRAL3_24B
+ else:
+ return TEModel.MISTRAL3_24B_PRUNED_FLUX2
+ if weight.shape[0] == 3072:
+ return TEModel.MINISTRAL_3_3B
+
+ return TEModel.LLAMA3_8
+ return None
+
+
+def t5xxl_detect(clip_data):
+ weight_name = "encoder.block.23.layer.1.DenseReluDense.wi_1.weight"
+ weight_name_old = "encoder.block.23.layer.1.DenseReluDense.wi.weight"
+
+ for sd in clip_data:
+ if weight_name in sd or weight_name_old in sd:
+ return comfy.text_encoders.sd3_clip.t5_xxl_detect(sd)
+
+ return {}
+
+def llama_detect(clip_data):
+ weight_names = ["model.layers.0.self_attn.k_proj.weight", "model.layers.0.linear_attn.in_proj_a.weight"]
+
+ for sd in clip_data:
+ for weight_name in weight_names:
+ if weight_name in sd:
+ return comfy.text_encoders.hunyuan_video.llama_detect(sd)
+
+ return {}
+
+def load_text_encoder_state_dicts(state_dicts=[], embedding_directory=None, clip_type=CLIPType.STABLE_DIFFUSION, model_options={}, disable_dynamic=False):
+ clip_data = state_dicts
+
+ class EmptyClass:
+ pass
+
+ for i in range(len(clip_data)):
+ if "transformer.resblocks.0.ln_1.weight" in clip_data[i]:
+ clip_data[i] = comfy.utils.clip_text_transformers_convert(clip_data[i], "", "")
+ else:
+ if "text_projection" in clip_data[i]:
+ clip_data[i]["text_projection.weight"] = clip_data[i]["text_projection"].transpose(0, 1) #old models saved with the CLIPSave node
+ if "lm_head.weight" in clip_data[i]:
+ clip_data[i]["model.lm_head.weight"] = clip_data[i].pop("lm_head.weight") # prefix missing in some models
+
+ tokenizer_data = {}
+ clip_target = EmptyClass()
+ clip_target.params = {}
+ if len(clip_data) == 1:
+ te_model = detect_te_model(clip_data[0])
+ if te_model == TEModel.CLIP_G:
+ if clip_type == CLIPType.STABLE_CASCADE:
+ clip_target.clip = sdxl_clip.StableCascadeClipModel
+ clip_target.tokenizer = sdxl_clip.StableCascadeTokenizer
+ elif clip_type == CLIPType.SD3:
+ clip_target.clip = comfy.text_encoders.sd3_clip.sd3_clip(clip_l=False, clip_g=True, t5=False)
+ clip_target.tokenizer = comfy.text_encoders.sd3_clip.SD3Tokenizer
+ elif clip_type == CLIPType.HIDREAM:
+ clip_target.clip = comfy.text_encoders.hidream.hidream_clip(clip_l=False, clip_g=True, t5=False, llama=False, dtype_t5=None, dtype_llama=None)
+ clip_target.tokenizer = comfy.text_encoders.hidream.HiDreamTokenizer
+ else:
+ clip_target.clip = sdxl_clip.SDXLRefinerClipModel
+ clip_target.tokenizer = sdxl_clip.SDXLTokenizer
+ elif te_model == TEModel.CLIP_H:
+ clip_target.clip = comfy.text_encoders.sd2_clip.SD2ClipModel
+ clip_target.tokenizer = comfy.text_encoders.sd2_clip.SD2Tokenizer
+ elif te_model == TEModel.T5_XXL:
+ if clip_type == CLIPType.SD3:
+ clip_target.clip = comfy.text_encoders.sd3_clip.sd3_clip(clip_l=False, clip_g=False, t5=True, **t5xxl_detect(clip_data))
+ clip_target.tokenizer = comfy.text_encoders.sd3_clip.SD3Tokenizer
+ elif clip_type == CLIPType.LTXV:
+ clip_target.clip = comfy.text_encoders.lt.ltxv_te(**t5xxl_detect(clip_data))
+ clip_target.tokenizer = comfy.text_encoders.lt.LTXVT5Tokenizer
+ elif clip_type == CLIPType.PIXART or clip_type == CLIPType.CHROMA:
+ clip_target.clip = comfy.text_encoders.pixart_t5.pixart_te(**t5xxl_detect(clip_data))
+ clip_target.tokenizer = comfy.text_encoders.pixart_t5.PixArtTokenizer
+ elif clip_type == CLIPType.WAN:
+ clip_target.clip = comfy.text_encoders.wan.te(**t5xxl_detect(clip_data))
+ clip_target.tokenizer = comfy.text_encoders.wan.WanT5Tokenizer
+ tokenizer_data["spiece_model"] = clip_data[0].get("spiece_model", None)
+ elif clip_type == CLIPType.HIDREAM:
+ clip_target.clip = comfy.text_encoders.hidream.hidream_clip(**t5xxl_detect(clip_data),
+ clip_l=False, clip_g=False, t5=True, llama=False, dtype_llama=None)
+ clip_target.tokenizer = comfy.text_encoders.hidream.HiDreamTokenizer
+ elif clip_type == CLIPType.COGVIDEOX:
+ clip_target.clip = comfy.text_encoders.cogvideo.cogvideo_te(**t5xxl_detect(clip_data))
+ clip_target.tokenizer = comfy.text_encoders.cogvideo.CogVideoXTokenizer
+ else: #CLIPType.MOCHI
+ clip_target.clip = comfy.text_encoders.genmo.mochi_te(**t5xxl_detect(clip_data))
+ clip_target.tokenizer = comfy.text_encoders.genmo.MochiT5Tokenizer
+ elif te_model == TEModel.T5_XXL_OLD:
+ clip_target.clip = comfy.text_encoders.cosmos.te(**t5xxl_detect(clip_data))
+ clip_target.tokenizer = comfy.text_encoders.cosmos.CosmosT5Tokenizer
+ elif te_model == TEModel.T5_XL:
+ clip_target.clip = comfy.text_encoders.aura_t5.AuraT5Model
+ clip_target.tokenizer = comfy.text_encoders.aura_t5.AuraT5Tokenizer
+ elif te_model == TEModel.T5_BASE:
+ if clip_type == CLIPType.ACE or "spiece_model" in clip_data[0]:
+ clip_target.clip = comfy.text_encoders.ace.AceT5Model
+ clip_target.tokenizer = comfy.text_encoders.ace.AceT5Tokenizer
+ tokenizer_data["spiece_model"] = clip_data[0].get("spiece_model", None)
+ else:
+ clip_target.clip = comfy.text_encoders.sa_t5.SAT5Model
+ clip_target.tokenizer = comfy.text_encoders.sa_t5.SAT5Tokenizer
+ elif te_model == TEModel.T5_GEMMA:
+ clip_target.clip = comfy.text_encoders.sa3.SAT5GemmaModel
+ clip_target.tokenizer = comfy.text_encoders.sa3.SAT5GemmaTokenizer
+ tokenizer_data["spiece_model"] = clip_data[0].get("spiece_model", None)
+ elif te_model in (TEModel.GEMMA_4_E4B, TEModel.GEMMA_4_E2B, TEModel.GEMMA_4_31B, TEModel.GEMMA_4_12B):
+ variant = {TEModel.GEMMA_4_E4B: comfy.text_encoders.gemma4.Gemma4_E4B,
+ TEModel.GEMMA_4_E2B: comfy.text_encoders.gemma4.Gemma4_E2B,
+ TEModel.GEMMA_4_31B: comfy.text_encoders.gemma4.Gemma4_31B,
+ TEModel.GEMMA_4_12B: comfy.text_encoders.gemma4.Gemma4_12B}[te_model]
+ clip_target.clip = comfy.text_encoders.gemma4.gemma4_te(**llama_detect(clip_data), model_class=variant)
+ clip_target.tokenizer = variant.tokenizer
+ tokenizer_data["tokenizer_json"] = clip_data[0].get("tokenizer_json", None)
+ elif te_model == TEModel.GEMMA_2_2B:
+ if clip_type == CLIPType.PIXELDIT:
+ clip_target.clip = comfy.text_encoders.pixeldit.pixeldit_te(**llama_detect(clip_data))
+ clip_target.tokenizer = comfy.text_encoders.pixeldit.PixelDiTGemma2Tokenizer
+ else:
+ clip_target.clip = comfy.text_encoders.lumina2.te(**llama_detect(clip_data))
+ clip_target.tokenizer = comfy.text_encoders.lumina2.LuminaTokenizer
+ tokenizer_data["spiece_model"] = clip_data[0].get("spiece_model", None)
+ elif te_model == TEModel.GEMMA_3_4B:
+ clip_target.clip = comfy.text_encoders.lumina2.te(**llama_detect(clip_data), model_type="gemma3_4b")
+ clip_target.tokenizer = comfy.text_encoders.lumina2.NTokenizer
+ tokenizer_data["spiece_model"] = clip_data[0].get("spiece_model", None)
+ elif te_model == TEModel.GEMMA_3_4B_VISION:
+ clip_target.clip = comfy.text_encoders.lumina2.te(**llama_detect(clip_data), model_type="gemma3_4b_vision")
+ clip_target.tokenizer = comfy.text_encoders.lumina2.NTokenizer
+ tokenizer_data["spiece_model"] = clip_data[0].get("spiece_model", None)
+ elif te_model == TEModel.GEMMA_3_12B:
+ clip_target.clip = comfy.text_encoders.lt.gemma3_te(**llama_detect(clip_data))
+ clip_target.tokenizer = comfy.text_encoders.lt.Gemma3_12BTokenizer
+ tokenizer_data["spiece_model"] = clip_data[0].get("spiece_model", None)
+ elif te_model == TEModel.LLAMA3_8:
+ clip_target.clip = comfy.text_encoders.hidream.hidream_clip(**llama_detect(clip_data),
+ clip_l=False, clip_g=False, t5=False, llama=True, dtype_t5=None)
+ clip_target.tokenizer = comfy.text_encoders.hidream.HiDreamTokenizer
+ elif te_model == TEModel.QWEN25_3B:
+ clip_target.clip = comfy.text_encoders.omnigen2.te(**llama_detect(clip_data))
+ clip_target.tokenizer = comfy.text_encoders.omnigen2.Omnigen2Tokenizer
+ elif te_model == TEModel.QWEN25_7B:
+ if clip_type == CLIPType.HUNYUAN_IMAGE:
+ clip_target.clip = comfy.text_encoders.hunyuan_image.te(byt5=False, **llama_detect(clip_data))
+ clip_target.tokenizer = comfy.text_encoders.hunyuan_image.HunyuanImageTokenizer
+ elif clip_type == CLIPType.LONGCAT_IMAGE:
+ clip_target.clip = comfy.text_encoders.longcat_image.te(**llama_detect(clip_data))
+ clip_target.tokenizer = comfy.text_encoders.longcat_image.LongCatImageTokenizer
+ else:
+ clip_target.clip = comfy.text_encoders.qwen_image.te(**llama_detect(clip_data))
+ clip_target.tokenizer = comfy.text_encoders.qwen_image.QwenImageTokenizer
+ elif te_model == TEModel.MISTRAL3_24B or te_model == TEModel.MISTRAL3_24B_PRUNED_FLUX2:
+ clip_target.clip = comfy.text_encoders.flux.flux2_te(**llama_detect(clip_data), pruned=te_model == TEModel.MISTRAL3_24B_PRUNED_FLUX2)
+ clip_target.tokenizer = comfy.text_encoders.flux.Flux2Tokenizer
+ tokenizer_data["tekken_model"] = clip_data[0].get("tekken_model", None)
+ elif te_model == TEModel.GPT_OSS_20B:
+ clip_target.clip = comfy.text_encoders.gpt_oss.lens_te(**llama_detect(clip_data))
+ clip_target.tokenizer = comfy.text_encoders.gpt_oss.LensTokenizer
+ tokenizer_data["tokenizer_json"] = clip_data[0].get("tokenizer_json", None)
+ elif te_model == TEModel.QWEN3_4B:
+ if clip_type == CLIPType.FLUX or clip_type == CLIPType.FLUX2:
+ clip_target.clip = comfy.text_encoders.flux.klein_te(**llama_detect(clip_data), model_type="qwen3_4b")
+ clip_target.tokenizer = comfy.text_encoders.flux.KleinTokenizer
+ else:
+ clip_target.clip = comfy.text_encoders.z_image.te(**llama_detect(clip_data))
+ clip_target.tokenizer = comfy.text_encoders.z_image.ZImageTokenizer
+ elif te_model == TEModel.QWEN3_2B:
+ clip_target.clip = comfy.text_encoders.ovis.te(**llama_detect(clip_data))
+ clip_target.tokenizer = comfy.text_encoders.ovis.OvisTokenizer
+ elif te_model == TEModel.QWEN3_8B:
+ if clip_type == CLIPType.IDEOGRAM4:
+ clip_target.clip = comfy.text_encoders.ideogram4.te(**llama_detect(clip_data))
+ clip_target.tokenizer = comfy.text_encoders.ideogram4.Ideogram4Tokenizer
+ else:
+ clip_target.clip = comfy.text_encoders.flux.klein_te(**llama_detect(clip_data), model_type="qwen3_8b")
+ clip_target.tokenizer = comfy.text_encoders.flux.KleinTokenizer8B
+ elif te_model == TEModel.JINA_CLIP_2:
+ clip_target.clip = comfy.text_encoders.jina_clip_2.JinaClip2TextModelWrapper
+ clip_target.tokenizer = comfy.text_encoders.jina_clip_2.JinaClip2TokenizerWrapper
+ elif te_model in (TEModel.QWEN35_08B, TEModel.QWEN35_2B, TEModel.QWEN35_4B, TEModel.QWEN35_9B, TEModel.QWEN35_27B):
+ clip_data[0] = comfy.utils.state_dict_prefix_replace(clip_data[0], {"model.language_model.": "model.", "model.visual.": "visual.", "lm_head.": "model.lm_head."})
+ qwen35_type = {TEModel.QWEN35_08B: "qwen35_08b", TEModel.QWEN35_2B: "qwen35_2b", TEModel.QWEN35_4B: "qwen35_4b", TEModel.QWEN35_9B: "qwen35_9b", TEModel.QWEN35_27B: "qwen35_27b"}[te_model]
+ clip_target.clip = comfy.text_encoders.qwen35.te(**llama_detect(clip_data), model_type=qwen35_type)
+ clip_target.tokenizer = comfy.text_encoders.qwen35.tokenizer(model_type=qwen35_type)
+ elif te_model in (TEModel.QWEN3VL_4B, TEModel.QWEN3VL_8B):
+ if clip_type == CLIPType.IDEOGRAM4 and te_model == TEModel.QWEN3VL_8B: # Ideogram4 reuses the full Qwen3-VL-8B (13-layer tap for conditioning + multimodal generate).
+ clip_data[0] = comfy.utils.state_dict_prefix_replace(clip_data[0], {"model.language_model.": "model.", "model.visual.": "visual.", "lm_head.": "model.lm_head."})
+ clip_target.clip = comfy.text_encoders.ideogram4.te_qwen3vl(**llama_detect(clip_data))
+ clip_target.tokenizer = comfy.text_encoders.ideogram4.Ideogram4Qwen3VLTokenizer
+ elif clip_type == CLIPType.BOOGU and te_model == TEModel.QWEN3VL_8B: # Boogu-Image: full Qwen3-VL-8B, last hidden state, no-think template.
+ clip_data[0] = comfy.utils.state_dict_prefix_replace(clip_data[0], {"model.language_model.": "model.", "model.visual.": "visual.", "lm_head.": "model.lm_head."})
+ clip_target.clip = comfy.text_encoders.boogu.te(**llama_detect(clip_data))
+ clip_target.tokenizer = comfy.text_encoders.boogu.BooguTokenizer
+ elif clip_type == CLIPType.KREA2 and te_model == TEModel.QWEN3VL_4B: # Krea2: full Qwen3-VL-4B (12-layer tap for conditioning + multimodal generate).
+ clip_data[0] = comfy.utils.state_dict_prefix_replace(clip_data[0], {"model.language_model.": "model.", "model.visual.": "visual.", "lm_head.": "model.lm_head."})
+ clip_target.clip = comfy.text_encoders.krea2.te(**llama_detect(clip_data))
+ clip_target.tokenizer = comfy.text_encoders.krea2.Krea2Tokenizer
+ elif clip_type == CLIPType.MAGE and te_model == TEModel.QWEN3VL_4B: # Mage-Flow: full Qwen3-VL-4B, last hidden state, Qwen-Image-style templates.
+ clip_data[0] = comfy.utils.state_dict_prefix_replace(clip_data[0], {"model.language_model.": "model.", "model.visual.": "visual.", "lm_head.": "model.lm_head."})
+ clip_target.clip = comfy.text_encoders.mage_flow.te(**llama_detect(clip_data))
+ clip_target.tokenizer = comfy.text_encoders.mage_flow.MageFlowTokenizer
+ elif clip_type == CLIPType.JOYIMAGE and te_model == TEModel.QWEN3VL_8B: # JoyImageEdit: full Qwen3-VL-8B, edit-conditioning template + drop_idx.
+ clip_data[0] = comfy.utils.state_dict_prefix_replace(clip_data[0], {"model.language_model.": "model.", "model.visual.": "visual.", "lm_head.": "model.lm_head."})
+ clip_target.clip = comfy.text_encoders.joyimage.te(**llama_detect(clip_data))
+ clip_target.tokenizer = comfy.text_encoders.joyimage.JoyImageTokenizer
+ elif clip_type in (CLIPType.FLUX, CLIPType.FLUX2): # Flux2 Klein reuses the Qwen3-VL LM (3-layer tap -> 12288); visual unused.
+ klein_model_type = "qwen3_8b" if te_model == TEModel.QWEN3VL_8B else "qwen3_4b"
+ clip_target.clip = comfy.text_encoders.flux.klein_te(**llama_detect(clip_data), model_type=klein_model_type)
+ clip_target.tokenizer = comfy.text_encoders.flux.KleinTokenizer8B if te_model == TEModel.QWEN3VL_8B else comfy.text_encoders.flux.KleinTokenizer
+ else:
+ clip_data[0] = comfy.utils.state_dict_prefix_replace(clip_data[0], {"model.language_model.": "model.", "model.visual.": "visual.", "lm_head.": "model.lm_head."})
+ qwen3vl_type = {TEModel.QWEN3VL_4B: "qwen3vl_4b", TEModel.QWEN3VL_8B: "qwen3vl_8b"}[te_model]
+ clip_target.clip = comfy.text_encoders.qwen3vl.te(**llama_detect(clip_data), model_type=qwen3vl_type)
+ clip_target.tokenizer = comfy.text_encoders.qwen3vl.tokenizer(model_type=qwen3vl_type)
+ elif te_model == TEModel.QWEN3VL_32B:
+ clip_target.clip = comfy.text_encoders.minimax.te(**llama_detect(clip_data))
+ clip_target.tokenizer = comfy.text_encoders.minimax.MiniMaxH3Tokenizer
+ elif te_model == TEModel.QWEN3_06B:
+ clip_target.clip = comfy.text_encoders.anima.te(**llama_detect(clip_data))
+ clip_target.tokenizer = comfy.text_encoders.anima.AnimaTokenizer
+ elif te_model == TEModel.MINISTRAL_3_3B:
+ clip_target.clip = comfy.text_encoders.ernie.te(**llama_detect(clip_data))
+ clip_target.tokenizer = comfy.text_encoders.ernie.ErnieTokenizer
+ tokenizer_data["tekken_model"] = clip_data[0].get("tekken_model", None)
+ else:
+ # clip_l
+ if clip_type == CLIPType.SD3:
+ clip_target.clip = comfy.text_encoders.sd3_clip.sd3_clip(clip_l=True, clip_g=False, t5=False)
+ clip_target.tokenizer = comfy.text_encoders.sd3_clip.SD3Tokenizer
+ elif clip_type == CLIPType.HIDREAM:
+ clip_target.clip = comfy.text_encoders.hidream.hidream_clip(clip_l=True, clip_g=False, t5=False, llama=False, dtype_t5=None, dtype_llama=None)
+ clip_target.tokenizer = comfy.text_encoders.hidream.HiDreamTokenizer
+ else:
+ clip_target.clip = sd1_clip.SD1ClipModel
+ clip_target.tokenizer = sd1_clip.SD1Tokenizer
+ elif len(clip_data) == 2:
+ if clip_type == CLIPType.SD3:
+ te_models = [detect_te_model(clip_data[0]), detect_te_model(clip_data[1])]
+ clip_target.clip = comfy.text_encoders.sd3_clip.sd3_clip(clip_l=TEModel.CLIP_L in te_models, clip_g=TEModel.CLIP_G in te_models, t5=TEModel.T5_XXL in te_models, **t5xxl_detect(clip_data))
+ clip_target.tokenizer = comfy.text_encoders.sd3_clip.SD3Tokenizer
+ elif clip_type == CLIPType.HUNYUAN_DIT:
+ clip_target.clip = comfy.text_encoders.hydit.HyditModel
+ clip_target.tokenizer = comfy.text_encoders.hydit.HyditTokenizer
+ elif clip_type == CLIPType.FLUX:
+ clip_target.clip = comfy.text_encoders.flux.flux_clip(**t5xxl_detect(clip_data))
+ clip_target.tokenizer = comfy.text_encoders.flux.FluxTokenizer
+ elif clip_type == CLIPType.HUNYUAN_VIDEO:
+ clip_target.clip = comfy.text_encoders.hunyuan_video.hunyuan_video_clip(**llama_detect(clip_data))
+ clip_target.tokenizer = comfy.text_encoders.hunyuan_video.HunyuanVideoTokenizer
+ elif clip_type == CLIPType.HIDREAM:
+ # Detect
+ hidream_dualclip_classes = []
+ for hidream_te in clip_data:
+ te_model = detect_te_model(hidream_te)
+ hidream_dualclip_classes.append(te_model)
+
+ clip_l = TEModel.CLIP_L in hidream_dualclip_classes
+ clip_g = TEModel.CLIP_G in hidream_dualclip_classes
+ t5 = TEModel.T5_XXL in hidream_dualclip_classes
+ llama = TEModel.LLAMA3_8 in hidream_dualclip_classes
+
+ # Initialize t5xxl_detect and llama_detect kwargs if needed
+ t5_kwargs = t5xxl_detect(clip_data) if t5 else {}
+ llama_kwargs = llama_detect(clip_data) if llama else {}
+
+ clip_target.clip = comfy.text_encoders.hidream.hidream_clip(clip_l=clip_l, clip_g=clip_g, t5=t5, llama=llama, **t5_kwargs, **llama_kwargs)
+ clip_target.tokenizer = comfy.text_encoders.hidream.HiDreamTokenizer
+ elif clip_type == CLIPType.HUNYUAN_IMAGE:
+ clip_target.clip = comfy.text_encoders.hunyuan_image.te(**llama_detect(clip_data))
+ clip_target.tokenizer = comfy.text_encoders.hunyuan_image.HunyuanImageTokenizer
+ elif clip_type == CLIPType.HUNYUAN_VIDEO_15:
+ clip_target.clip = comfy.text_encoders.hunyuan_image.te(**llama_detect(clip_data))
+ clip_target.tokenizer = comfy.text_encoders.hunyuan_video.HunyuanVideo15Tokenizer
+ elif clip_type == CLIPType.KANDINSKY5:
+ clip_target.clip = comfy.text_encoders.kandinsky5.te(**llama_detect(clip_data))
+ clip_target.tokenizer = comfy.text_encoders.kandinsky5.Kandinsky5Tokenizer
+ elif clip_type == CLIPType.KANDINSKY5_IMAGE:
+ clip_target.clip = comfy.text_encoders.kandinsky5.te(**llama_detect(clip_data))
+ clip_target.tokenizer = comfy.text_encoders.kandinsky5.Kandinsky5TokenizerImage
+ elif clip_type == CLIPType.LTXV:
+ clip_target.clip = comfy.text_encoders.lt.ltxav_te(**llama_detect(clip_data), **comfy.text_encoders.lt.sd_detect(clip_data))
+ clip_target.tokenizer = comfy.text_encoders.lt.LTXAVGemmaTokenizer
+ tokenizer_data["spiece_model"] = clip_data[0].get("spiece_model", None)
+ elif clip_type == CLIPType.NEWBIE:
+ clip_target.clip = comfy.text_encoders.newbie.te(**llama_detect(clip_data))
+ clip_target.tokenizer = comfy.text_encoders.newbie.NewBieTokenizer
+ if "model.layers.0.self_attn.q_norm.weight" in clip_data[0]:
+ clip_data_gemma = clip_data[0]
+ clip_data_jina = clip_data[1]
+ else:
+ clip_data_gemma = clip_data[1]
+ clip_data_jina = clip_data[0]
+ tokenizer_data["gemma_spiece_model"] = clip_data_gemma.get("spiece_model", None)
+ tokenizer_data["jina_spiece_model"] = clip_data_jina.get("spiece_model", None)
+ elif clip_type == CLIPType.ACE:
+ te_models = [detect_te_model(clip_data[0]), detect_te_model(clip_data[1])]
+ if TEModel.QWEN3_4B in te_models:
+ model_type = "qwen3_4b"
+ else:
+ model_type = "qwen3_2b"
+ clip_target.clip = comfy.text_encoders.ace15.te(lm_model=model_type, **llama_detect(clip_data))
+ clip_target.tokenizer = comfy.text_encoders.ace15.ACE15Tokenizer
+ else:
+ clip_target.clip = sdxl_clip.SDXLClipModel
+ clip_target.tokenizer = sdxl_clip.SDXLTokenizer
+ elif len(clip_data) == 3:
+ clip_target.clip = comfy.text_encoders.sd3_clip.sd3_clip(**t5xxl_detect(clip_data))
+ clip_target.tokenizer = comfy.text_encoders.sd3_clip.SD3Tokenizer
+ elif len(clip_data) == 4:
+ clip_target.clip = comfy.text_encoders.hidream.hidream_clip(**t5xxl_detect(clip_data), **llama_detect(clip_data))
+ clip_target.tokenizer = comfy.text_encoders.hidream.HiDreamTokenizer
+
+ parameters = 0
+ for c in clip_data:
+ parameters += comfy.utils.calculate_parameters(c)
+ tokenizer_data, model_options = comfy.text_encoders.long_clipl.model_options_long_clip(c, tokenizer_data, model_options)
+
+ clip = CLIP(clip_target, embedding_directory=embedding_directory, parameters=parameters, tokenizer_data=tokenizer_data, state_dict=clip_data, model_options=model_options, disable_dynamic=disable_dynamic)
+ return clip
+
+def load_gligen(ckpt_path):
+ data = comfy.utils.load_torch_file(ckpt_path, safe_load=True)
+ model = gligen.load_gligen(data)
+ if model_management.should_use_fp16():
+ model = model.half()
+ return comfy.model_patcher.CoreModelPatcher(model, load_device=model_management.get_torch_device(), offload_device=model_management.unet_offload_device())
+
+def model_detection_error_hint(path, state_dict):
+ filename = os.path.basename(path)
+ if 'lora' in filename.lower():
+ return "\nHINT: This seems to be a Lora file and Lora files should be put in the lora folder and loaded with a lora loader node.."
+ return ""
+
+def load_checkpoint(config_path=None, ckpt_path=None, output_vae=True, output_clip=True, embedding_directory=None, state_dict=None, config=None):
+ logging.warning("Warning: The load checkpoint with config function is deprecated and will eventually be removed, please use the other one.")
+ model, clip, vae, _ = load_checkpoint_guess_config(ckpt_path, output_vae=output_vae, output_clip=output_clip, output_clipvision=False, embedding_directory=embedding_directory, output_model=True)
+ #TODO: this function is a mess and should be removed eventually
+ if config is None:
+ with open(config_path, 'r') as stream:
+ config = yaml.safe_load(stream)
+ model_config_params = config['model']['params']
+ clip_config = model_config_params['cond_stage_config']
+
+ if "parameterization" in model_config_params:
+ if model_config_params["parameterization"] == "v":
+ m = model.clone()
+ class ModelSamplingAdvanced(comfy.model_sampling.ModelSamplingDiscrete, comfy.model_sampling.V_PREDICTION):
+ pass
+ m.add_object_patch("model_sampling", ModelSamplingAdvanced(model.model.model_config))
+ model = m
+
+ layer_idx = clip_config.get("params", {}).get("layer_idx", None)
+ if layer_idx is not None:
+ clip.clip_layer(layer_idx)
+
+ return (model, clip, vae)
+
+def load_checkpoint_guess_config(ckpt_path, output_vae=True, output_clip=True, output_clipvision=False, embedding_directory=None, output_model=True, model_options={}, te_model_options={}, disable_dynamic=False):
+ sd, metadata = comfy.utils.load_torch_file(ckpt_path, return_metadata=True)
+ out = load_state_dict_guess_config(sd, output_vae, output_clip, output_clipvision, embedding_directory, output_model, model_options, te_model_options=te_model_options, metadata=metadata, disable_dynamic=disable_dynamic)
+ if out is None:
+ raise RuntimeError("ERROR: Could not detect model type of: {}\n{}".format(ckpt_path, model_detection_error_hint(ckpt_path, sd)))
+ if out[0] is not None:
+ out[0].cached_patcher_init = (load_checkpoint_guess_config, (ckpt_path, False, False, False, embedding_directory, output_model, model_options, te_model_options), 0)
+ # Register reload factories for the CLIP and VAE produced by the same checkpoint so
+ # ModelPatcher.deepclone_multigpu can spawn per-device copies (Select{CLIP,VAE}Device,
+ # MultiGPU work-units, etc.) without falling back to copy.deepcopy of an
+ # already-loaded module.
+ if out[1] is not None and getattr(out[1], "patcher", None) is not None:
+ out[1].patcher.cached_patcher_init = (load_checkpoint_clip_patcher, (ckpt_path, embedding_directory, model_options, te_model_options))
+ if out[2] is not None and getattr(out[2], "patcher", None) is not None:
+ out[2].patcher.cached_patcher_init = (load_checkpoint_vae_patcher, (ckpt_path, embedding_directory, model_options, te_model_options))
+ return out
+
+
+def load_checkpoint_clip_patcher(ckpt_path, embedding_directory=None, model_options={}, te_model_options={}, disable_dynamic=False):
+ """Reload only the CLIP patcher from a checkpoint. Used as the cached_patcher_init
+ factory for the CLIP returned by load_checkpoint_guess_config."""
+ _, clip, _, _ = load_checkpoint_guess_config(
+ ckpt_path,
+ output_vae=False,
+ output_clip=True,
+ output_clipvision=False,
+ embedding_directory=embedding_directory,
+ output_model=False,
+ model_options=model_options,
+ te_model_options=te_model_options,
+ disable_dynamic=disable_dynamic,
+ )
+ return clip.patcher
+
+
+def load_checkpoint_vae_patcher(ckpt_path, embedding_directory=None, model_options={}, te_model_options={}, disable_dynamic=False):
+ """Reload only the VAE patcher from a checkpoint. Used as the cached_patcher_init
+ factory for the VAE returned by load_checkpoint_guess_config."""
+ _, _, vae, _ = load_checkpoint_guess_config(
+ ckpt_path,
+ output_vae=True,
+ output_clip=False,
+ output_clipvision=False,
+ embedding_directory=embedding_directory,
+ output_model=False,
+ model_options=model_options,
+ te_model_options=te_model_options,
+ disable_dynamic=disable_dynamic,
+ )
+ return vae.patcher
+
+def load_checkpoint_guess_config_model_only(ckpt_path, embedding_directory=None, model_options={}, te_model_options={}, disable_dynamic=False):
+ model, *_ = load_checkpoint_guess_config(ckpt_path, False, False, False,
+ embedding_directory=embedding_directory,
+ model_options=model_options,
+ te_model_options=te_model_options,
+ disable_dynamic=disable_dynamic)
+ return model
+
+def load_checkpoint_guess_config_clip_only(ckpt_path, embedding_directory=None, model_options={}, te_model_options={}, disable_dynamic=False):
+ _, clip, *_ = load_checkpoint_guess_config(ckpt_path, False, True, False,
+ embedding_directory=embedding_directory, output_model=False,
+ model_options=model_options,
+ te_model_options=te_model_options,
+ disable_dynamic=disable_dynamic)
+ return clip.patcher
+
+def load_state_dict_guess_config(sd, output_vae=True, output_clip=True, output_clipvision=False, embedding_directory=None, output_model=True, model_options={}, te_model_options={}, metadata=None, disable_dynamic=False):
+ clip = None
+ clipvision = None
+ vae = None
+ model = None
+ model_patcher = None
+
+ diffusion_model_prefix = model_detection.unet_prefix_from_state_dict(sd)
+ parameters = comfy.utils.calculate_parameters(sd, diffusion_model_prefix)
+ weight_dtype = comfy.utils.weight_dtype(sd, diffusion_model_prefix)
+ load_device = model_options.get("load_device", model_management.get_torch_device())
+
+ custom_operations = model_options.get("custom_operations", None)
+ if custom_operations is None:
+ sd, metadata = comfy.utils.convert_old_quants(sd, diffusion_model_prefix, metadata=metadata)
+
+ model_config = model_detection.model_config_from_unet(sd, diffusion_model_prefix, metadata=metadata)
+ if model_config is None:
+ logging.warning("Warning, This is not a checkpoint file, trying to load it as a diffusion model only.")
+ diffusion_model = load_diffusion_model_state_dict(sd, model_options={})
+ if diffusion_model is None:
+ return None
+ return (diffusion_model, None, VAE(sd={}), None) # The VAE object is there to throw an exception if it's actually used'
+
+ unet_weight_dtype = list(model_config.supported_inference_dtypes)
+ if model_config.quant_config is not None:
+ weight_dtype = None
+
+ if custom_operations is not None:
+ model_config.custom_operations = custom_operations
+
+ unet_dtype = model_options.get("dtype", model_options.get("weight_dtype", None))
+
+ if unet_dtype is None:
+ unet_dtype = model_management.unet_dtype(model_params=parameters, supported_dtypes=unet_weight_dtype, weight_dtype=weight_dtype)
+
+ if model_config.quant_config is not None:
+ manual_cast_dtype = model_management.unet_manual_cast(None, load_device, model_config.supported_inference_dtypes)
+ else:
+ manual_cast_dtype = model_management.unet_manual_cast(unet_dtype, load_device, model_config.supported_inference_dtypes)
+ model_config.set_inference_dtype(unet_dtype, manual_cast_dtype, device=load_device)
+
+ if model_config.clip_vision_prefix is not None:
+ if output_clipvision:
+ clipvision = clip_vision.load_clipvision_from_sd(sd, model_config.clip_vision_prefix, True)
+
+ if output_model:
+ inital_load_device = model_management.unet_inital_load_device(parameters, unet_dtype)
+ model = model_config.get_model(sd, diffusion_model_prefix, device=inital_load_device)
+ ModelPatcher = comfy.model_patcher.ModelPatcher if disable_dynamic else comfy.model_patcher.CoreModelPatcher
+ offload_device = model_options.get("offload_device", model_management.unet_offload_device())
+ model_patcher = ModelPatcher(model, load_device=load_device, offload_device=offload_device)
+ model.load_model_weights(sd, diffusion_model_prefix, assign=model_patcher.is_dynamic())
+
+ if output_vae:
+ vae_sd = comfy.utils.state_dict_prefix_replace(sd, {k: "" for k in model_config.vae_key_prefix}, filter_keys=True)
+ vae_sd = model_config.process_vae_state_dict(vae_sd)
+ vae_device = model_options.get("load_device", None)
+ vae = VAE(sd=vae_sd, metadata=metadata, device=vae_device)
+
+ if output_clip:
+ if te_model_options.get("custom_operations", None) is None:
+ scaled_fp8_list = []
+ for k in list(sd.keys()): # Convert scaled fp8 to mixed ops
+ if k.endswith(".scaled_fp8"):
+ scaled_fp8_list.append(k[:-len("scaled_fp8")])
+
+ if len(scaled_fp8_list) > 0:
+ out_sd = {}
+ for k in sd:
+ skip = False
+ for pref in scaled_fp8_list:
+ skip = skip or k.startswith(pref)
+ if not skip:
+ out_sd[k] = sd[k]
+
+ for pref in scaled_fp8_list:
+ quant_sd, qmetadata = comfy.utils.convert_old_quants(sd, pref, metadata={})
+ for k in quant_sd:
+ out_sd[k] = quant_sd[k]
+ sd = out_sd
+
+ clip_target = model_config.clip_target(state_dict=sd)
+ if clip_target is not None:
+ clip_sd = model_config.process_clip_state_dict(sd)
+ if len(clip_sd) > 0:
+ parameters = comfy.utils.calculate_parameters(clip_sd)
+ clip = CLIP(clip_target, embedding_directory=embedding_directory, tokenizer_data=clip_sd, parameters=parameters, state_dict=clip_sd, model_options=te_model_options, disable_dynamic=disable_dynamic)
+ else:
+ logging.warning("no CLIP/text encoder weights in checkpoint, the text encoder model will not be loaded.")
+
+ left_over = sd.keys()
+ if len(left_over) > 0:
+ logging.debug("left over keys: {}".format(left_over))
+
+ if output_model:
+ if inital_load_device != torch.device("cpu"):
+ logging.info("loaded diffusion model directly to GPU")
+ model_management.load_models_gpu([model_patcher], force_full_load=True)
+
+ return (model_patcher, clip, vae, clipvision)
+
+
+def load_diffusion_model_state_dict(sd, model_options={}, metadata=None, disable_dynamic=False):
+ """
+ Loads a UNet diffusion model from a state dictionary, supporting both diffusers and regular formats.
+
+ Args:
+ sd (dict): State dictionary containing model weights and configuration
+ model_options (dict, optional): Additional options for model loading. Supports:
+ - dtype: Override model data type
+ - custom_operations: Custom model operations
+ - fp8_optimizations: Enable FP8 optimizations
+
+ Returns:
+ ModelPatcher: A wrapped model instance that handles device management and weight loading.
+ Returns None if the model configuration cannot be detected.
+
+ The function:
+ 1. Detects and handles different model formats (regular, diffusers, mmdit)
+ 2. Configures model dtype based on parameters and device capabilities
+ 3. Handles weight conversion and device placement
+ 4. Manages model optimization settings
+ 5. Loads weights and returns a device-managed model instance
+ """
+ dtype = model_options.get("dtype", None)
+
+ custom_operations = model_options.get("custom_operations", None)
+ if custom_operations is None:
+ sd, metadata = comfy.utils.convert_old_quants(sd, "", metadata=metadata)
+
+ #Allow loading unets from checkpoint files
+ diffusion_model_prefix = model_detection.unet_prefix_from_state_dict(sd)
+ temp_sd = comfy.utils.state_dict_prefix_replace(sd, {diffusion_model_prefix: ""}, filter_keys=True)
+ if len(temp_sd) > 0:
+ sd = temp_sd
+ if custom_operations is None:
+ sd, metadata = comfy.utils.convert_old_quants(sd, "", metadata=metadata)
+
+ parameters = comfy.utils.calculate_parameters(sd)
+ weight_dtype = comfy.utils.weight_dtype(sd)
+
+ load_device = model_options.get("load_device", model_management.get_torch_device())
+ model_config = model_detection.model_config_from_unet(sd, "", metadata=metadata)
+
+ if model_config is not None:
+ new_sd = sd
+ else:
+ new_sd = model_detection.convert_diffusers_mmdit(sd, "")
+ if new_sd is not None: #diffusers mmdit
+ model_config = model_detection.model_config_from_unet(new_sd, "")
+ if model_config is None:
+ return None
+ else: #diffusers unet
+ model_config = model_detection.model_config_from_diffusers_unet(sd)
+ if model_config is None:
+ return None
+
+ diffusers_keys = comfy.utils.unet_to_diffusers(model_config.unet_config)
+
+ new_sd = {}
+ for k in diffusers_keys:
+ if k in sd:
+ new_sd[diffusers_keys[k]] = sd.pop(k)
+ else:
+ logging.warning("{} {}".format(diffusers_keys[k], k))
+
+ offload_device = model_options.get("offload_device", model_management.unet_offload_device())
+ unet_weight_dtype = list(model_config.supported_inference_dtypes)
+ if model_config.quant_config is not None:
+ weight_dtype = None
+
+ if dtype is None:
+ unet_dtype = model_management.unet_dtype(model_params=parameters, supported_dtypes=unet_weight_dtype, weight_dtype=weight_dtype)
+ else:
+ unet_dtype = dtype
+
+ if model_config.quant_config is not None:
+ manual_cast_dtype = model_management.unet_manual_cast(None, load_device, model_config.supported_inference_dtypes)
+ else:
+ manual_cast_dtype = model_management.unet_manual_cast(unet_dtype, load_device, model_config.supported_inference_dtypes)
+ model_config.set_inference_dtype(unet_dtype, manual_cast_dtype, device=load_device)
+
+ if custom_operations is not None:
+ model_config.custom_operations = custom_operations
+
+ if model_options.get("fp8_optimizations", False):
+ model_config.optimizations["fp8"] = True
+
+ model = model_config.get_model(new_sd, "")
+ ModelPatcher = comfy.model_patcher.ModelPatcher if disable_dynamic else comfy.model_patcher.CoreModelPatcher
+ model_patcher = ModelPatcher(model, load_device=load_device, offload_device=offload_device)
+ if not model_management.is_device_cpu(offload_device):
+ model.to(offload_device)
+ model.load_model_weights(new_sd, "", assign=model_patcher.is_dynamic())
+ left_over = sd.keys()
+ if len(left_over) > 0:
+ logging.info("left over keys in diffusion model: {}".format(left_over))
+ return model_patcher
+
+def load_diffusion_model(unet_path, model_options={}, disable_dynamic=False):
+ sd, metadata = comfy.utils.load_torch_file(unet_path, return_metadata=True)
+ model = load_diffusion_model_state_dict(sd, model_options=model_options, metadata=metadata, disable_dynamic=disable_dynamic)
+ if model is None:
+ logging.error("ERROR UNSUPPORTED DIFFUSION MODEL {}".format(unet_path))
+ raise RuntimeError("ERROR: Could not detect model type of: {}\n{}".format(unet_path, model_detection_error_hint(unet_path, sd)))
+ model.cached_patcher_init = (load_diffusion_model, (unet_path, model_options))
+ return model
+
+
+def load_vae_patcher(vae_path, metadata=None, device=None, disable_dynamic=False):
+ """Reload a disk-backed VAE from ``vae_path`` and return its patcher.
+
+ Used as the ``cached_patcher_init`` factory on ``VAE.patcher`` so
+ :meth:`comfy.model_patcher.ModelPatcher.deepclone_multigpu` can produce a
+ fresh, untainted VAE patcher (no inherited per-device load state, no
+ in-place quantization fallout) for multigpu work-units and the
+ SelectVAEDevice node. The optional ``device`` matches the source loader's
+ VAE initialization path; the deepclone's ``load_device`` still controls
+ where the cloned patcher is targeted.
+ """
+ if metadata is None:
+ sd, metadata = comfy.utils.load_torch_file(vae_path, return_metadata=True)
+ else:
+ sd = comfy.utils.load_torch_file(vae_path)
+ vae = VAE(sd=sd, metadata=metadata, device=device)
+ vae.throw_exception_if_invalid()
+ return vae.patcher
+
+def load_unet(unet_path, dtype=None):
+ logging.warning("The load_unet function has been deprecated and will be removed please switch to: load_diffusion_model")
+ return load_diffusion_model(unet_path, model_options={"dtype": dtype})
+
+def load_unet_state_dict(sd, dtype=None):
+ logging.warning("The load_unet_state_dict function has been deprecated and will be removed please switch to: load_diffusion_model_state_dict")
+ return load_diffusion_model_state_dict(sd, model_options={"dtype": dtype})
+
+def save_checkpoint(output_path, model, clip=None, vae=None, clip_vision=None, metadata=None, extra_keys={}):
+ clip_sd = None
+ load_models = [model]
+ if clip is not None:
+ load_models.append(clip.load_model())
+ clip_sd = clip.state_dict_for_saving()
+ vae_sd = None
+ if vae is not None:
+ vae_sd = vae.get_sd()
+
+ if metadata is None:
+ metadata = {}
+
+ model_management.load_models_gpu(load_models)
+ clip_vision_sd = clip_vision.get_sd() if clip_vision is not None else None
+ sd = model.state_dict_for_saving(clip_sd, vae_sd, clip_vision_sd)
+ for k in extra_keys:
+ sd[k] = extra_keys[k]
+
+ for k in sd:
+ t = sd[k]
+ if not t.is_contiguous():
+ sd[k] = t.contiguous()
+
+ comfy.utils.save_torch_file(sd, output_path, metadata=metadata)
diff --git a/ComfyUI/comfy/sd1_clip.py b/ComfyUI/comfy/sd1_clip.py
new file mode 100644
index 0000000000000000000000000000000000000000..f0fdf1aa5bd21ae580621653b8eb2a89bc2aef4f
--- /dev/null
+++ b/ComfyUI/comfy/sd1_clip.py
@@ -0,0 +1,750 @@
+import os
+
+from transformers import CLIPTokenizer
+import comfy.ops
+import torch
+import traceback
+import zipfile
+from . import model_management
+import comfy.clip_model
+import json
+import logging
+import numbers
+import re
+
+def gen_empty_tokens(special_tokens, length):
+ start_token = special_tokens.get("start", None)
+ end_token = special_tokens.get("end", None)
+ pad_token = special_tokens.get("pad")
+ output = []
+ if start_token is not None:
+ output.append(start_token)
+ if end_token is not None:
+ output.append(end_token)
+ output += [pad_token] * (length - len(output))
+ return output
+
+class ClipTokenWeightEncoder:
+ def encode_token_weights(self, token_weight_pairs):
+ to_encode = list()
+ max_token_len = 0
+ has_weights = False
+ for x in token_weight_pairs:
+ tokens = list(map(lambda a: a[0], x))
+ max_token_len = max(len(tokens), max_token_len)
+ has_weights = has_weights or not all(map(lambda a: a[1] == 1.0, x))
+ to_encode.append(tokens)
+
+ sections = len(to_encode)
+ if has_weights or sections == 0:
+ if hasattr(self, "gen_empty_tokens"):
+ to_encode.append(self.gen_empty_tokens(self.special_tokens, max_token_len))
+ else:
+ to_encode.append(gen_empty_tokens(self.special_tokens, max_token_len))
+
+ o = self.encode(to_encode)
+ out, pooled = o[:2]
+
+ if pooled is not None:
+ first_pooled = pooled[0:1].to(device=model_management.intermediate_device())
+ else:
+ first_pooled = pooled
+
+ output = []
+ for k in range(0, sections):
+ z = out[k:k+1]
+ if has_weights:
+ z_empty = out[-1]
+ for i in range(len(z)):
+ for j in range(len(z[i])):
+ weight = token_weight_pairs[k][j][1]
+ if weight != 1.0:
+ z[i][j] = (z[i][j] - z_empty[j]) * weight + z_empty[j]
+ output.append(z)
+
+ if (len(output) == 0):
+ r = (out[-1:].to(device=model_management.intermediate_device()), first_pooled)
+ else:
+ r = (torch.cat(output, dim=-2).to(device=model_management.intermediate_device()), first_pooled)
+
+ if len(o) > 2:
+ extra = {}
+ for k in o[2]:
+ v = o[2][k]
+ if k == "attention_mask":
+ v = v[:sections].flatten().unsqueeze(dim=0).to(device=model_management.intermediate_device())
+ extra[k] = v
+
+ r = r + (extra,)
+ return r
+
+class SDClipModel(torch.nn.Module, ClipTokenWeightEncoder):
+ LAYERS = [
+ "last",
+ "pooled",
+ "hidden",
+ "all"
+ ]
+ def __init__(self, device="cpu", max_length=77,
+ freeze=True, layer="last", layer_idx=None, textmodel_json_config=None, dtype=None, model_class=comfy.clip_model.CLIPTextModel,
+ special_tokens={"start": 49406, "end": 49407, "pad": 49407}, layer_norm_hidden_state=True, enable_attention_masks=False, zero_out_masked=False,
+ return_projected_pooled=True, return_attention_masks=False, model_options={}): # clip-vit-base-patch32
+ super().__init__()
+
+ if textmodel_json_config is None:
+ textmodel_json_config = os.path.join(os.path.dirname(os.path.realpath(__file__)), "sd1_clip_config.json")
+ if "model_name" not in model_options:
+ model_options = {**model_options, "model_name": "clip_l"}
+
+ if isinstance(textmodel_json_config, dict):
+ config = textmodel_json_config
+ else:
+ with open(textmodel_json_config) as f:
+ config = json.load(f)
+
+ te_model_options = model_options.get("{}_model_config".format(model_options.get("model_name", "")), {})
+ for k, v in te_model_options.items():
+ config[k] = v
+
+ operations = model_options.get("custom_operations", None)
+ quant_config = model_options.get("quantization_metadata", None)
+
+ if operations is None:
+ if quant_config is not None:
+ operations = comfy.ops.mixed_precision_ops(quant_config, dtype, full_precision_mm=True)
+ logging.info("Using MixedPrecisionOps for text encoder")
+ else:
+ operations = comfy.ops.manual_cast
+
+ self.operations = operations
+ self.transformer = model_class(config, dtype, device, self.operations)
+
+ self.num_layers = self.transformer.num_layers
+
+ self.max_length = max_length
+ if freeze:
+ self.freeze()
+ self.layer = layer
+ self.layer_idx = None
+ self.special_tokens = special_tokens
+
+ self.logit_scale = torch.nn.Parameter(torch.tensor(4.6055))
+ self.enable_attention_masks = enable_attention_masks
+ self.zero_out_masked = zero_out_masked
+
+ self.layer_norm_hidden_state = layer_norm_hidden_state
+ self.return_projected_pooled = return_projected_pooled
+ self.return_attention_masks = return_attention_masks
+ self.execution_device = None
+
+ if layer == "hidden":
+ assert layer_idx is not None
+ assert abs(layer_idx) < self.num_layers
+ self.set_clip_options({"layer": layer_idx})
+ self.options_default = (self.layer, self.layer_idx, self.return_projected_pooled)
+
+ def freeze(self):
+ self.transformer = self.transformer.eval()
+ #self.train = disabled_train
+ for param in self.parameters():
+ param.requires_grad = False
+
+ def set_clip_options(self, options):
+ layer_idx = options.get("layer", self.layer_idx)
+ self.return_projected_pooled = options.get("projected_pooled", self.return_projected_pooled)
+ self.execution_device = options.get("execution_device", self.execution_device)
+ if isinstance(self.layer, list) or self.layer == "all":
+ pass
+ elif isinstance(layer_idx, list):
+ self.layer = layer_idx
+ elif layer_idx is None or abs(layer_idx) > self.num_layers:
+ self.layer = "last"
+ else:
+ self.layer = "hidden"
+ self.layer_idx = layer_idx
+
+ def reset_clip_options(self):
+ self.layer = self.options_default[0]
+ self.layer_idx = self.options_default[1]
+ self.return_projected_pooled = self.options_default[2]
+ self.execution_device = None
+
+ def process_tokens(self, tokens, device):
+ end_token = self.special_tokens.get("end", None)
+ pad_token = self.special_tokens.get("pad", -1)
+ if end_token is None:
+ cmp_token = pad_token
+ else:
+ cmp_token = end_token
+
+ embeds_out = []
+ attention_masks = []
+ num_tokens = []
+
+ for x in tokens:
+ attention_mask = []
+ tokens_temp = []
+ other_embeds = []
+ eos = False
+ index = 0
+ left_pad = False
+ for y in x:
+ if isinstance(y, numbers.Integral):
+ token = int(y)
+ if index == 0 and token == pad_token:
+ left_pad = True
+
+ if eos or (left_pad and token == pad_token):
+ attention_mask.append(0)
+ else:
+ attention_mask.append(1)
+ left_pad = False
+
+ tokens_temp += [token]
+ if not eos and token == cmp_token and not left_pad:
+ if end_token is None:
+ attention_mask[-1] = 0
+ eos = True
+ else:
+ other_embeds.append((index, y))
+ index += 1
+
+ tokens_embed = torch.tensor([tokens_temp], device=device, dtype=torch.long)
+ tokens_embed = self.transformer.get_input_embeddings()(tokens_embed, out_dtype=torch.float32)
+ index = 0
+ pad_extra = 0
+ embeds_info = []
+ for o in other_embeds:
+ emb = o[1]
+ if torch.is_tensor(emb):
+ emb = {"type": "embedding", "data": emb}
+
+ extra = None
+ emb_type = emb.get("type", None)
+ if emb_type == "embedding":
+ emb = emb.get("data", None)
+ else:
+ if hasattr(self.transformer, "preprocess_embed"):
+ emb, extra = self.transformer.preprocess_embed(emb, device=device)
+ else:
+ emb = None
+
+ if emb is None:
+ index += -1
+ continue
+
+ ind = index + o[0]
+ emb = emb.view(1, -1, emb.shape[-1]).to(device=device, dtype=torch.float32)
+ emb_shape = emb.shape[1]
+ if emb.shape[-1] == tokens_embed.shape[-1]:
+ tokens_embed = torch.cat([tokens_embed[:, :ind], emb, tokens_embed[:, ind:]], dim=1)
+ attention_mask = attention_mask[:ind] + [1] * emb_shape + attention_mask[ind:]
+ index += emb_shape - 1
+ embeds_info.append({"type": emb_type, "index": ind, "size": emb_shape, "extra": extra})
+ else:
+ index += -1
+ pad_extra += emb_shape
+ logging.warning("WARNING: shape mismatch when trying to apply embedding, embedding will be ignored {} != {}".format(emb.shape[-1], tokens_embed.shape[-1]))
+
+ if pad_extra > 0:
+ padd_embed = self.transformer.get_input_embeddings()(torch.tensor([[self.special_tokens["pad"]] * pad_extra], device=device, dtype=torch.long), out_dtype=torch.float32)
+ tokens_embed = torch.cat([tokens_embed, padd_embed], dim=1)
+ attention_mask = attention_mask + [0] * pad_extra
+
+ embeds_out.append(tokens_embed)
+ attention_masks.append(attention_mask)
+ num_tokens.append(sum(attention_mask))
+
+ return torch.cat(embeds_out), torch.tensor(attention_masks, device=device, dtype=torch.long), num_tokens, embeds_info
+
+ def forward(self, tokens):
+ if self.execution_device is None:
+ device = self.transformer.get_input_embeddings().weight.device
+ else:
+ device = self.execution_device
+
+ embeds, attention_mask, num_tokens, embeds_info = self.process_tokens(tokens, device)
+
+ attention_mask_model = None
+ if self.enable_attention_masks:
+ attention_mask_model = attention_mask
+
+ if isinstance(self.layer, list):
+ intermediate_output = self.layer
+ elif self.layer == "all":
+ intermediate_output = "all"
+ else:
+ intermediate_output = self.layer_idx
+
+ outputs = self.transformer(None, attention_mask_model, embeds=embeds, num_tokens=num_tokens, intermediate_output=intermediate_output, final_layer_norm_intermediate=self.layer_norm_hidden_state, dtype=torch.float32, embeds_info=embeds_info)
+
+ if self.layer == "last":
+ z = outputs[0].float()
+ else:
+ z = outputs[1].float()
+
+ if self.zero_out_masked:
+ z *= attention_mask.unsqueeze(-1).float()
+
+ pooled_output = None
+ if len(outputs) >= 3:
+ if not self.return_projected_pooled and len(outputs) >= 4 and outputs[3] is not None:
+ pooled_output = outputs[3].float()
+ elif outputs[2] is not None:
+ pooled_output = outputs[2].float()
+
+ extra = {}
+ if self.return_attention_masks:
+ extra["attention_mask"] = attention_mask
+
+ if len(extra) > 0:
+ return z, pooled_output, extra
+
+ return z, pooled_output
+
+ def encode(self, tokens):
+ return self(tokens)
+
+ def load_sd(self, sd):
+ return self.transformer.load_state_dict(sd, strict=False, assign=getattr(self, "can_assign_sd", False))
+
+ def generate(self, tokens, do_sample, max_length, temperature, top_k, top_p, min_p, repetition_penalty, seed, presence_penalty=0.0):
+ if isinstance(tokens, dict):
+ tokens_only = next(iter(tokens.values())) # todo: get this better?
+ else:
+ tokens_only = tokens
+ tokens_only = [[t[0] for t in b] for b in tokens_only]
+ embeds = self.process_tokens(tokens_only, device=self.execution_device)[0]
+ return self.transformer.generate(embeds, do_sample, max_length, temperature, top_k, top_p, min_p, repetition_penalty, seed, presence_penalty=presence_penalty)
+
+def parse_parentheses(string):
+ result = []
+ current_item = ""
+ nesting_level = 0
+ for char in string:
+ if char == "(":
+ if nesting_level == 0:
+ if current_item:
+ result.append(current_item)
+ current_item = "("
+ else:
+ current_item = "("
+ else:
+ current_item += char
+ nesting_level += 1
+ elif char == ")":
+ nesting_level -= 1
+ if nesting_level == 0:
+ result.append(current_item + ")")
+ current_item = ""
+ else:
+ current_item += char
+ else:
+ current_item += char
+ if current_item:
+ result.append(current_item)
+ return result
+
+def token_weights(string, current_weight):
+ a = parse_parentheses(string)
+ out = []
+ for x in a:
+ weight = current_weight
+ if len(x) >= 2 and x[-1] == ')' and x[0] == '(':
+ x = x[1:-1]
+ xx = x.rfind(":")
+ weight *= 1.1
+ if xx > 0:
+ try:
+ weight = float(x[xx+1:])
+ x = x[:xx]
+ except:
+ pass
+ out += token_weights(x, weight)
+ else:
+ out += [(x, current_weight)]
+ return out
+
+def escape_important(text):
+ text = text.replace("\\)", "\0\1")
+ text = text.replace("\\(", "\0\2")
+ return text
+
+def unescape_important(text):
+ text = text.replace("\0\1", ")")
+ text = text.replace("\0\2", "(")
+ return text
+
+def safe_load_embed_zip(embed_path):
+ with zipfile.ZipFile(embed_path) as myzip:
+ names = list(filter(lambda a: "data/" in a, myzip.namelist()))
+ names.reverse()
+ for n in names:
+ with myzip.open(n) as myfile:
+ data = myfile.read()
+ number = len(data) // 4
+ length_embed = 1024 #sd2.x
+ if number < 768:
+ continue
+ if number % 768 == 0:
+ length_embed = 768 #sd1.x
+ num_embeds = number // length_embed
+ embed = torch.frombuffer(data, dtype=torch.float)
+ out = embed.reshape((num_embeds, length_embed)).clone()
+ del embed
+ return out
+
+def expand_directory_list(directories):
+ dirs = set()
+ for x in directories:
+ dirs.add(x)
+ for root, subdir, file in os.walk(x, followlinks=True):
+ dirs.add(root)
+ return list(dirs)
+
+def bundled_embed(embed, prefix, suffix): #bundled embedding in lora format
+ out_list = []
+ for k in embed:
+ if k.startswith(prefix) and k.endswith(suffix):
+ out_list.append(embed[k])
+ if len(out_list) == 0:
+ return None
+
+ return torch.cat(out_list, dim=0)
+
+def load_embed(embedding_name, embedding_directory, embedding_size, embed_key=None):
+ if isinstance(embedding_directory, str):
+ embedding_directory = [embedding_directory]
+
+ embedding_directory = expand_directory_list(embedding_directory)
+
+ valid_file = None
+ for embed_dir in embedding_directory:
+ embed_path = os.path.abspath(os.path.join(embed_dir, embedding_name))
+ embed_dir = os.path.abspath(embed_dir)
+ try:
+ if os.path.commonpath((embed_dir, embed_path)) != embed_dir:
+ continue
+ except:
+ continue
+ if not os.path.isfile(embed_path):
+ extensions = ['.safetensors', '.pt', '.bin']
+ for x in extensions:
+ t = embed_path + x
+ if os.path.isfile(t):
+ valid_file = t
+ break
+ else:
+ valid_file = embed_path
+ if valid_file is not None:
+ break
+
+ if valid_file is None:
+ return None
+
+ embed_path = valid_file
+
+ embed_out = None
+
+ try:
+ if embed_path.lower().endswith(".safetensors"):
+ import safetensors.torch
+ embed = safetensors.torch.load_file(embed_path, device="cpu")
+ else:
+ try:
+ embed = torch.load(embed_path, weights_only=True, map_location="cpu")
+ except:
+ embed_out = safe_load_embed_zip(embed_path)
+ except Exception:
+ logging.warning("{}\n\nerror loading embedding, skipping loading: {}".format(traceback.format_exc(), embedding_name))
+ return None
+
+ if embed_out is None:
+ if 'string_to_param' in embed:
+ values = embed['string_to_param'].values()
+ embed_out = next(iter(values))
+ elif isinstance(embed, list):
+ out_list = []
+ for x in range(len(embed)):
+ for k in embed[x]:
+ t = embed[x][k]
+ if t.shape[-1] != embedding_size:
+ continue
+ out_list.append(t.reshape(-1, t.shape[-1]))
+ embed_out = torch.cat(out_list, dim=0)
+ elif embed_key is not None and embed_key in embed:
+ embed_out = embed[embed_key]
+ else:
+ embed_out = bundled_embed(embed, 'bundle_emb.', '.string_to_param.*')
+ if embed_out is None:
+ embed_out = bundled_embed(embed, 'bundle_emb.', '.{}'.format(embed_key))
+ if embed_out is None:
+ values = embed.values()
+ embed_out = next(iter(values))
+ return embed_out
+
+class SDTokenizer:
+ def __init__(self, tokenizer_path=None, max_length=77, pad_with_end=True, embedding_directory=None, embedding_size=768, embedding_key='clip_l', tokenizer_class=CLIPTokenizer, has_start_token=True, has_end_token=True, pad_to_max_length=True, min_length=None, pad_token=None, end_token=None, start_token=None, min_padding=None, pad_left=False, disable_weights=False, tokenizer_data={}, tokenizer_args={}):
+ if tokenizer_path is None:
+ tokenizer_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "sd1_tokenizer")
+ self.tokenizer = tokenizer_class.from_pretrained(tokenizer_path, **tokenizer_args)
+ self.max_length = tokenizer_data.get("{}_max_length".format(embedding_key), max_length)
+ self.min_length = tokenizer_data.get("{}_min_length".format(embedding_key), min_length)
+ self.end_token = None
+ self.min_padding = min_padding
+ self.pad_left = pad_left
+
+ empty = self.tokenizer('')["input_ids"]
+ self.tokenizer_adds_end_token = has_end_token
+ if has_start_token:
+ if len(empty) > 0:
+ self.tokens_start = 1
+ self.start_token = empty[0]
+ else:
+ self.tokens_start = 0
+ self.start_token = start_token
+ if start_token is None:
+ logging.warning("WARNING: There's something wrong with your tokenizers.'")
+
+ if end_token is not None:
+ self.end_token = end_token
+ else:
+ if has_end_token:
+ self.end_token = empty[1]
+ else:
+ self.tokens_start = 0
+ self.start_token = start_token
+ if end_token is not None:
+ self.end_token = end_token
+ else:
+ if has_end_token:
+ self.end_token = empty[0]
+
+ if pad_token is not None:
+ self.pad_token = pad_token
+ elif pad_with_end:
+ self.pad_token = self.end_token
+ else:
+ self.pad_token = 0
+
+ self.pad_with_end = pad_with_end
+ self.pad_to_max_length = pad_to_max_length
+
+ vocab = self.tokenizer.get_vocab()
+ self.inv_vocab = {v: k for k, v in vocab.items()}
+ self.embedding_directory = embedding_directory
+ self.max_word_length = 8
+ self.embedding_identifier = "embedding:"
+ self.embedding_size = embedding_size
+ self.embedding_key = embedding_key
+
+ self.disable_weights = disable_weights
+
+ def _try_get_embedding(self, embedding_name:str):
+ '''
+ Takes a potential embedding name and tries to retrieve it.
+ Returns a Tuple consisting of the embedding, the cleaned embedding name, and any leftover string, embedding can be None.
+ '''
+ split_embed = embedding_name.split()
+ embedding_name = split_embed[0]
+ leftover = ' '.join(split_embed[1:])
+
+ match = re.search(r'[<\[]', embedding_name)
+ if match is not None:
+ leftover = embedding_name[match.start():] + (" " + leftover if leftover else "")
+ embedding_name = embedding_name[:match.start()]
+
+ embed = load_embed(embedding_name, self.embedding_directory, self.embedding_size, self.embedding_key)
+ if embed is None:
+ stripped = embedding_name.strip(',')
+ if len(stripped) < len(embedding_name):
+ embed = load_embed(stripped, self.embedding_directory, self.embedding_size, self.embedding_key)
+ return (embed, embedding_name, "{} {}".format(embedding_name[len(stripped):], leftover))
+ return (embed, embedding_name, leftover)
+
+ def pad_tokens(self, tokens, amount):
+ if self.pad_left:
+ for i in range(amount):
+ tokens.insert(0, (self.pad_token, 1.0, 0))
+ else:
+ tokens.extend([(self.pad_token, 1.0, 0)] * amount)
+
+ def tokenize_with_weights(self, text:str, return_word_ids=False, tokenizer_options={}, **kwargs):
+ '''
+ Takes a prompt and converts it to a list of (token, weight, word id) elements.
+ Tokens can both be integer tokens and pre computed CLIP tensors.
+ Word id values are unique per word and embedding, where the id 0 is reserved for non word tokens.
+ Returned list has the dimensions NxM where M is the input size of CLIP
+ '''
+ min_length = tokenizer_options.get("{}_min_length".format(self.embedding_key), self.min_length)
+ min_padding = tokenizer_options.get("{}_min_padding".format(self.embedding_key), self.min_padding)
+
+ min_length = kwargs.get("min_length", min_length)
+
+ text = escape_important(text)
+ if kwargs.get("disable_weights", self.disable_weights):
+ parsed_weights = [(text, 1.0)]
+ else:
+ parsed_weights = token_weights(text, 1.0)
+
+ # tokenize words
+ tokens = []
+ for weighted_segment, weight in parsed_weights:
+ to_tokenize = unescape_important(weighted_segment)
+ split = re.split(r'(?<=\s){}'.format(re.escape(self.embedding_identifier)), to_tokenize)
+ to_tokenize = [split[0]]
+ for i in range(1, len(split)):
+ to_tokenize.append("{}{}".format(self.embedding_identifier, split[i]))
+
+ to_tokenize = [x for x in to_tokenize if x != ""]
+ for word in to_tokenize:
+ # if we find an embedding, deal with the embedding
+ if word.startswith(self.embedding_identifier) and self.embedding_directory is not None:
+ embedding_name = word[len(self.embedding_identifier):].strip('\n')
+ embed, embedding_name, leftover = self._try_get_embedding(embedding_name)
+ if embed is None:
+ logging.warning(f"warning, embedding:{embedding_name} does not exist, ignoring")
+ else:
+ if len(embed.shape) == 1:
+ tokens.append([(embed, weight)])
+ else:
+ tokens.append([(embed[x], weight) for x in range(embed.shape[0])])
+ #if we accidentally have leftover text, continue parsing using leftover, else move on to next word
+ if leftover != "":
+ word = leftover
+ else:
+ continue
+ end = 999999999999
+ if self.tokenizer_adds_end_token:
+ end = -1
+ #parse word
+ tokens.append([(t, weight) for t in self.tokenizer(word)["input_ids"][self.tokens_start:end]])
+
+ #reshape token array to CLIP input size
+ batched_tokens = []
+ batch = []
+ if self.start_token is not None:
+ batch.append((self.start_token, 1.0, 0))
+ batched_tokens.append(batch)
+ for i, t_group in enumerate(tokens):
+ #determine if we're going to try and keep the tokens in a single batch
+ is_large = len(t_group) >= self.max_word_length
+ if self.end_token is not None:
+ has_end_token = 1
+ else:
+ has_end_token = 0
+
+ while len(t_group) > 0:
+ if len(t_group) + len(batch) > self.max_length - has_end_token:
+ remaining_length = self.max_length - len(batch) - has_end_token
+ #break word in two and add end token
+ if is_large:
+ batch.extend([(t,w,i+1) for t,w in t_group[:remaining_length]])
+ if self.end_token is not None:
+ batch.append((self.end_token, 1.0, 0))
+ t_group = t_group[remaining_length:]
+ #add end token and pad
+ else:
+ if self.end_token is not None:
+ batch.append((self.end_token, 1.0, 0))
+ if self.pad_to_max_length:
+ self.pad_tokens(batch, remaining_length)
+ #start new batch
+ batch = []
+ if self.start_token is not None:
+ batch.append((self.start_token, 1.0, 0))
+ batched_tokens.append(batch)
+ else:
+ batch.extend([(t,w,i+1) for t,w in t_group])
+ t_group = []
+
+ #fill last batch
+ if self.end_token is not None:
+ batch.append((self.end_token, 1.0, 0))
+ if min_padding is not None:
+ self.pad_tokens(batch, min_padding)
+ if self.pad_to_max_length and len(batch) < self.max_length:
+ self.pad_tokens(batch, self.max_length - len(batch))
+ if min_length is not None and len(batch) < min_length:
+ self.pad_tokens(batch, min_length - len(batch))
+
+ if not return_word_ids:
+ batched_tokens = [[(t, w) for t, w,_ in x] for x in batched_tokens]
+
+ return batched_tokens
+
+
+ def untokenize(self, token_weight_pair):
+ return list(map(lambda a: (a, self.inv_vocab[a[0]]), token_weight_pair))
+
+ def state_dict(self):
+ return {}
+
+ def decode(self, token_ids, skip_special_tokens=True):
+ return self.tokenizer.decode(token_ids, skip_special_tokens=skip_special_tokens)
+
+class SD1Tokenizer:
+ def __init__(self, embedding_directory=None, tokenizer_data={}, clip_name="l", tokenizer=SDTokenizer, name=None):
+ if name is not None:
+ self.clip_name = name
+ self.clip = "{}".format(self.clip_name)
+ else:
+ self.clip_name = clip_name
+ self.clip = "clip_{}".format(self.clip_name)
+
+ tokenizer = tokenizer_data.get("{}_tokenizer_class".format(self.clip), tokenizer)
+ setattr(self, self.clip, tokenizer(embedding_directory=embedding_directory, tokenizer_data=tokenizer_data))
+
+ def tokenize_with_weights(self, text:str, return_word_ids=False, **kwargs):
+ out = {}
+ out[self.clip_name] = getattr(self, self.clip).tokenize_with_weights(text, return_word_ids, **kwargs)
+ return out
+
+ def untokenize(self, token_weight_pair):
+ return getattr(self, self.clip).untokenize(token_weight_pair)
+
+ def state_dict(self):
+ return getattr(self, self.clip).state_dict()
+
+ def decode(self, token_ids, skip_special_tokens=True):
+ return getattr(self, self.clip).decode(token_ids, skip_special_tokens=skip_special_tokens)
+
+class SD1CheckpointClipModel(SDClipModel):
+ def __init__(self, device="cpu", dtype=None, model_options={}):
+ super().__init__(device=device, return_projected_pooled=False, dtype=dtype, model_options=model_options)
+
+class SD1ClipModel(torch.nn.Module):
+ def __init__(self, device="cpu", dtype=None, model_options={}, clip_name="l", clip_model=SD1CheckpointClipModel, name=None, **kwargs):
+ super().__init__()
+
+ if name is not None:
+ self.clip_name = name
+ self.clip = "{}".format(self.clip_name)
+ else:
+ self.clip_name = clip_name
+ self.clip = "clip_{}".format(self.clip_name)
+
+ clip_model = model_options.get("{}_class".format(self.clip), clip_model)
+ model_options = {**model_options, "model_name": self.clip}
+ setattr(self, self.clip, clip_model(device=device, dtype=dtype, model_options=model_options, **kwargs))
+
+ self.dtypes = set()
+ if dtype is not None:
+ self.dtypes.add(dtype)
+
+ def set_clip_options(self, options):
+ getattr(self, self.clip).set_clip_options(options)
+
+ def reset_clip_options(self):
+ getattr(self, self.clip).reset_clip_options()
+
+ def encode_token_weights(self, token_weight_pairs):
+ token_weight_pairs = token_weight_pairs[self.clip_name]
+ out = getattr(self, self.clip).encode_token_weights(token_weight_pairs)
+ return out
+
+ def load_sd(self, sd):
+ return getattr(self, self.clip).load_sd(sd)
+
+ def generate(self, tokens, do_sample=True, max_length=256, temperature=1.0, top_k=50, top_p=0.95, min_p=0.0, repetition_penalty=1.0, seed=None, presence_penalty=0.0):
+ return getattr(self, self.clip).generate(tokens, do_sample=do_sample, max_length=max_length, temperature=temperature, top_k=top_k, top_p=top_p, min_p=min_p, repetition_penalty=repetition_penalty, seed=seed, presence_penalty=presence_penalty)
diff --git a/ComfyUI/comfy/sd1_clip_config.json b/ComfyUI/comfy/sd1_clip_config.json
new file mode 100644
index 0000000000000000000000000000000000000000..3ba8c6b5bc3d6389fb6c9e2c8231729ad9d663a4
--- /dev/null
+++ b/ComfyUI/comfy/sd1_clip_config.json
@@ -0,0 +1,25 @@
+{
+ "_name_or_path": "openai/clip-vit-large-patch14",
+ "architectures": [
+ "CLIPTextModel"
+ ],
+ "attention_dropout": 0.0,
+ "bos_token_id": 0,
+ "dropout": 0.0,
+ "eos_token_id": 49407,
+ "hidden_act": "quick_gelu",
+ "hidden_size": 768,
+ "initializer_factor": 1.0,
+ "initializer_range": 0.02,
+ "intermediate_size": 3072,
+ "layer_norm_eps": 1e-05,
+ "max_position_embeddings": 77,
+ "model_type": "clip_text_model",
+ "num_attention_heads": 12,
+ "num_hidden_layers": 12,
+ "pad_token_id": 1,
+ "projection_dim": 768,
+ "torch_dtype": "float32",
+ "transformers_version": "4.24.0",
+ "vocab_size": 49408
+}
diff --git a/ComfyUI/comfy/sd1_tokenizer/merges.txt b/ComfyUI/comfy/sd1_tokenizer/merges.txt
new file mode 100644
index 0000000000000000000000000000000000000000..76e821f1b6f0a9709293c3b6b51ed90980b3166b
--- /dev/null
+++ b/ComfyUI/comfy/sd1_tokenizer/merges.txt
@@ -0,0 +1,48895 @@
+#version: 0.2
+i n
+t h
+a n
+r e
+a r
+e r
+th e
+in g
+o u
+o n
+s t
+o r
+e n
+o n
+a l
+a t
+e r
+i t
+i n
+t o
+r o
+i s
+l e
+i c
+a t
+an d
+e d
+o f
+c h
+o r
+e s
+i l
+e l
+s t
+a c
+o m
+a m
+l o
+a n
+a y
+s h
+r i
+l i
+t i
+f or
+n e
+ð Ł
+r a
+h a
+d e
+o l
+v e
+s i
+u r
+a l
+s e
+' s
+u n
+d i
+b e
+l a
+w h
+o o
+d ay
+e n
+m a
+n o
+l e
+t o
+ou r
+i r
+g h
+w it
+i t
+y o
+a s
+s p
+th is
+t s
+at i
+yo u
+wit h
+a d
+i s
+a b
+l y
+w e
+th e
+t e
+a s
+a g
+v i
+p p
+s u
+h o
+m y
+. .
+b u
+c om
+s e
+er s
+m e
+m e
+al l
+c on
+m o
+k e
+g e
+ou t
+en t
+c o
+f e
+v er
+a r
+f ro
+a u
+p o
+c e
+gh t
+ar e
+s s
+fro m
+c h
+t r
+ou n
+on e
+b y
+d o
+t h
+w or
+er e
+k e
+p ro
+f or
+d s
+b o
+t a
+w e
+g o
+h e
+t er
+in g
+d e
+b e
+ati on
+m or
+a y
+e x
+il l
+p e
+k s
+s c
+l u
+f u
+q u
+v er
+ðŁ ĺ
+j u
+m u
+at e
+an d
+v e
+k ing
+m ar
+o p
+h i
+.. .
+p re
+a d
+r u
+th at
+j o
+o f
+c e
+ne w
+a m
+a p
+g re
+s s
+d u
+no w
+y e
+t ing
+y our
+it y
+n i
+c i
+p ar
+g u
+f i
+a f
+p er
+t er
+u p
+s o
+g i
+on s
+g r
+g e
+b r
+p l
+' t
+m i
+in e
+we e
+b i
+u s
+sh o
+ha ve
+to day
+a v
+m an
+en t
+ac k
+ur e
+ou r
+â Ģ
+c u
+l d
+lo o
+i m
+ic e
+s om
+f in
+re d
+re n
+oo d
+w as
+ti on
+p i
+i r
+th er
+t y
+p h
+ar d
+e c
+! !
+m on
+mor e
+w ill
+t ra
+c an
+c ol
+p u
+t e
+w n
+m b
+s o
+it i
+ju st
+n ing
+h ere
+t u
+p a
+p r
+bu t
+wh at
+al ly
+f ir
+m in
+c a
+an t
+s a
+t ed
+e v
+m ent
+f a
+ge t
+am e
+ab out
+g ra
+no t
+ha pp
+ay s
+m an
+h is
+ti me
+li ke
+g h
+ha s
+th an
+lo ve
+ar t
+st e
+d ing
+h e
+c re
+w s
+w at
+d er
+it e
+s er
+ac e
+ag e
+en d
+st r
+a w
+st or
+r e
+c ar
+el l
+al l
+p s
+f ri
+p ho
+p or
+d o
+a k
+w i
+f re
+wh o
+sh i
+b oo
+s on
+el l
+wh en
+il l
+ho w
+gre at
+w in
+e l
+b l
+s si
+al i
+som e
+ðŁ Ĵ
+t on
+d er
+le s
+p la
+ï ¸
+e d
+s ch
+h u
+on g
+d on
+k i
+s h
+an n
+c or
+. .
+oun d
+a z
+in e
+ar y
+fu l
+st u
+ou ld
+st i
+g o
+se e
+ab le
+ar s
+l l
+m is
+b er
+c k
+w a
+en ts
+n o
+si g
+f e
+fir st
+e t
+sp e
+ac k
+i f
+ou s
+' m
+st er
+a pp
+an g
+an ce
+an s
+g ood
+b re
+e ver
+the y
+t ic
+com e
+of f
+b ack
+as e
+ing s
+ol d
+i ght
+f o
+h er
+happ y
+p ic
+it s
+v ing
+u s
+m at
+h om
+d y
+e m
+s k
+y ing
+the ir
+le d
+r y
+u l
+h ar
+c k
+t on
+on al
+h el
+r ic
+b ir
+vi e
+w ay
+t ri
+d a
+p le
+b ro
+st o
+oo l
+ni ght
+tr u
+b a
+re ad
+re s
+ye ar
+f r
+t or
+al s
+c oun
+c la
+t ure
+v el
+at ed
+le c
+en d
+th ing
+v o
+ic i
+be st
+c an
+wor k
+la st
+af ter
+en ce
+p ri
+p e
+e s
+i l
+âĢ ¦
+d re
+y s
+o ver
+i es
+ðŁ ij
+com m
+t w
+in k
+s un
+c l
+li fe
+t t
+a ch
+l and
+s y
+t re
+t al
+p ol
+s m
+du c
+s al
+f t
+' re
+ch e
+w ar
+t ur
+ati ons
+ac h
+m s
+il e
+p m
+ou gh
+at e
+st ar
+wee k
+! !!
+c lu
+th ere
+n er
+t om
+s el
+ï¸ ı
+wor ld
+v es
+c am
+go t
+in ter
+of f
+u m
+ton ight
+o ther
+h ou
+loo k
+j e
+i d
+si on
+be au
+at t
+el i
+or t
+re c
+f f
+st er
+su pp
+g en
+be en
+il y
+te am
+m m
+i c
+pe op
+it t
+at s
+on ly
+mb er
+en g
+b ri
+m p
+k now
+b ur
+b ar
+in s
+lo w
+sh e
+ro w
+â Ŀ
+t ro
+peop le
+vi a
+lo w
+ag a
+be t
+x t
+f ac
+ch ar
+e ar
+w al
+s en
+f am
+b le
+n ati
+is h
+n or
+g ame
+li ve
+s co
+le y
+d on
+ic k
+b all
+ver y
+the se
+p an
+i a
+at ing
+c r
+a re
+g ir
+ma ke
+st re
+sho w
+. "
+f l
+u p
+d r
+than ks
+il li
+w om
+st s
+i g
+s ur
+ever y
+c ur
+vie w
+le t
+in to
+mo st
+n a
+in di
+g ar
+ha d
+s ou
+v ed
+an t
+iti on
+ma de
+f ol
+un i
+it ed
+ðŁ ı
+ic al
+th r
+read y
+ch ec
+d ra
+k es
+boo k
+e p
+si c
+mor ning
+ne ws
+c au
+c t
+w ell
+an c
+pho to
+th an
+or s
+bir th
+g g
+ou t
+ne xt
+som e
+en ing
+stor y
+ch ri
+do wn
+hom e
+f fe
+fre e
+d a
+b or
+f il
+ci al
+than k
+si de
+le ar
+qu e
+l ine
+t en
+at es
+ye ars
+m y
+pho to
+beau ti
+ri ght
+n u
+for m
+shi p
+b an
+th er
+d ays
+g am
+as on
+g y
+ðŁ İ
+birth day
+se t
+ic k
+e t
+st ill
+com ing
+ta ke
+ðŁ ĩ
+b b
+s ol
+s on
+d en
+e p
+mu sic
+the m
+de n
+wh y
+f oo
+c ra
+am az
+w n
+h ol
+t ting
+w r
+u e
+ma g
+c ro
+l an
+c lo
+b ra
+a k
+s ing
+c al
+re ad
+' ve
+jo h
+b ab
+d ri
+b lo
+bi g
+er ic
+in t
+t or
+tr y
+l a
+le g
+hou se
+m ic
+v al
+beauti ful
+l itt
+chec k
+ne w
+ver s
+s w
+ar i
+pla y
+h er
+âĢ ĵ
+w in
+m a
+con gr
+sch ool
+f un
+. @
+he al
+ic h
+d el
+wh ere
+l on
+ke t
+tw o
+mu ch
+wat ch
+v en
+d ed
+a st
+k ed
+b as
+go ing
+m p
+e ver
+w ays
+ro o
+de sig
+l y
+s ed
+to p
+l in
+ch an
+to o
+it ing
+d ent
+gh ts
+t y
+sp o
+ne ed
+b lu
+in st
+be ing
+âĿ ¤
+w el
+l s
+hi m
+m ay
+st ing
+n a
+el y
+litt le
+g a
+n at
+tom or
+m c
+h on
+w ant
+a ir
+pi c
+am eric
+p er
+le ss
+wee k
+ve l
+a h
+c ap
+ch am
+g er
+ti m
+tomor row
+ne ss
+st ate
+h al
+ser v
+z e
+o s
+p at
+v is
+ex c
+s in
+f f
+c ity
+c en
+an y
+b el
+su mm
+t in
+w ould
+loo king
+k o
+ce le
+fam ily
+m er
+po w
+hel p
+bu s
+c o
+c le
+sel f
+en s
+ic s
+th o
+an i
+ch o
+le ad
+b s
+t wee
+th ink
+for e
+ch il
+vi de
+di d
+al e
+ch i
+v il
+en ds
+w ing
+p as
+' ll
+v ol
+s a
+g s
+man y
+j ec
+be fore
+gra ph
+n y
+ur ing
+w il
+d d
+bu il
+f av
+st ed
+tr an
+l ing
+ou d
+d ge
+fi el
+nati onal
+st a
+c er
+w ere
+in a
+se ason
+c ou
+n ed
+amaz ing
+ti ons
+cele br
+n s
+a th
+he ad
+s day
+d ar
+lo c
+v in
+an other
+g oo
+s at
+n y
+jo in
+pre s
+s es
+s ing
+an a
+in ing
+.. ..
+c our
+ï¸ ı
+ac t
+cau se
+li ght
+am s
+t a
+b al
+f c
+hi gh
+off ici
+t t
+chri st
+d ic
+d ay
+ra l
+h or
+: )
+vi si
+n am
+o b
+ma s
+gh t
+re ally
+t un
+fin d
+thr ough
+por t
+u t
+ti ve
+st y
+n e
+or e
+ðŁĺ Ĥ
+supp ort
+ne ver
+ev en
+ðŁ Ķ
+h a
+y a
+l d
+u k
+r an
+j am
+wi th
+me di
+d es
+ne y
+ch ing
+al e
+h y
+k in
+! !
+d y
+pl ace
+al so
+b le
+wh ich
+bl ack
+b li
+s ay
+par k
+pl ay
+ir e
+vide o
+week end
+a il
+ke y
+p t
+w ard
+fri day
+d in
+ine ss
+g ro
+b en
+al ways
+t ball
+ag o
+m il
+c y
+pro duc
+di sc
+un der
+ple ase
+sp or
+fu ll
+e y
+ðŁ Ļ
+is e
+iti es
+c at
+k no
+u se
+fo re
+k er
+ar t
+hi gh
+op en
+s an
+e f
+our s
+sh ed
+st ri
+d ro
+aga in
+i m
+ðŁ ĵ
+en jo
+fu n
+ge tting
+p en
+g er
+c li
+an y
+ever y
+e u
+wom en
+â ľ
+e st
+c ould
+r y
+" @
+th ou
+sh a
+comm un
+b er
+d ents
+di s
+wh ile
+aw ay
+di o
+h am
+g la
+d ate
+k a
+mis s
+un ch
+w on
+in f
+roo m
+g a
+re al
+ex per
+di rec
+sh ould
+sp r
+g ol
+l ong
+bet ter
+or i
+e y
+i ence
+il s
+z z
+h an
+f ound
+v s
+â Ļ
+po st
+ti c
+par t
+m en
+ren ce
+ce ss
+v ic
+s il
+sho p
+ðŁĺ Ĥ
+f ood
+v al
+sti c
+y ou
+s ays
+e lec
+st ar
+o c
+l and
+i d
+c tion
+fiel d
+s of
+st art
+wat er
+fri ends
+on es
+ðŁ Į
+f la
+f ar
+wh ite
+par ty
+in st
+gr ou
+t v
+every one
+m ent
+j a
+ch a
+pr in
+an ts
+d uring
+l at
+l ar
+we st
+th en
+k a
+y oun
+in sp
+in te
+we en
+visi t
+aga inst
+re le
+he ad
+c es
+to wn
+loo ks
+th re
+re gi
+ren t
+pro jec
+gir l
+se ar
+w o
+m om
+c ar
+h un
+pu bli
+d i
+p le
+c all
+c ri
+u m
+for d
+per fe
+fri end
+h ard
+ssi on
+te st
+pla ying
+ar ound
+be cause
+ke ts
+me et
+sat ur
+ar ti
+wor k
+j un
+v en
+r un
+me mber
+por t
+su per
+t wit
+s am
+el s
+t ly
+ad v
+ati ve
+at h
+s ure
+av ail
+la r
+s qu
+ar ds
+ev ent
+m en
+l l
+o ver
+lo gy
+it al
+tim es
+m al
+b ack
+c oo
+ma king
+st ru
+â ģ
+it u
+sh ar
+g an
+c as
+s n
+summ er
+pic ture
+f an
+h in
+christ mas
+c y
+pr oud
+cham pi
+desig n
+pp ing
+ho pe
+c a
+avail able
+ma y
+we d
+photo graph
+spe cial
+sal e
+sto p
+er y
+a we
+al ity
+hi story
+am a
+pre si
+b ru
+wor king
+d one
+d r
+k en
+fe at
+w ood
+ate st
+sun day
+mo vi
+vel y
+s le
+f ace
+sp ec
+stu dents
+b y
+ha m
+sp on
+bus iness
+d at
+i e
+i p
+so ci
+g lo
+h and
+re cor
+r s
+me e
+ke ep
+p ur
+heal th
+sh e
+com ple
+go d
+da vi
+col lec
+li st
+r a
+clu b
+t ers
+in clu
+th ings
+pl an
+â ĺ
+joh n
+sh ing
+at ul
+so on
+blu e
+g or
+satur day
+w on
+congr atul
+se e
+âĿ¤ ï¸ı
+tho se
+ðŁĺ į
+fin al
+d ou
+it h
+o wn
+ro ad
+t our
+a st
+indi a
+ti l
+n d
+f er
+fav or
+su l
+lear n
+fir e
+ju st
+grou p
+a h
+r ac
+bo dy
+u r
+c are
+à ¸
+p lo
+o h
+po s
+gi ve
+te ch
+su b
+c ent
+er ing
+y m
+il ity
+f ic
+lon don
+v ir
+gu ys
+b a
+ðŁ ¤
+bab y
+sc re
+ðŁĺ į
+tru mp
+un der
+chan ge
+i an
+col le
+ss es
+l er
+ss ed
+n ice
+ann oun
+pow er
+s ar
+a king
+min i
+s li
+s wee
+k ar
+fu l
+c ru
+ac tion
+a ther
+) .
+st and
+de vel
+a a
+g an
+le ft
+lo l
+re l
+tran s
+m ents
+in t
+e f
+man ag
+di g
+gen er
+do wn
+p au
+ti v
+k u
+th ur
+k en
+st on
+f ans
+tal k
+twee t
+t oo
+sty le
+pro te
+se con
+fr on
+awe some
+g l
+p al
+ne t
+s or
+la u
+g on
+sin ce
+t ty
+ser ies
+me mor
+b eli
+fil m
+di d
+di es
+o t
+congratul ations
+p ra
+e ve
+w oo
+offici al
+su c
+in cre
+b on
+par t
+pp ed
+cla ss
+si ve
+bo y
+cu l
+perfe ct
+t ou
+d am
+wel come
+foo tball
+h i
+p ap
+wa it
+ad a
+congr ats
+youn g
+exc ited
+re ce
+j an
+v a
+re d
+st ra
+medi a
+' d
+do es
+le t
+mu l
+ill s
+gre en
+m el
+to ge
+fu ture
+ye ster
+vers ity
+for m
+ta in
+i de
+ch es
+ki ds
+qu i
+ha ha
+de ta
+bi g
+favor ite
+gir ls
+con tin
+do m
+sear ch
+u al
+a ir
+d ers
+mon th
+c er
+yester day
+commun ity
+ad e
+do g
+vil le
+ic es
+d eli
+sy ste
+ru n
+is m
+he art
+c up
+en ti
+fe w
+presi dent
+e ds
+un til
+fe sti
+o k
+f lo
+sa id
+ol e
+me d
+tra vel
+Â £
+ph one
+toge ther
+fa st
+lo t
+gam es
+sh ir
+bet ween
+y es
+th ers
+do ing
+m ac
+at or
+b and
+fol low
+projec t
+devel op
+di ffe
+con fe
+spe ci
+ca st
+y s
+bo ard
+r d
+i al
+sh oo
+r am
+ha ving
+sh are
+fol low
+on e
+n ame
+m r
+pu t
+disc u
+or y
+c ame
+ou s
+s ite
+twit ter
+t b
+t it
+fin ally
+z ed
+su per
+com pan
+us ing
+all s
+li st
+r is
+sho t
+g al
+t ar
+de l
+joh n
+âĢ Ķ
+some thing
+ra m
+inte re
+wh e
+b it
+ðŁ į
+stre et
+oun d
+a i
+tic kets
+movi e
+re al
+k y
+ta king
+o pp
+c c
+l am
+m oun
+in ve
+bl ack
+us ed
+on line
+y or
+loc al
+gu e
+c ks
+o w
+ge st
+bo ys
+illi on
+con t
+re ci
+in ed
+eu ro
+no w
+se en
+p h
+te ach
+de f
+sou th
+su ch
+aw ard
+mu st
+is su
+ca re
+fe el
+p lu
+l atest
+spor ts
+we b
+te x
+e ment
+s k
+fi c
+w an
+te ch
+o t
+bo x
+n er
+fre e
+t al
+a sh
+c ase
+ho t
+won der
+mee ting
+er a
+ch all
+ðŁ IJ
+jo b
+il i
+c ool
+j our
+th s
+m o
+f el
+di e
+mic ha
+e le
+te am
+serv ice
+st and
+ma kes
+p ing
+ear ly
+com es
+e k
+ho li
+v ers
+ag ue
+s au
+thre e
+mon day
+fa shi
+some one
+th ro
+se a
+b ad
+supp or
+tur n
+ur y
+m ing
+photograph y
+n ic
+mar k
+pre tty
+ss ing
+wat ching
+me mb
+ar ri
+coun ty
+be ach
+fr an
+cen ter
+pol ice
+b at
+publi c
+t an
+pre ss
+s af
+s y
+ge ts
+ro y
+n ers
+y our
+bu y
+st ers
+sho w
+as ed
+chil dre
+af ric
+in es
+sp ace
+sc ri
+h all
+pa in
+ar ing
+hom e
+m ur
+heal th
+ch ed
+s and
+rece i
+gu y
+e a
+americ an
+re si
+childre n
+- -
+i ri
+ing ton
+coun try
+ro ss
+le n
+ann a
+boo ks
+b c
+e ce
+d om
+lo vely
+k h
+pe t
+g y
+g ri
+st age
+off ice
+ro ck
+m on
+b ay
+t able
+su n
+m ed
+th in
+l or
+f low
+( @
+uni versity
+stor e
+fron t
+goo d
+z a
+vo te
+nor th
+he y
+an im
+or der
+mi d
+with out
+a de
+re member
+mar ket
+? ?
+mu s
+tra ining
+e duc
+bu t
+co ver
+st an
+sc en
+b la
+bre ak
+l ou
+s ame
+g old
+a in
+o s
+bo th
+l it
+ver n
+a i
+al bu
+p a
+enjo y
+be g
+ell ing
+thur sday
+inf o
+s an
+americ a
+ha ir
+te l
+mar ch
+con cer
+colle ge
+confe rence
+ap p
+h our
+ch ang
+â ļ
+s our
+ol s
+we ather
+w ar
+p hi
+festi val
+secon d
+cu te
+pr ac
+en er
+str y
+le a
+pol it
+s av
+se n
+o w
+m i
+ne ar
+ou ght
+z e
+co ffe
+w illi
+d an
+se y
+davi d
+e se
+f an
+de ci
+the at
+no v
+ati on
+tr ac
+sc i
+re view
+c el
+e m
+u n
+ju ly
+or ig
+ti on
+d ru
+form er
+st ay
+af ter
+in v
+too k
+dat a
+b al
+tu es
+d an
+ev ening
+ðŁĺĤ ðŁĺĤ
+d ol
+u res
+pro vi
+t s
+e st
+sig n
+j ac
+u k
+s ong
+ye t
+bo w
+in du
+j ap
+h oo
+po int
+any one
+z y
+i st
+h ur
+it al
+buil ding
+wom an
+ch ur
+j er
+per for
+co ach
+le ague
+ce ss
+ne t
+i mag
+nati on
+br it
+qu e
+aw ards
+ag es
+wor ks
+c ed
+man ce
+l ate
+ig n
+mon ey
+tru e
+i i
+t ell
+pl ac
+p ac
+as y
+wor ld
+be hin
+im port
+read ing
+gra m
+gi ving
+me t
+h it
+for ward
+st om
+pres ent
+jun e
+so cial
+no on
+mar t
+hal f
+s we
+go vern
+k er
+deta ils
+li sh
+_ _
+ac y
+si a
+ber t
+f all
+! !!!
+) ,
+th i
+d iti
+sp ort
+k ing
+f it
+st af
+c at
+mu se
+cen tr
+y er
+con tro
+b loo
+wal k
+ac tu
+did n
+li m
+lear ning
+re search
+wed ne
+au th
+h ours
+k y
+f ar
+h en
+.. ..
+it ch
+ri l
+str ong
+sk y
+que sti
+jam es
+r on
+d g
+f ur
+c in
+do es
+app ro
+mar ke
+tu res
+ful ly
+ch at
+behin d
+te m
+fin i
+mis sion
+b att
+fe el
+he av
+every thing
+b ar
+w ish
+pre mi
+i ma
+exper ience
+e ach
+re port
+swee t
+tic s
+spr ing
+re spon
+syste m
+vic tor
+l in
+sa w
+al ready
+gh ter
+f le
+ã ĥ
+br ing
+albu m
+- -
+ell s
+st an
+to m
+inter national
+w ent
+an ni
+mat ch
+pp er
+st one
+sm all
+ra in
+fashi on
+are a
+v an
+ag ram
+k o
+thou ght
+wor th
+v an
+m er
+coffe e
+it es
+g n
+arti st
+c on
+ar ch
+c ir
+se cre
+gr ound
+is o
+h and
+co m
+bri dge
+h s
+x i
+l ink
+pu l
+sp l
+r ace
+f li
+ri ver
+g as
+di sco
+d al
+play er
+f it
+photo s
+it y
+o k
+j or
+tr a
+ap ril
+ad s
+a di
+sol u
+beau ty
+do or
+me ss
+up date
+ali a
+sch o
+en ed
+mom ent
+sco t
+sc ience
+i or
+ti es
+ac ross
+ous ly
+sh es
+does n
+p age
+wat er
+m illion
+cla ssi
+l ic
+ca st
+form ation
+micha el
+ell o
+s mo
+in ts
+vi sion
+op ening
+ld n
+au str
+tues day
+win ner
+po ssi
+r ound
+shir t
+di t
+b o
+u es
+il led
+al ong
+tri p
+star ting
+im pro
+k an
+per son
+no t
+re co
+ne eds
+c le
+li e
+re st
+r ing
+win ter
+si mp
+mo m
+be er
+fac e
+tor s
+us a
+collec tion
+ge or
+se ssion
+tr ying
+la s
+la ke
+j en
+orig in
+stu dent
+se cur
+v in
+pic s
+ex pe
+com p
+gon na
+e qu
+b ad
+le y
+a u
+memb ers
+bre ak
+w all
+gi c
+din ner
+bu l
+insp ir
+r i
+min d
+ic a
+win ning
+tal king
+t ren
+s is
+t en
+wonder ful
+s now
+he ar
+th om
+no thing
+gu i
+st in
+blo g
+fe st
+b un
+le e
+war ds
+ch ance
+dre ss
+re n
+pau l
+p es
+tech no
+ru ssi
+c ard
+e ast
+mar i
+w ine
+t i
+la w
+str ic
+k i
+ap e
+au gu
+pro fe
+as h
+cour se
+ma il
+ren tly
+d un
+m un
+lo ve
+is land
+dri ve
+s l
+end ed
+ma in
+lo st
+nat ure
+âĿ¤ ï¸ı
+ch ic
+re por
+p in
+pr o
+st ation
+ce p
+ta kes
+compan y
+go es
+on d
+ma ch
+ra dio
+d ad
+ro ck
+j a
+p ay
+champi on
+e e
+in de
+tt a
+ati c
+t ab
+beli eve
+ener gy
+z i
+t at
+wor d
+on ce
+re sul
+y l
+and re
+an o
+inst agram
+clo se
+t am
+cu stom
+w a
+con om
+sho ws
+li fe
+k in
+ro b
+t age
+n ation
+al most
+list en
+sa ve
+re li
+ac e
+mar y
+tre e
+for get
+j ack
+wa iting
+direc tor
+h ill
+bor n
+te mp
+f l
+st e
+on a
+sing le
+wedne sday
+un ited
+in o
+@ _
+ne l
+celebr ate
+en ding
+de al
+j i
+can ada
+hu ge
+tr ack
+âĢ ¢
+f y
+fan ta
+an g
+yor k
+rele ase
+p un
+ep iso
+wor ds
+t our
+p ack
+i gh
+classi c
+perfor mance
+ke t
+after noon
+recor d
+win s
+pro ble
+âĿ ¤
+f our
+b ed
+ban k
+d ance
+s la
+cal led
+mi ght
+a p
+pa st
+ðŁ ļ
+diffe rent
+it e
+gi ft
+ssi ve
+chur ch
+c us
+pro gram
+ho tel
+ic e
+ma d
+secur ity
+en ge
+d c
+en ough
+st a
+e ty
+de ad
+g un
+he ar
+m ir
+hu man
+gre ss
+oun ds
+pi ece
+bre aking
+gar den
+fi ght
+vie ws
+f ish
+star ted
+run ning
+gre en
+ser i
+s m
+as k
+d or
+de ath
+e conom
+er i
+ir d
+s er
+l unch
+âģ ¦
+bo x
+nat u
+ba se
+b an
+f al
+glo bal
+wil d
+wo w
+out side
+mo ve
+le ad
+an al
+muse um
+on g
+ha w
+pow er
+than k
+b ac
+char ac
+cam pa
+dig ital
+r o
+op er
+de v
+w ol
+p ati
+f a
+m ale
+pap er
+ill ing
+c s
+â ĥ
+educ ation
+ta ken
+e ffe
+m ou
+s ad
+" .
+bas ed
+staf f
+inclu ding
+li ving
+a c
+ch ina
+mo b
+stor m
+lu ck
+ph il
+o o
+y n
+tra vel
+k el
+ti al
+pr ice
+boo k
+import ant
+bi o
+p ool
+ny c
+f ab
+lo ad
+? !
+chall enge
+cr y
+ser ve
+we ar
+bu s
+ta in
+nu mber
+ro r
+k at
+i z
+th ough
+ho sp
+m m
+fa ir
+ut es
+ho t
+po p
+fi ed
+cam p
+develop ment
+li br
+c ali
+em s
+âģ¦ @
+b ol
+is ed
+stand ing
+mo del
+it a
+g le
+bro wn
+ima ge
+ve red
+for ce
+o il
+par tic
+sh u
+da ily
+la w
+se c
+cla ss
+cam p
+holi day
+cl in
+k ers
+pres ent
+gam e
+incre di
+er ship
+inter view
+b ill
+du e
+and y
+ab o
+in nov
+ke y
+ac ade
+p il
+mo der
+st ars
+br and
+f er
+wee ks
+con si
+pr e
+sa fe
+wr it
+di um
+la unch
+marke ting
+ann ual
+as si
+cour t
+la dy
+c ted
+and a
+in side
+chil d
+opp or
+sm ith
+centr e
+gu e
+âģ ©
+f ren
+st y
+for t
+ent ly
+is n
+ke ep
+to ber
+on y
+bo y
+al d
+col la
+de mo
+le vel
+com pet
+ad o
+b our
+fanta stic
+m ate
+s u
+sou th
+oppor tun
+vers ary
+lat er
+bu d
+face book
+la un
+ster n
+p it
+! "
+ma j
+gr am
+tb t
+fi re
+happ y
+a ks
+wh ole
+actu ally
+ill er
+ell a
+lo ts
+al ex
+an ge
+lan ds
+ðŁĺ Ń
+en ter
+r ou
+episo de
+p ed
+in ten
+sh ire
+wh o
+pl an
+h o
+ca ke
+we st
+mag az
+fre sh
+c c
+n ar
+ch ris
+wr iting
+w er
+n om
+l o
+mi dd
+dre am
+o l
+ti onal
+de b
+> >
+be come
+s i
+gr and
+all ing
+hi stor
+ri de
+i red
+saf e
+que en
+ci l
+in tro
+vi l
+d ani
+.. .
+ar tic
+st at
+sh ort
+or ing
+sel fi
+mis si
+do c
+b it
+g all
+b om
+i re
+se lec
+d ition
+ðŁĶ ¥
+fri end
+be at
+gh ting
+ðŁĺ Ĭ
+pe ace
+ex hi
+ant a
+ab ility
+il lu
+j on
+qu ality
+tri bu
+m es
+play ers
+fa ir
+cu t
+c ab
+suc cess
+b i
+su s
+pro mo
+sch e
+an ge
+ic o
+comm it
+cat ch
+ill a
+kin d
+feel ing
+qu o
+s ay
+anni versary
+spo t
+mo ther
+an e
+p end
+your self
+op s
+app le
+min utes
+p o
+gr and
+ri es
+ha ha
+care er
+ed ition
+de c
+ric k
+am i
+concer t
+iti ve
+ge ous
+d ly
+t te
+adv ent
+i g
+li ghts
+ak er
+sk y
+âĥ £
+r ay
+fini shed
+w ay
+s d
+ac coun
+ðŁĴ ķ
+ck y
+ch el
+lit er
+pain ting
+lo s
+st un
+techno logy
+n as
+ma r
+b il
+afric a
+ki e
+ey es
+gol f
+plu s
+ni a
+it ec
+serv ices
+wed ding
+kno wn
+te le
+.. ...
+star ts
+pa ren
+w ants
+ati onal
+mon ths
+win do
+fav our
+er t
+magaz ine
+ex clu
+re ve
+b c
+origin al
+e ss
+n al
+an ti
+st ro
+t ice
+stu dy
+à ¤
+v ac
+nation al
+fi ve
+ra in
+ve ment
+u te
+ver se
+em er
+ar my
+possi ble
+gue ss
+val ley
+ther n
+cro w
+m r
+col or
+on to
+pic k
+cle ar
+dar k
+t ac
+wan ted
+it ting
+can cer
+govern ment
+di e
+ri se
+z ing
+col d
+f oun
+stu dio
+str ation
+bro ther
+a head
+sh el
+mic ro
+ic ally
+d au
+sig ned
+vi ol
+a x
+as se
+i o
+w re
+spl ay
+ch ick
+augu st
+pl at
+ti ps
+sp i
+hu man
+e asy
+lo gi
+mi ke
+gro w
+ag re
+w w
+sh ad
+mo tiv
+wi de
+tur ns
+om g
+v ar
+de fin
+su g
+j im
+ðŁĶ ¥
+t d
+campa ign
+nam ed
+re tweet
+co p
+t v
+le av
+k is
+dou ble
+s mar
+issu e
+vil la
+in formation
+li es
+sto ck
+n t
+di stric
+sh or
+mi x
+er o
+se p
+me x
+see ing
+li ve
+re min
+co de
+g ur
+s c
+wil d
+l un
+h ood
+spo t
+fa ther
+fore ver
+up d
+tra f
+f ly
+ne ed
+gra du
+tra in
+ma ke
+s ab
+be y
+si ze
+lead er
+tal ks
+e u
+lo g
+fo x
+gor geous
+le ss
+le ts
+sur pri
+my self
+no te
+li ves
+f ru
+lo ved
+se ver
+de m
+j i
+so c
+h old
+do gs
+n i
+â ŀ
+lea ve
+air port
+ben ef
+ex pl
+shi ps
+comple te
+ach i
+gre at
+vin tage
+j ack
+ro c
+woo d
+pri v
+off er
+ey e
+ver sion
+te a
+co ach
+off ic
+w ell
+g en
+s at
+h h
+you th
+o x
+? "
+m t
+mi x
+g g
+d le
+natu ral
+buil d
+break fast
+thin king
+theat re
+mo on
+ber g
+go als
+geor ge
+en e
+exc ell
+il ing
+tun e
+y ed
+g ate
+m it
+net work
+jo e
+h ello
+f b
+tu be
+we aring
+ath le
+stru c
+har d
+gla ss
+g ers
+thro w
+g es
+b t
+indu stry
+manag ement
+ali st
+go al
+stre am
+y el
+a vi
+ici ous
+o thers
+s ki
+chri sti
+bir d
+e sc
+m in
+tr o
+l t
+j an
+im p
+ri ghts
+sh a
+or gan
+cent ral
+ar a
+ro ll
+favour ite
+che ster
+el se
+p ay
+car s
+m ine
+ste p
+prac tice
+maj or
+h ang
+ðŁĺ ĺ
+n on
+v ari
+eng ine
+vol un
+di a
+i led
+arch itec
+p ink
+d s
+th y
+wa sh
+web site
+ba g
+contro l
+el li
+f ra
+an sw
+d ence
+y u
+r on
+ol a
+g in
+dr in
+li c
+cou ple
+sp ar
+g on
+cre ate
+c t
+celebr ating
+de ep
+e at
+te e
+vo ice
+dro p
+vis it
+at ors
+sta dium
+f t
+w is
+ro l
+gra de
+fam il
+po ints
+re pre
+w as
+traf fic
+jap an
+or g
+hon or
+tex as
+man u
+âĻ ¥
+safe ty
+re r
+b ag
+em plo
+rele ased
+re gu
+ak a
+n av
+ro le
+sen ior
+spec t
+cro ss
+lin es
+be st
+p ack
+s in
+ti e
+mis sing
+sun set
+li ber
+is ing
+j ay
+sk i
+champion ship
+ac tiv
+la dies
+play ed
+y y
+pu bl
+al o
+pri de
+s r
+pa ki
+lu x
+sur vi
+ck ed
+e ts
+cho col
+austr alia
+par is
+mi les
+h at
+ment al
+al a
+me an
+mob ile
+en a
+in si
+f ound
+chi ef
+t ag
+incredi ble
+re turn
+Ã ©
+goo gle
+fren ch
+cre w
+hal lo
+ali an
+j az
+ch er
+sil ver
+nor th
+eng lish
+base ball
+c af
+lim ited
+follow ing
+app reci
+ear th
+k ir
+ve mber
+w ed
+p tion
+g ed
+oc tober
+fl ori
+c r
+en cy
+ga ve
+lor d
+stu ff
+ber ry
+po st
+sm ile
+bro ad
+st ate
+gg er
+me ans
+ic y
+gu n
+y o
+ma ster
+bur g
+han ds
+ni e
+/ /
+uni on
+brit ish
+big gest
+distric t
+am ing
+h il
+o ce
+per son
+pas s
+en vir
+scho ols
+arri ved
+anc es
+insp ired
+ex pla
+be n
+libr ary
+bo tt
+am p
+ste ph
+cont act
+b ang
+m s
+cali for
+t old
+batt le
+b b
+chic ago
+âľ ¨
+str ate
+sh i
+de ce
+- )
+ad d
+la b
+j ones
+leg end
+cast le
+ing er
+st ance
+be l
+ur a
+re fu
+lead ers
+po t
+se x
+h ic
+artic le
+ki d
+fr ance
+x x
+ex e
+gui de
+volun te
+pr int
+al i
+ce o
+twee ts
+w x
+scen e
+vol u
+ant i
+h an
+as soci
+shar ing
+ro se
+mini ster
+sh er
+in ste
+cle an
+demo cr
+po ster
+sk in
+p sy
+pro per
+cra zy
+i am
+o re
+in i
+any thing
+po d
+mo ving
+cl ick
+ex plo
+com b
+cra ft
+f i
+bloo d
+is ra
+publ ic
+d ent
+ol ym
+eng land
+a si
+ch er
+fac t
+envir on
+har ry
+g one
+me dic
+enjo ying
+just ice
+j r
+indi an
+wi fe
+s ound
+t es
+dra wing
+p al
+ide a
+cr it
+ju li
+il er
+war m
+cl ar
+thou ghts
+def en
+coun cil
+intro duc
+di ed
+jan u
+an i
+s end
+li er
+m l
+intere sting
+tra de
+win d
+b ay
+s ac
+anc y
+sour ce
+b es
+org ani
+ar ly
+lar ge
+ff ici
+ta g
+u t
+de sp
+o es
+tit le
+sy m
+pic tures
+op en
+wom en
+sho wing
+ri a
+le ast
+lead ership
+cur rent
+elec tr
+val ent
+list ening
+c key
+gener al
+de ser
+du ce
+; )
+c ent
+ðŁĺį ðŁĺį
+sco tt
+po or
+selfi e
+ev ents
+i on
+wr ong
+de v
+h ill
+sep te
+cul ture
+l ine
+sor ry
+s ent
+si ster
+ce pt
+k ri
+no vember
+ar i
+announ ce
+z ation
+br an
+g ent
+d u
+l en
+per s
+f m
+mart in
+o p
+e mb
+om e
+midd le
+suc cess
+pe ter
+janu ary
+f lu
+rac ing
+d av
+bi ke
+ðŁı »
+pe t
+shoo t
+profe ssi
+feat uring
+septe mber
+now playing
+sta ur
+z a
+on ic
+qu ick
+bas ke
+spe aking
+mil it
+z er
+chick en
+b ell
+s ad
+co ast
+lo ving
+y ers
+d j
+pan el
+ver age
+s wit
+ic ks
+b ou
+califor nia
+s am
+paren ts
+er o
+k illed
+ph ys
+jo bs
+mi gr
+an th
+e mo
+hallo ween
+and er
+c m
+compet ition
+e ag
+s ket
+sp ir
+may be
+exclu sive
+app e
+jour ney
+scre en
+for d
+i o
+h ate
+u g
+sou l
+her o
+soci ety
+sy n
+gu it
+n h
+d j
+as es
+im pre
+ti me
+sal es
+d d
+f ts
+summ it
+stun ning
+om s
+tur ned
+cle an
+sof t
+be at
+re staur
+de red
+en ces
+ma gic
+di o
+sh ine
+gu est
+health y
+exhi b
+stor ies
+po pu
+n is
+el a
+bel ow
+fun ny
+resul ts
+s ne
+cur rently
+ar d
+down load
+f light
+m al
+f ine
+p ad
+ch u
+ent ed
+h at
+ðŁij ı
+ste ve
+j o
+mar k
+r at
+b all
+p c
+p on
+b by
+o li
+ar ts
+as ure
+bow l
+att ack
+mi c
+de ar
+ran ge
+en ter
+chocol ate
+br illi
+ac cess
+, "
+? ??
+ch ap
+con st
+t n
+mat ter
+blu e
+gall ery
+em p
+work shop
+lead ing
+y ours
+baske tball
+w anna
+th u
+_ _
+mar ri
+sle ep
+bi a
+ch e
+ma d
+imp act
+o wn
+si r
+chan nel
+euro pe
+e sp
+k itch
+hosp ital
+w ra
+roy al
+f s
+ne u
+qu ar
+ne y
+ac ks
+ch ase
+pp y
+st al
+at ely
+ti m
+dece mber
+r are
+per form
+cre am
+we ight
+ch oo
+ni ght
+ha ven
+fr anc
+kh an
+buil t
+hel ping
+tru st
+ty pe
+gol den
+ta x
+s now
+s wi
+di sa
+questi ons
+ve y
+li ght
+c n
+cl oud
+thom as
+ag ed
+sh ou
+te ams
+gr an
+re ason
+a a
+you tube
+v p
+pi zz
+manag er
+bur y
+cre dit
+tre at
+ma x
+i k
+ma in
+g ing
+de ad
+pro bab
+ye ah
+ã Ĥ
+br and
+so li
+pl ant
+ta yl
+gir l
+ðŁĺ Ń
+nam ent
+au to
+mess age
+ko re
+n ur
+ter r
+ag u
+ma p
+sen ting
+lo ves
+gi ves
+g ab
+z en
+ro bert
+con fir
+w ars
+o m
+sta in
+cam era
+and er
+won der
+a b
+ca p
+s old
+su it
+wal king
+contin ue
+effe c
+dau ghter
+d anc
+cha in
+mul ti
+ki d
+y an
+champi on
+v o
+ta ins
+ho st
+min i
+mis sed
+re sc
+ly n
+fin ish
+del icious
+s as
+tayl or
+i b
+pro mis
+produc ts
+moun tain
+flori da
+regi ster
+tre at
+rec ent
+fe male
+boo th
+mat t
+ve hic
+s op
+mo tor
+suppor ting
+phi c
+ex tre
+dr ink
+lan e
+th ird
+p s
+con stru
+ce re
+far m
+ðŁİ ī
+tu red
+ðŁij ī
+c ats
+a j
+gi e
+shoo ting
+as ked
+paki stan
+am e
+m b
+g il
+leg al
+squ are
+in vol
+dra w
+oo oo
+!! !!
+opportun ity
+p y
+e i
+b ts
+teach er
+charac ter
+john son
+br on
+ly wood
+ch ine
+c ing
+c ine
+d ge
+gam ing
+russi a
+ci a
+quo te
+ric h
+go v
+flow ers
+sp iri
+st in
+grow th
+ðŁı ¼
+comm er
+j uni
+mu m
+r an
+s na
+a ren
+c b
+ac tor
+col or
+si t
+pa ir
+ch i
+bo w
+acade my
+hel d
+r ang
+me tal
+y l
+ac tive
+probab ly
+t ch
+need ed
+spe e
+cho ice
+ital y
+ry an
+ðŁĩ º
+flow er
+v it
+m n
+found ation
+b ak
+si ons
+ne igh
+f loo
+he ard
+re mo
+fre sh
+ing ing
+re f
+to wn
+cl ou
+je sus
+spiri t
+cou ldn
+z es
+ðŁĴ Ļ
+willi ams
+pro ce
+moder n
+pro cess
+sho es
+cre ated
+tri c
+issu es
+ann e
+att en
+de but
+h r
+n it
+sti g
+a po
+e ps
+z u
+ã Ģ
+si x
+car ds
+lan gu
+fam ous
+tour nament
+se l
+e bay
+y n
+st on
+k ick
+announ ced
+k am
+vo c
+brilli ant
+hou se
+che ese
+war ri
+mus ic
+ho ckey
+ðŁĺĤ ðŁĺĤ
+sk ills
+au tom
+smar t
+med ical
+mon y
+e x
+gu ar
+gi ve
+pers onal
+ven tion
+al li
+pre ss
+flo or
+m c
+victor y
+hi m
+simp le
+th or
+ðŁĩº ðŁĩ
+ta il
+lu cky
+ale x
+qu ite
+bo t
+ssi ons
+chall eng
+c ann
+amaz on
+h ell
+b ought
+) :
+ed y
+secre t
+produc tion
+inde pend
+de fe
+ad ded
+p r
+p ag
+be d
+gre atest
+with in
+j ay
+ðŁ ¥
+ire land
+re ly
+s d
+te xt
+dri ving
+pro gram
+spe ed
+col um
+str on
+Ã ©
+fore st
+â ĸ
+mach ine
+co in
+sc ar
+oun t
+bi e
+¡ ï¸ı
+por tra
+comm on
+wre st
+recei ved
+kno w
+inve st
+pl ans
+ac cor
+ad op
+ter y
+re ali
+p p
+k al
+art work
+me an
+go d
+inste ad
+an ci
+motiv ation
+as ing
+inspir ation
+up coming
+polit ical
+euro pe
+m ers
+heav y
+ðŁij į
+fe bru
+scot land
+ou gh
+b t
+bo ss
+sche du
+spe ak
+n ick
+u red
+in o
+e k
+ri sk
+tor y
+pres ents
+b on
+ru g
+st ates
+exhib ition
+il o
+m ill
+br ought
+: -)
+tou ri
+com e
+offici ally
+champi ons
+do ors
+re p
+po se
+ex tra
+k ings
+soc cer
+squ ad
+app lic
+at a
+some times
+t ari
+excell ent
+ðŁĺ ĺ
+stra ight
+car ol
+ri p
+âĢ į
+gra phic
+m ol
+elec tion
+febru ary
+as ons
+l i
+di r
+m t
+n ick
+u su
+m rs
+com ics
+inst itu
+cor por
+v i
+ðŁĻ ı
+tu ral
+di se
+ac ci
+we are
+am ong
+sho pping
+t ill
+wh at
+cha ir
+sp an
+chine se
+innov ation
+jo y
+k it
+cent ury
+ob ama
+ph ili
+f c
+re ach
+c iti
+ul ous
+n on
+d ang
+happ ening
+bur n
+p el
+or ange
+d v
+k ick
+cla im
+ing ham
+ph y
+no v
+pod cast
+wh i
+ni ghts
+ear lier
+be ar
+la h
+exc iting
+or a
+gi ven
+s lo
+memor ies
+contin ues
+produc t
+gh o
+c d
+kno ws
+ðŁİ ī
+publi shed
+discu ss
+y ard
+i phone
+tri es
+w all
+fe b
+are n
+tru th
+win ners
+tu re
+diti onal
+milit ary
+proble m
+m and
+do g
+lo ss
+c ric
+can adi
+ve ter
+villa ge
+" ,
+y r
+un g
+don ald
+ag ing
+bir ds
+sci enti
+le s
+th is
+regi on
+tic al
+itt en
+il a
+ðŁĺ İ
+d ad
+di am
+abo ve
+st ren
+li t
+p ir
+la b
+fo cus
+bus y
+d ur
+app ly
+s ma
+auth or
+ac i
+exe cu
+dom in
+re la
+jack son
+at o
+wash ington
+ðŁĻ Į
+k ill
+popu lar
+ce ment
+ro ad
+e ating
+loc ation
+v ent
+ar re
+n an
+cu sto
+advent ure
+or din
+spor t
+ul t
+lo ck
+questi on
+dri ver
+land sc
+on i
+k ins
+p d
+jor dan
+te red
+k k
+a f
+chil d
+s p
+just in
+en i
+s elling
+z o
+wh it
+bo ston
+partic ip
+sig ning
+happ ened
+he at
+m am
+dre ams
+lo ws
+gra ph
+the day
+head ing
+br o
+ble ssed
+vi c
+ve gas
+h d
+in ning
+ro man
+and ro
+den ti
+u se
+c it
+pro gress
+writ er
+bo b
+ff s
+gro wing
+b ly
+aw are
+ex am
+sp ent
+be t
+sc ore
+bey ond
+do cu
+ad el
+s f
+cou ra
+colla bor
+in c
+priv ate
+bo at
+* *
+z one
+p ha
+b ill
+to tal
+plan ning
+to wards
+plac es
+pre view
+cre ative
+dam n
+ide as
+se ems
+po ten
+say ing
+di splay
+s w
+a qu
+lou is
+by e
+li l
+e mail
+we stern
+ger many
+ell er
+re s
+f ant
+ment ary
+de als
+ric hard
+jer sey
+stren g
+ra d
+pizz a
+mon d
+w are
+l ac
+g i
+ar chi
+c d
+yel low
+rec ently
+re ach
+à ¹
+kitch en
+desig ned
+tr y
+g al
+restaur ant
+at ure
+w w
+j as
+l ma
+ðŁij Į
+pa in
+av o
+min ute
+sch ol
+ther ap
+tic ket
+d ry
+jap an
+diti ons
+ter ri
+sel ves
+happ en
+t up
+ma g
+cop y
+sh er
+free dom
+f ile
+speci ally
+tor onto
+lo ad
+g ary
+re y
+answ er
+lo y
+cau ght
+pri ze
+u ne
+fic ation
+ni ger
+sy d
+tou ch
+feat ure
+jaz z
+recor ds
+him self
+di sh
+ro ber
+spot ted
+ma ster
+wa ve
+fin als
+bu ll
+for um
+al d
+re comm
+ch a
+a e
+d oo
+inst ru
+tru ly
+l g
+in k
+bro thers
+de st
+j im
+m it
+clo sed
+is on
+tri ed
+s anta
+af fe
+w an
+hor se
+g row
+camp us
+rel ation
+nati ve
+jour n
+go v
+o ct
+k it
+b ound
+part ner
+re ma
+crow d
+! )
+c alls
+ra il
+qu ali
+solu tion
+con test
+con vers
+sn ap
+b ase
+in iti
+ta x
+y e
+ent repre
+it or
+constru ction
+foo d
+present ed
+n ings
+cli mate
+k m
+mo del
+b j
+blo ck
+present ation
+dre am
+fi x
+c alling
+bus ine
+con gress
+under stand
+we b
+val ue
+ï¸ı âĥ£
+mex ico
+it ely
+ki m
+char ity
+ref lec
+bl an
+fl ying
+anal y
+famil ies
+b and
+reci pe
+celebr ation
+ac cep
+ar y
+to t
+g b
+intere sted
+cap tain
+âĻ ¥
+ti p
+ab sol
+bra z
+inve stig
+o logy
+de c
+tru ck
+ver ing
+c lear
+don t
+go tta
+ad vis
+beg ins
+ma ss
+de scri
+blo ck
+k im
+davi d
+son gs
+memor ial
+feat ures
+su stain
+' .
+gra b
+jo se
+v a
+con serv
+se ts
+man chester
+fi ghting
+de gre
+ag a
+in d
+sle ep
+pos ition
+ha ir
+sig ns
+pol icy
+it o
+al ert
+st am
+sp end
+w y
+absol ut
+d m
+anim al
+my ster
+success ful
+proble ms
+ro bo
+k ay
+gar den
+p d
+may or
+d ale
+t ol
+off ers
+vis iting
+friend ly
+tre es
+offic er
+accoun t
+ke vin
+ðŁij į
+gi ant
+contin u
+con su
+tr act
+n fl
+ðŁĺ Ĭ
+h q
+b ility
+a ar
+dis ney
+te en
+on ed
+wh ite
+tra iler
+de dic
+al one
+absolut ely
+dig ital
+willi am
+in ation
+s wa
+e e
+enti re
+ger man
+ro ll
+h its
+co st
+st ay
+th a
+ali ve
+accor ding
+co t
+liter ally
+her it
+re ti
+haha ha
+exper i
+li kes
+g t
+ste el
+__ __
+ch air
+christi an
+to wer
+diffe rence
+m d
+tre ss
+mi d
+prin ce
+afric an
+fe der
+foo t
+car ri
+ser ved
+r ice
+sh all
+feat ured
+ck er
+rec ru
+po e
+sen se
+ni fic
+com edy
+cont ent
+f at
+po sted
+con tribu
+tim ate
+li ver
+mb le
+inter net
+ag e
+europe an
+cl ing
+gla d
+ff ic
+sc o
+ak es
+el le
+ter min
+ton y
+p ale
+col our
+seri ous
+pat ri
+movi es
+b m
+professi onal
+ad o
+al u
+br inging
+f alls
+isra el
+ter m
+langu age
+bro ok
+man n
+commun ic
+can not
+ac ti
+p he
+y an
+entrepre ne
+tur key
+log ical
+lon g
+ar m
+ur s
+work ers
+ing ly
+gg s
+ri c
+tu al
+recei ve
+op ens
+ge ar
+soci al
+fe et
+c king
+ad ver
+fin an
+fe els
+sp la
+h r
+ea ster
+bra in
+ã ģ
+fi g
+le dge
+ne arly
+prote ct
+ma ssive
+e th
+aw a
+ðŁĺ ģ
+y rs
+aware ness
+defin itely
+k n
+imag ine
+k u
+syste ms
+ðŁij ı
+f as
+li k
+provi de
+am o
+disco ver
+inf lu
+ma ker
+g az
+fit ness
+stre et
+er s
+te d
+w c
+ys is
+pos itive
+hel ped
+que st
+andre w
+bra d
+b in
+hang ing
+l ing
+bri ght
+se ction
+ma ss
+ðŁĻ Į
+follow ers
+ho sting
+tem por
+fla g
+a ve
+let ter
+k ur
+re qui
+of ten
+cry p
+su ff
+âļ ½
+russi an
+treat ment
+al le
+ha y
+l an
+keep ing
+hol y
+power ful
+pre dic
+fun d
+e specially
+windo w
+je wel
+il y
+ðŁĴ ľ
+gener ation
+app a
+seri ously
+o d
+ðŁĺĤðŁĺĤ ðŁĺĤ
+cer ti
+iri sh
+ðŁij Į
+mi ami
+be th
+v ity
+se cu
+che f
+cri me
+graph y
+ma x
+arti sts
+re volu
+gu ard
+spee ch
+u c
+upd ates
+fac es
+st ant
+chang ed
+repor ts
+low er
+pe ar
+n c
+k il
+loo ked
+spe aker
+s f
+re spect
+ok ay
+oce an
+s itting
+architec ture
+tra il
+se at
+i ra
+le g
+japan ese
+d am
+u lar
+sw im
+polit ics
+finan cial
+ol d
+mou th
+at temp
+de stin
+fi shing
+atten tion
+me m
+chang es
+deci ded
+reli gi
+g in
+c av
+z z
+ad am
+ma c
+wr ite
+beg in
+sc ul
+al ter
+is s
+ath on
+imag es
+m oo
+jo ined
+ðŁĺ ī
+âŀ ¡ï¸ı
+pas sed
+mu sli
+h ir
+lar gest
+cam er
+com ic
+gh ted
+rug by
+bur gh
+gg ing
+te sting
+pre par
+lau gh
+al ed
+impro ve
+beli ev
+adv ice
+sha res
+he art
+tur ning
+s b
+t el
+caf e
+n es
+dani el
+pat ter
+t z
+se tt
+par k
+c and
+st ick
+happ ens
+bri an
+ne west
+e pic
+ad or
+ki es
+war ning
+anim als
+custo m
+ar c
+di an
+gol d
+cor e
+t f
+c ity
+pan ts
+re ality
+con fi
+in ju
+fo x
+gu il
+k new
+âĺ º
+cor rec
+itu de
+d den
+. #
+re duc
+pas s
+f on
+y a
+ow ner
+re turns
+n c
+e ast
+ap ol
+in sur
+th o
+si m
+juni or
+be e
+ang el
+att le
+elec tric
+hor ror
+cra sh
+e ye
+pat h
+sou thern
+emplo ye
+ge o
+t an
+ha z
+r ally
+ðŁı »
+proper ty
+was n
+enjo yed
+gre y
+g as
+bre w
+nor thern
+hol ding
+g p
+ta ke
+ch art
+ly n
+dr ama
+z o
+pa id
+throw back
+cu p
+discu ssion
+down town
+w ill
+le w
+b is
+t ary
+bre ad
+up on
+r ate
+teach ers
+it ation
+anc ed
+cy cle
+choo se
+d c
+ir an
+co w
+da ve
+ra ise
+prin cess
+fa ith
+- >
+indu stri
+sp ain
+guit ar
+fac ts
+m n
+sp en
+cour te
+go tt
+projec ts
+au di
+o sc
+pe ter
+s and
+intere st
+happ iness
+ven ue
+sol di
+surpri se
+poten tial
+per io
+custom er
+i i
+g ni
+manu fac
+e co
+bro ken
+sing er
+vel s
+wal es
+hu s
+in j
+f our
+tal ent
+d ying
+mat the
+fil m
+jo ining
+s ell
+j ar
+lma o
+sur ger
+bb c
+sour ces
+au stin
+ni k
+char les
+f am
+prin ci
+ange l
+cas h
+lo t
+o red
+pla ys
+pl ate
+don e
+memor y
+br ings
+n ba
+solu tions
+teach ing
+gr ace
+cir cu
+hel ps
+foun der
+mar y
+expl ore
+de cor
+par ts
+ch o
+inte gr
+ha u
+is es
+pu tting
+in er
+r it
+v y
+mic hel
+blu es
+every day
+for ms
+bi o
+ye ar
+p in
+t ter
+spr ing
+) )
+po t
+al ing
+perform ing
+sh an
+plan et
+mus ical
+head s
+it alian
+stru gg
+âĢį âĻ
+w ings
+pu mp
+h h
+tr ou
+a id
+pri me
+ear th
+pa int
+mon t
+am y
+bb c
+fab ulous
+fru it
+andro id
+bour ne
+cere mony
+enti al
+? ?
+deb ate
+on ing
+dra ft
+sol ar
+t x
+j am
+cor n
+!! !!!
+bro o
+mil k
+po sed
+o hi
+mo vement
+b ren
+part ner
+p g
+et te
+ar ies
+sh out
+n g
+leav ing
+t ells
+sen s
+ta ste
+kel ly
+wor l
+gy m
+ric h
+e gy
+pi d
+ma s
+â Ĥ
+courte sy
+fran k
+incre ase
+wr itten
+pp ers
+re l
+ha i
+s as
+s ound
+tt i
+w ich
+ri ver
+.. ."
+a g
+fel low
+ro me
+sm all
+gen cy
+ic an
+lux ury
+pro of
+me t
+wild life
+mom ents
+ra ther
+cor ner
+com pe
+canadi an
+lik ely
+therap y
+li am
+econom ic
+indi e
+rou te
+fi ght
+ho pe
+se tting
+ant ly
+cro ss
+fant asy
+de e
+sket ch
+comp li
+ym i
+ru les
+engine ering
+fig ure
+ro w
+. ,
+f w
+syd ney
+w ou
+t ation
+dre w
+us es
+the re
+sp read
+struc ture
+pat rick
+appa rently
+ro s
+h ills
+w we
+ann y
+com mission
+di v
+f ying
+con sul
+anal ysis
+ex i
+ten nis
+vehic le
+ðŁĺŃ ðŁĺŃ
+as s
+high ly
+op ened
+b ann
+ðŁĴ Ļ
+mp h
+wi shing
+v or
+fi f
+give away
+r r
+ra y
+je ss
+g at
+ic ymi
+x it
+high est
+yor k
+pi e
+invol ved
+high er
+ri e
+mal ay
+int elli
+desp ite
+che e
+sar ah
+be an
+reco gni
+ar sen
+tal ented
+pas sion
+ic h
+ab c
+lead s
+dise ase
+v is
+se c
+pre senting
+m illi
+hol e
+sho ts
+de part
+surger y
+gov t
+b in
+du al
+e vi
+lon ger
+ev ol
+scre en
+portra it
+et c
+lo se
+ch at
+p en
+p i
+om a
+s ick
+er c
+compan ies
+en try
+plan e
+gr y
+ven e
+liver pool
+premi ere
+sha red
+a red
+fil ms
+ir a
+holi days
+cric ket
+ici an
+v ing
+. )
+ul timate
+di vision
+con duc
+se pt
+for ces
+mon t
+s mart
+disa pp
+sun shine
+in d
+b less
+ma de
+col ors
+fran k
+ir on
+bott le
+s go
+m ood
+j ason
+er ic
+bir th
+te en
+respon se
+tar get
+state ment
+fe ar
+th el
+al um
+ar ab
+bl in
+direc tion
+ste ps
+er ial
+wor ked
+at l
+ðŁĴ ķ
+fel t
+pol i
+scen es
+hom es
+b ell
+e at
+ate ful
+t in
+l ace
+fol ks
+p se
+an n
+wis dom
+fa v
+but ter
+s r
+are as
+sm oo
+bi z
+dg es
+app o
+mo re
+the m
+effe ct
+windo ws
+sun ny
+cap ital
+tot ally
+c ities
+gr ant
+mb ers
+s low
+au tu
+il ities
+w ro
+ri sing
+st ics
+viol ence
+i gh
+qu ot
+h it
+t c
+herit age
+bu ff
+ne s
+z ar
+den tial
+ex ac
+ed ge
+de ep
+aren a
+be came
+benef its
+mar ks
+mb er
+a z
+am es
+pre ci
+dra gon
+re g
+d ings
+do s
+ðŁĴ ª
+n el
+s ity
+me al
+di st
+leg end
+pur chase
+pic al
+st ick
+f at
+du ba
+profe ss
+car to
+pro f
+coun tries
+respon si
+se qu
+fa b
+tribu te
+hon ored
+prac tic
+pur ple
+an ton
+pa red
+t ough
+summ er
+environ ment
+s ons
+ðŁĻ ı
+m ps
+gi es
+her oes
+t elling
+hen ry
+f en
+know ledge
+Ģ ï¸ı
+f r
+ne g
+u re
+ac king
+hear ts
+s oo
+hol lywood
+ju mp
+sau ce
+schedu le
+tur n
+yo ga
+cre ating
+c ket
+cre ek
+â Ń
+custom ers
+ma dri
+gu l
+asse mb
+moun t
+c ell
+to p
+st al
+dav is
+t wi
+sig n
+premi er
+iti ons
+he aring
+un k
+pati ents
+app ear
+heav en
+al ty
+doc tor
+a e
+plat form
+je ff
+ðŁĵ ·
+regi onal
+bi d
+box ing
+ex ten
+or ity
+a w
+w ise
+il le
+sever al
+bi e
+s itu
+sy ria
+âľ ħ
+remin der
+enter tain
+li on
+part ners
+in n
+ph ar
+f au
+pl s
+expe cted
+sug ar
+deci sion
+s b
+ch ron
+associ ation
+leav es
+vis ited
+sh ap
+ðŁĴ ĸ
+fur ther
+h ann
+w i
+run s
+l er
+fun ding
+fil led
+.. ....
+tin y
+han g
+or g
+co ol
+se min
+ðŁı Ĩ
+spon s
+nav y
+sa int
+dru g
+d al
+r oun
+co vered
+tra ditional
+invest ment
+de te
+al ism
+f low
+n is
+sun rise
+fe at
+f ted
+we ird
+je re
+ve gan
+medic ine
+an o
+ac cu
+deli very
+temp le
+chang ing
+wil son
+phili pp
+re fe
+n d
+is er
+g ay
+r and
+ati ves
+t ely
+p and
+intelli g
+g are
+am bas
+de mon
+commit tee
+strate gy
+refu ge
+bud get
+prote c
+pi er
+ex press
+nom in
+econom y
+al low
+ic on
+gal ax
+o h
+indi vi
+dem and
+vir gin
+lu ke
+ali sts
+man i
+s mi
+ju dge
+ent y
+mic hi
+resul t
+am ed
+spe aks
+' ,
+hou ston
+sh in
+b ing
+fl y
+ch em
+au to
+v as
+ge t
+ar m
+thank s
+d in
+gan g
+x x
+si on
+loc ated
+p l
+jo sh
+in fo
+jo ins
+adver ti
+ot d
+el d
+si e
+re asons
+v ent
+ðŁĩºðŁĩ ¸
+â ł
+convers ation
+stu di
+ðŁĶ¥ ðŁĶ¥
+go s
+s ounds
+un it
+mu sc
+ge l
+ack ed
+pac i
+co s
+de re
+u u
+a o
+la m
+inspir ing
+ar ms
+tw are
+mat ters
+ad dic
+du de
+ex t
+cri sis
+b ath
+me et
+sing h
+expe ct
+del hi
+resc ue
+wor st
+au g
+shi pping
+ser ving
+st o
+dar k
+ac es
+histor ic
+landsc ape
+desig ner
+b illion
+gr ateful
+wa ke
+e ve
+m iller
+hou sing
+dy nam
+is co
+be ha
+sh op
+pr ou
+e as
+a sia
+e ding
+k on
+depart ment
+aw ar
+mar ine
+in ci
+photograph er
+ta pe
+lo go
+r ings
+d it
+-- --
+vin yl
+w c
+vo ting
+se ven
+ambas sad
+dal las
+t u
+com ment
+k ra
+b les
+w ag
+u d
+au dio
+stri ke
+offici al
+o ts
+me tho
+to ols
+ra di
+al an
+hun t
+wat ched
+a ke
+fa ke
+drin king
+mer ry
+m l
+b day
+ri o
+ni ke
+c ant
+re pe
+co stu
+mur der
+ak ers
+ch ers
+ou ts
+beg inning
+so s
+ad es
+n in
+not es
+wro te
+sol o
+c i
+li ghting
+ur ban
+bre xit
+att end
+shir ts
+pla yo
+ac tress
+pl ic
+stand ard
+quot es
+par ade
+anci ent
+Â ©
+tur ing
+re e
+pri mary
+fla sh
+citi z
+mat es
+ste in
+z i
+clin ton
+sk in
+gen e
+hu m
+g ar
+t le
+y i
+fo cu
+de an
+pl ants
+cy ber
+b u
+om e
+ho p
+ad dress
+ti x
+gi fts
+relation ship
+sub scri
+fe ed
+exac tly
+haw ks
+ex o
+stre ss
+s n
+arre sted
+an e
+sof tware
+z ero
+the me
+mu mb
+im migr
+mi a
+make up
+ple asure
+uni vers
+har b
+eng ine
+ap er
+r in
+br a
+institu te
+le ather
+al th
+sing ing
+co s
+gh ty
+me as
+st ic
+si de
+insur ance
+co t
+pit ch
+moun tains
+cri min
+su pre
+valent ine
+at er
+wou ldn
+sc ale
+rel ated
+re gar
+star tup
+pack ed
+mi ke
+week ly
+p ts
+coun t
+ha r
+gott en
+min d
+ber lin
+con ditions
+swit ch
+cor n
+sa ve
+g li
+emer gency
+tun ed
+sto ck
+discu ssing
+every body
+s day
+whe ther
+wrest ling
+ec es
+gen der
+ch en
+ðŁij Ģ
+madri d
+mar athon
+e gg
+i er
+th x
+as king
+kore a
+wol f
+ay a
+g m
+g au
+at ory
+v r
+gra ss
+k illing
+b ble
+ur o
+un i
+e th
+sh ore
+th en
+re ale
+bot tom
+ex erc
+k ar
+or ies
+ad ri
+san ds
+se x
+. '
+volunte ers
+per form
+par liam
+inclu de
+deli ghted
+execu tive
+fu el
+kis s
+ã ħ
+char ge
+h u
+ca kes
+ve t
+g lu
+agre e
+pr ices
+n au
+h l
+g ru
+ra j
+streng th
+b ic
+sp ending
+al es
+av en
+b last
+: (
+yo f
+nor mal
+si x
+qu ick
+se a
+d aw
+mee ts
+lo vers
+upd ated
+po tat
+comple ted
+coo k
+opportun ities
+p ure
+organ ic
+tem per
+c am
+avo id
+par king
+duba i
+and o
+di stri
+to y
+comple tely
+don ald
+tri al
+bas s
+b oun
+back ground
+v as
+mar vel
+lu m
+ru s
+t ool
+com missi
+throw back
+fin ding
+is lam
+! ?
+st op
+e vil
+or al
+resi dents
+i denti
+o ak
+ðŁİ ¶
+l il
+span ish
+chap ter
+sto pped
+direc t
+ho sted
+pic ked
+lab our
+lew is
+defen se
+à ®
+health care
+wh is
+mat h
+pe ak
+ra ised
+fi x
+bu ll
+th ir
+chel sea
+fol k
+tr e
+can di
+pau l
+ei ther
+ad am
+poe try
+jewel ry
+ðŁ ¦
+pr ay
+Ø §
+g c
+o z
+wi shes
+fore ign
+sun g
+lear ned
+en e
+n ing
+micha el
+illu stration
+legend ary
+w av
+b au
+ðŁļ ¨
+cal end
+stre ets
+â Ĩ
+mon ster
+bu ck
+g r
+scho ol
+ba th
+wa ste
+ne ck
+ha wa
+be ach
+re plac
+jec t
+on er
+fac tory
+coun t
+ðŁĵ ¸
+mor gan
+der ing
+se an
+steph en
+de p
+no vel
+vide os
+ic al
+press ure
+arsen al
+ex pre
+ir s
+tren ding
+ss a
+fla sh
+re sear
+thr ough
+profess or
+scul p
+to s
+gg ed
+mm a
+be e
+a pe
+hun ter
+am i
+he i
+pla stic
+bu cks
+uni verse
+le gen
+niger ia
+ple ased
+ri s
+thin ks
+autu mn
+i ds
+d is
+anth ony
+ðŁı ½
+ak ed
+gla sses
+fin ance
+z er
+k as
+con tract
+nu mbers
+sh aw
+partner ship
+t il
+laun ched
+s al
+victor ia
+theat er
+usu al
+nam es
+perio d
+eli za
+i th
+bar cel
+ro cks
+bag s
+mat e
+distri bu
+j on
+di ffic
+ali zed
+cur ren
+sco red
+b ha
+du blin
+ro se
+in ted
+soli d
+beha vi
+wal ker
+simp ly
+garden s
+head ed
+in i
+ohi o
+we ap
+f o
+gl en
+e state
+ran dom
+th under
+thr u
+k ill
+jac ket
+it i
+entertain ment
+thanks giving
+ent al
+en coura
+el o
+a ther
+tan k
+high lights
+f ting
+ru le
+model s
+bor der
+bj p
+hus band
+in done
+ken ya
+be ars
+al o
+n inten
+pi x
+str o
+or ders
+sal ad
+ro ads
+n or
+l ation
+sop hi
+ðŁı ¼
+pi eces
+b one
+min s
+inclu des
+nu tr
+phi l
+s ent
+fun dra
+ga in
+bor ough
+n ad
+mon day
+activ ity
+it ems
+be coming
+ken ne
+de tro
+car di
+gue sts
+u x
+world wide
+sever e
+new s
+thank ful
+fic tion
+ve ge
+m all
+si an
+er al
+inj ury
+le e
+men u
+danc ing
+scot ti
+exam ple
+( #
+na i
+studi os
+ba i
+ðŁĴ Ľ
+j av
+diam ond
+vin ce
+ric k
+prote ction
+lin col
+cham ps
+appro ach
+d ar
+m ile
+clou ds
+je ff
+in fin
+l ers
+p les
+pe ace
+go p
+âĻ ¡
+tech n
+str a
+a verage
+ef fort
+introduc ing
+di versity
+austr alian
+am p
+boo st
+s ke
+pati ent
+appreci ate
+ici ans
+pu r
+f ell
+woo ds
+illu str
+ðŁ ĸ
+ag ency
+ac tions
+brit ain
+under way
+se attle
+el and
+ag o
+f ill
+stre aming
+pro test
+challeng es
+ky o
+et sy
+coo king
+exper t
+ru ss
+rain bow
+commer cial
+sp in
+be ats
+c ry
+val u
+el i
+th row
+gr ams
+le vels
+michi gan
+c ad
+ador able
+const itu
+w s
+pu b
+mid night
+th at
+net fli
+braz il
+die go
+regu lar
+jo y
+âĤ ¬
+li qu
+ea stern
+k ni
+fl at
+n p
+bro wn
+w er
+se y
+tt ers
+ac ting
+v anc
+cy cling
+program me
+ra w
+comple x
+tat too
+throwback thursday
+se ssions
+ro oms
+si ght
+speci es
+bom b
+lau gh
+ke eps
+mo on
+offic ers
+con ver
+t r
+ha sh
+t ack
+ri ous
+ad ap
+a j
+reco gn
+ex po
+sug ge
+confir med
+rol ling
+dre ssing
+ic t
+fri day
+ph ones
+ri dge
+con cept
+ro y
+ke ys
+ef for
+c ate
+k ne
+ev en
+l ay
+commun ities
+mo d
+n az
+every where
+al ab
+bit coin
+ban ks
+out door
+feder al
+sto res
+h p
+c al
+m ely
+sig nific
+be ar
+re public
+clo ser
+al lah
+pic k
+x d
+pal ace
+ch ill
+b am
+er ous
+un a
+al len
+out standing
+olym pic
+supp ly
+fi gu
+v au
+l p
+char lie
+un es
+> >>
+legen ds
+ici al
+co ast
+benef it
+mul ti
+f its
+far mers
+am ount
+si sters
+har ve
+hon ey
+que en
+b ers
+pl ann
+âŃ IJ
+m u
+barcel ona
+al ber
+stat us
+re main
+ex tra
+c andy
+vi ous
+âľ Į
+o v
+warri ors
+-- >
+ju mp
+am ar
+x mas
+stu dies
+i ors
+k or
+don ate
+pre p
+fi sh
+im a
+pain ted
+ad mini
+co splay
+spor ts
+dro ps
+fi ghter
+evi dence
+ðŁĴ ª
+la ke
+ro b
+cine ma
+pro file
+Ã ±
+stan ds
+leg acy
+sh ape
+ro of
+ci vil
+i ans
+sy l
+sh am
+vo ted
+re tail
+ph illi
+li sted
+du ty
+n b
+th es
+f are
+au ction
+ffici al
+stor ms
+d p
+l oun
+sh ops
+al y
+ani me
+multi ple
+ðŁĺį ðŁĺį
+psy cho
+je an
+ap art
+candi date
+gg y
+con f
+jose ph
+w ick
+me at
+fr ame
+c l
+for got
+ph y
+f ing
+li ed
+re p
+se ed
+f all
+u fc
+nu t
+lin d
+mo de
+fiel ds
+en ce
+s ley
+ðŁ¤ Ķ
+ch ill
+follow ed
+announ ces
+cor ru
+tro phy
+them selves
+ac le
+al du
+k ong
+l on
+s v
+bro ke
+ander son
+ta i
+stor y
+tempor ary
+activ ities
+k ati
+ari z
+cry stal
+spo ke
+extre mely
+tra ding
+ðŁĴ ļ
+Ã ¼
+in ch
+ed in
+out fit
+equ ip
+ma di
+form ed
+be ef
+po p
+ti ger
+this day
+ti red
+neigh b
+re tro
+is a
+un t
+t as
+kan sas
+de st
+secon ds
+ta y
+hur ric
+o u
+galax y
+dad dy
+bro w
+bur ger
+en ced
+de sk
+ac cur
+secre tary
+el ite
+k ab
+ch in
+touri sm
+bud dy
+ici de
+dre ssed
+u d
+vac ation
+che ers
+com for
+charac ters
+j et
+bu ying
+l ins
+n ap
+reale state
+li e
+af c
+i ii
+f ame
+n r
+b at
+ag ent
+ma kers
+âĢ ¼
+sec tor
+op ti
+le on
+di et
+pra yer
+hi p
+mi r
+le x
+br y
+an a
+pas sing
+w en
+reco very
+ak i
+po pul
+res ort
+mar ia
+stu ck
+read s
+ti er
+perfe c
+netfli x
+p oo
+cham p
+o c
+re duce
+we red
+comm ents
+cla im
+acci dent
+s ag
+h ack
+sal t
+kin da
+k iller
+i os
+z y
+ex change
+lec ture
+eng er
+ic king
+t au
+reve als
+pri son
+z om
+gh an
+u l
+jour nal
+i ot
+tr in
+jon a
+govern or
+cap e
+quar ter
+spec tive
+impre ssive
+bab ies
+t x
+m ill
+o y
+har ri
+jo int
+su e
+collabor ation
+tren d
+revolu tion
+re new
+alum ni
+ge tt
+sh ell
+sun day
+ent u
+ni c
+donald trump
+block chain
+paci fic
+expla ins
+sp y
+ad voc
+par adi
+to f
+star ring
+p av
+fe ed
+br ac
+smo ke
+ham p
+y am
+to kyo
+si mon
+d h
+e ffici
+phys ical
+n j
+ell i
+s low
+gradu ate
+americ ans
+ti fy
+f red
+ap ore
+fin ds
+rob in
+we t
+not ice
+se mi
+un ve
+k om
+pil ot
+scre ening
+da ily
+ðŁĴ Ĺ
+roy al
+sp a
+vo tes
+n ag
+wh ate
+att ending
+exper im
+ad dition
+k ate
+sto l
+m ali
+foo t
+chri st
+ch an
+de e
+lic en
+glo bal
+mo ore
+ti a
+bri gh
+myster y
+y ay
+âĿ¤ï¸ı âĿ¤ï¸ı
+cre ati
+me chan
+clo ck
+di c
+âĢ Ķ
+pp er
+al ph
+through out
+al low
+re sources
+selec tion
+ham il
+bb q
+aa aa
+virgin ia
+dis ney
+en g
+so red
+drin ks
+f ancy
+consi der
+end a
+jan e
+hand made
+du l
+on tari
+i us
+s ville
+color ado
+whate ver
+whe el
+promis e
+ne ver
+desig ns
+ab ly
+sex ual
+vanc ou
+at i
+con vention
+cul tural
+sing apore
+pro mo
+load ed
+gla sgo
+pp l
+n oo
+ke e
+ste m
+men tion
+i do
+cru ise
+ri ding
+be comes
+be y
+âļ½ ï¸ı
+tw in
+dedic ated
+na sh
+de si
+work out
+jen ni
+i v
+grou ps
+rela x
+pho eni
+li ft
+mix ed
+m ck
+p c
+mu st
+me tro
+ci es
+y ar
+a im
+ang er
+i e
+rec y
+marri ed
+dro pped
+eng ag
+le st
+ambassad or
+op h
+de s
+w ick
+assi stant
+nat ur
+fa il
+l td
+shor t
+k ap
+sha w
+bi gger
+rema ins
+crit ical
+sur vey
+co verage
+er son
+win d
+n b
+bil ly
+let es
+ac ts
+jim my
+at lan
+al and
+t c
+import ance
+dam age
+f g
+stor age
+tw t
+bon d
+bal ance
+cr ying
+pu ppy
+vo te
+pu sh
+ðŁĴ ľ
+pol y
+me l
+lon don
+terr ori
+effec tive
+corpor ate
+atl anta
+jac o
+nas a
+gre ek
+sen ate
+i sh
+ev a
+intellig ence
+effor ts
+al co
+k un
+h all
+di ag
+claim s
+fir st
+h b
+ba e
+v ul
+pu ll
+Â °
+se par
+spe ed
+vic ti
+on thisday
+audi ence
+r ates
+te ach
+fil ming
+bu sh
+son g
+y um
+br un
+ra ine
+aw a
+par ks
+ð Ŀ
+ra bb
+ra ch
+ra id
+reach ed
+ra il
+mo ves
+selec ted
+fr i
+ra ising
+om y
+st ones
+su k
+franc isco
+cas es
+cap it
+con fu
+w tf
+po ke
+equip ment
+gre g
+ess ential
+off ering
+ne x
+pi es
+be c
+cre ation
+chair man
+cro wn
+w al
+john ny
+shi ft
+ne ck
+ban g
+bir d
+ðŁĺ ı
+du ck
+re serve
+de pu
+ma sters
+over all
+no tic
+ju ice
+sne ak
+che er
+cla sses
+eag les
+n ca
+car pet
+ci vil
+coach es
+har ris
+u ps
+b alls
+dec or
+mar tin
+ro s
+v ice
+announ cement
+who se
+ti gers
+ste red
+c ts
+dr am
+ste el
+youn g
+inst all
+supp o
+recor ding
+de ck
+se ats
+l der
+ang le
+bo t
+sty les
+elec tions
+for tun
+n ab
+but ter
+ari an
+ka sh
+in ner
+ou red
+be ast
+we i
+ic onic
+exper ts
+ne cess
+b eng
+jam es
+li a
+gre ece
+ðŁĵ ·
+ðŁĺ ģ
+good bye
+m itch
+tw ice
+mumb ai
+ste am
+ru sh
+med al
+ne tt
+fashi on
+t ar
+r s
+sav ing
+ric ul
+l m
+sleep ing
+brook lyn
+mis s
+sen ding
+disco vered
+sp here
+of theday
+k icks
+missi ons
+w right
+er n
+ght ly
+i ous
+mel bourne
+star tu
+mo ved
+car ry
+d ak
+ag ues
+bel gi
+e ma
+way ne
+do t
+er ie
+pe l
+it unes
+matthe w
+no body
+est ab
+cal m
+win ds
+lu c
+prep are
+tren ds
+exerc ise
+adv ant
+ðŁĴ ¯
+athle tics
+app s
+c tions
+adv ance
+laun ches
+litt le
+real donaldtrump
+eliza beth
+carol ina
+hu b
+hi dden
+n w
+us er
+pol l
+great er
+mo st
+f ed
+p at
+life style
+s ati
+sco res
+marri age
+l r
+aven ue
+de serve
+ri f
+ðŁ Ĺ
+wat ch
+champion ships
+gr ay
+en ni
+cot ton
+g om
+whe re
+pack age
+su m
+ab solu
+new ly
+foo ds
+ty ler
+assemb ly
+musli m
+ban k
+re memb
+op tions
+produc er
+land o
+fun ds
+u pper
+shad ow
+pro gre
+co p
+ing e
+leg s
+detro it
+hill ary
+jo se
+gi ants
+sou p
+sustain able
+t us
+clo thes
+roc king
+n z
+min ne
+mat eri
+bru ce
+ear t
+ca sting
+independ ent
+thou sands
+ta h
+de cl
+veter ans
+li ons
+wra p
+âĢ ¦
+de ss
+bl ing
+st ine
+e ggs
+o on
+clo sing
+z ay
+at t
+bac on
+fa il
+ariz ona
+de pre
+gho st
+new sp
+w ers
+vi p
+li ked
+id ent
+volunte er
+ad ult
+pu pp
+cir cle
+mat erial
+degre e
+gro wn
+boo m
+calend ar
+su r
+vie wing
+ath letes
+ch and
+re ll
+asi an
+en tr
+vol ley
+victi ms
+bo dy
+m ama
+trans fer
+ge ek
+in dic
+sav ed
+ma i
+g ent
+it s
+loun ge
+k ol
+the ory
+situ ation
+is lands
+ar th
+z oo
+floo d
+vi ously
+show ed
+parliam ent
+ch ev
+el ine
+at trac
+ab ad
+ta il
+h rs
+lu s
+por tu
+gor y
+provi des
+to ys
+de ath
+in fe
+an ce
+g le
+li am
+lo ver
+hu d
+dv d
+reve aled
+g w
+re ment
+ca the
+l ying
+ra dio
+der by
+stor s
+che mi
+hosp it
+âľ ¨
+' :
+ilo ve
+le mon
+re public
+s ni
+ne ss
+do or
+re action
+pre gn
+fla v
+schol ar
+spo tify
+is ation
+vis ual
+aw are
+spon sored
+jo ke
+less ons
+leg is
+lo ck
+si mil
+ðŁĺ ĭ
+kin d
+la y
+ma h
+ho ping
+vancou ver
+as er
+clean ing
+gal a
+thre at
+la p
+ach e
+ro mance
+ex pen
+re post
+z am
+e pi
+mir ror
+o ak
+ad ul
+bat man
+s lu
+l c
+vie wed
+re views
+d ates
+indone sia
+acti vi
+off en
+lea f
+i si
+ag ricul
+costu me
+s ites
+spir itu
+appear ance
+ir y
+st air
+applic ation
+spec tac
+ic ity
+ski es
+hand le
+pun k
+paradi se
+t n
+de al
+provi ding
+do c
+recei ving
+bre w
+micro soft
+Ã ¶
+fer r
+me tro
+th ail
+y um
+car ter
+Ã ¡
+gent le
+bre aks
+coo per
+show case
+cu tting
+egy pt
+bab y
+semin ar
+gl ori
+ss on
+fa ve
+re hear
+lo tte
+la dy
+al as
+pre p
+deli vered
+nu clear
+ir o
+engag ement
+at ta
+con ven
+z an
+gl ory
+hol ds
+busine sses
+str ange
+sch e
+it self
+gra d
+mar kets
+f alling
+st ats
+ge on
+bu dd
+li s
+she et
+thi si
+co lo
+deser t
+regi stration
+ig n
+expla in
+inter ior
+la ws
+writ ers
+spr ings
+k r
+fri ed
+blo om
+inf ra
+a o
+cre d
+pa st
+line up
+bo o
+bre a
+boo ts
+celebr ity
+att acks
+bro ok
+ev es
+ex cu
+cher ry
+oo p
+fas cin
+boy friend
+se as
+n ine
+effec ts
+po wered
+k ha
+ðŁĺ Ģ
+sh out
+con dition
+i j
+her o
+enter pri
+win ter
+applic ations
+sho e
+g el
+batt le
+pro grams
+w art
+ðŁĴ ¥
+ra p
+ho l
+dang erous
+di a
+coun ter
+ric s
+i or
+k night
+co at
+emo tional
+at ures
+d as
+whe el
+fore cast
+tran sport
+glasgo w
+king dom
+prepar ing
+im medi
+ff in
+awar ded
+prin ting
+ro man
+fight ers
+any more
+bel t
+p ine
+win e
+x i
+employe es
+logi es
+al led
+de mo
+birth day
+ange les
+lo g
+dri vers
+neck lace
+k ath
+s it
+athle te
+ef s
+s burg
+pur pose
+resi stance
+rele ases
+t is
+vari ous
+deli ver
+ch al
+s anc
+opp o
+cra w
+neu ro
+dr a
+suppor ters
+sna p
+diffic ult
+swe ar
+logi st
+pa th
+attemp t
+à ¥
+swim ming
+ste ve
+hur t
+inclu ded
+b ap
+wa re
+ðŁĴ ĭ
+end ers
+ja ke
+le eds
+cli mb
+l b
+im ple
+li sa
+clo thing
+ðŁĺ İ
+d t
+com pla
+sw ing
+stra w
+v als
+k le
+us ers
+stor m
+cu ts
+ontari o
+p an
+hand some
+i ow
+ar gu
+chec king
+scotti sh
+Ķ ï¸ı
+si er
+em ma
+po d
+patter n
+de sh
+en h
+ed ward
+t ing
+k h
+hal f
+lincol n
+mo ther
+al leg
+r c
+volley ball
+d n
+g ay
+all y
+le ton
+gro ve
+l oud
+adv anced
+re spec
+cli ent
+supre me
+thail and
+ho w
+gi g
+to i
+do t
+dol lar
+ðŁij ĩ
+p it
+r b
+h n
+produc ed
+gg ers
+âĨ Ĵ
+ml b
+can vas
+fin eart
+us d
+in the
+p son
+actu al
+s l
+t b
+ip ad
+en sure
+u mb
+w d
+sk a
+mar s
+k end
+f eli
+th ing
+count down
+absolu te
+r out
+dra l
+p y
+inju red
+min t
+hun ting
+mm er
+s age
+li gh
+ac ity
+ex pan
+mur ray
+ar o
+sec ure
+four th
+eag le
+reli ef
+st akes
+industri al
+clar k
+under standing
+see m
+pl enty
+sil ver
+cla u
+thre at
+sa il
+pro duce
+ab str
+is is
+b r
+eng ers
+wor ry
+bie ber
+s j
+just in
+reali ze
+ky le
+esp n
+fil ter
+s ch
+ty pes
+game dev
+d ing
+twit ter
+soldi ers
+p om
+car bon
+y ards
+child hood
+ri ed
+ke l
+ele ph
+t ons
+key note
+qui et
+wi re
+po sting
+is sa
+repre senting
+bac ks
+alex ander
+celebr ates
+ta ining
+| |
+ch or
+esc ape
+pe ek
+ti ves
+fiel d
+ssi e
+im pac
+spons or
+r c
+we dd
+cann ab
+si des
+trac ks
+com par
+con trac
+techn ical
+bi ble
+expl oring
+sh are
+tra v
+n ate
+ill o
+sc ru
+m ingham
+gun s
+of the
+sh ame
+se es
+ca tho
+ac cess
+ce l
+repor ted
+Â »
+mari o
+p ad
+hope fully
+ou se
+y on
+disapp o
+ol o
+p itt
+pa c
+ga p
+cru sh
+s g
+k le
+ge m
+emp ire
+dir ty
+a is
+avi ation
+ze aland
+fac ing
+high way
+d anny
+spi der
+ot ta
+ðŁĺ Ħ
+w y
+col ours
+in fl
+co sts
+olym pics
+au s
+h m
+ho ward
+pas ses
+lau ren
+mu sh
+op in
+r ho
+disc ount
+oper ation
+em ily
+mm m
+cham ber
+d il
+to yo
+shi p
+sam u
+pic tured
+un ic
+po l
+keep er
+carto on
+st en
+ig nor
+n ations
+n l
+ta sting
+deta il
+offici als
+mo tor
+franc is
+ed itor
+ðŁij ĩ
+pe ts
+rang ers
+t g
+r n
+w ri
+nic hol
+i se
+spo ts
+ani e
+chec k
+tri ple
+ku mar
+spe akers
+ic ing
+pre pared
+ab use
+friend ship
+mon th
+swi m
+air e
+sc ent
+hamil ton
+indi an
+j es
+yum my
+te ars
+da wn
+i zed
+worl ds
+ðŁ ķ
+b illi
+st one
+n hs
+ba sic
+p or
+st le
+ir on
+ol der
+cle vel
+e ing
+ðŁĺįðŁĺį ðŁĺį
+prin ts
+fir m
+air craft
+fin est
+devel op
+aar on
+t z
+gra ham
+own ers
+fo li
+less on
+qu es
+bab e
+cra ft
+ph en
+ju n
+bir mingham
+v ine
+ll er
+i an
+fineart america
+evol u
+st ab
+im per
+war d
+com ic
+wi z
+inv ited
+du ke
+mat ch
+por ts
+ro ger
+diag no
+ke pt
+te st
+vis u
+r hy
+so c
+to x
+b aker
+sur face
+co vers
+man s
+b its
+x box
+ff le
+n an
+gar d
+h art
+wat ers
+v illa
+re tro
+light ning
+catho lic
+democr acy
+neigh bor
+pen n
+cr an
+jona than
+la ura
+vi bes
+su b
+coach ing
+clear ly
+uk raine
+bra ve
+commit ment
+t all
+mar t
+ra p
+mo di
+sco tt
+bro s
+show er
+ðŁı ¾
+âĺº ï¸ı
+cou sin
+appro ach
+br e
+com pos
+hil ari
+phil ly
+g ad
+quick ly
+ri an
+t m
+vir tual
+hou ses
+k t
+phoeni x
+w ire
+ff y
+b unch
+anc ing
+tal e
+snap chat
+star ter
+h t
+k icking
+ap art
+th y
+) !
+blo gger
+it z
+com fort
+ang els
+w ash
+" :
+ar gent
+re quest
+hon est
+mi ghty
+bo bby
+k g
+ro l
+thou se
+ex po
+h c
+tab les
+mag ical
+po sts
+de m
+n w
+or lando
+ab er
+* **
+ðŁĺ ľ
+environ mental
+trans formation
+mi le
+w ic
+hir ing
+ma ine
+bo ar
+r ying
+ti s
+nit ure
+twee ted
+anton io
+opin ion
+fin ale
+di y
+f is
+th in
+trou ble
+le go
+fi les
+qu art
+sp a
+curren cy
+cli mate
+fan art
+rail way
+sp ace
+ban ds
+dani el
+mo tion
+l eng
+hol der
+oc cu
+mar ie
+cathe dral
+bu zz
+bi es
+nas car
+bm w
+bat tery
+char lotte
+doc tor
+zz le
+se ven
+in san
+d dy
+st en
+lab or
+thr illed
+se ren
+docu mentary
+wav es
+cer tain
+can did
+allow ed
+ninten do
+star wars
+ta p
+home made
+d les
+ther ing
+bre e
+emp ty
+pi ano
+pos iti
+coun try
+por k
+pu ts
+per ry
+m atic
+spot light
+ti st
+or ities
+we alth
+c p
+bar bar
+commit ted
+as sau
+pro fit
+e ight
+hu l
+fini shing
+run ner
+ss o
+insp ec
+char ged
+christ op
+lo sing
+co al
+ho o
+ele v
+de le
+mo ham
+don ation
+c able
+clin ic
+j in
+manag ed
+ter ing
+â ¬
+ur ban
+depu ty
+bb er
+bur n
+acade mic
+o tt
+sta ke
+it er
+sto wn
+ack er
+advent ures
+ad ams
+gre g
+pro m
+vo l
+ac qu
+con gre
+pa int
+citiz ens
+c all
+af ford
+v c
+as ks
+the tic
+independ ence
+â Ľ
+h itting
+bl on
+fu ture
+â ı
+in no
+gen e
+bo ards
+di stance
+se t
+re mem
+th al
+pre vent
+l ang
+ob jec
+su sp
+mat t
+in duc
+bor o
+pi one
+re di
+vir tu
+prin ted
+sco pe
+shar k
+suc ce
+a stron
+il legal
+j ag
+c ting
+ine e
+at o
+rob in
+nutr ition
+b f
+du tch
+b n
+fur niture
+for gotten
+at ar
+ru p
+hy per
+bran ch
+communic ation
+degre es
+on ia
+un cle
+promo te
+or che
+wi i
+j s
+but ton
+ma jor
+c bs
+bri stol
+premi um
+ordin ary
+e dit
+m g
+we ed
+st even
+: '
+gu s
+te s
+cap tured
+dru gs
+do w
+wr ites
+bi shop
+whe els
+ali zation
+disco very
+w r
+rach el
+ne il
+hy dr
+cu test
+entreprene ur
+kore an
+ore gon
+ul ty
+perfec tly
+suppor ted
+histor ical
+t wins
+ell y
+we l
+de vil
+in come
+scienti sts
+de leg
+h en
+on i
+ic ed
+gi o
+cur ry
+reve al
+e g
+buff alo
+n ol
+op era
+camer on
+haha haha
+j ab
+gradu ation
+cra ig
+r al
+i f
+organi zation
+le ge
+g ang
+su d
+edin burgh
+l ack
+fli es
+g ate
+thr ones
+q b
+the real
+e leg
+pp in
+c les
+jam ie
+tn am
+cryp to
+ou l
+p ages
+a se
+roo ts
+stu pid
+a did
+boo t
+prote in
+s ap
+si um
+su s
+end or
+fun ction
+don t
+en na
+ch y
+squ e
+wor ker
+m tv
+e a
+k an
+ðŁĴ ļ
+mu s
+professi on
+t to
+oper ations
+al lo
+c tor
+inv ite
+sc and
+ou th
+z im
+lin ks
+cli ents
+sam sung
+discu sses
+n ell
+ul tra
+some where
+ste wart
+ine t
+de z
+b out
+fac tor
+ti an
+tr ans
+jere my
+d b
+ðŁĩ ¬
+or n
+develop ing
+spo l
+coo per
+ma u
+rememb ering
+tre k
+famil y
+sen iors
+fo ster
+att ended
+w ing
+trans form
+ele mentary
+hor iz
+li sting
+malay sia
+it ch
+warri or
+philipp ines
+russ ell
+m end
+initi ative
+cre ep
+to ps
+br iti
+a ur
+shar p
+adverti sing
+ug ly
+achi ev
+materi als
+bu g
+dev ice
+bon us
+fac ility
+col e
+nh l
+y as
+plann ed
+pol e
+excell ence
+tr ick
+con fl
+r p
+achi eve
+lo an
+swa g
+jess ica
+ho we
+p our
+sc u
+z oo
+r ated
+dre sses
+re bel
+mex ican
+co ordin
+me ss
+atlan tic
+t l
+osc ar
+wal ks
+phar mac
+investig ation
+... #
+cc i
+eas ily
+monday motivation
+y ment
+au ti
+for ced
+ar med
+colle agues
+pap ers
+pro per
+sha ke
+bu c
+le an
+exhi bit
+e vement
+co tt
+bi z
+sp er
+k ent
+sw an
+/ @
+girl friend
+haw k
+âĺ Ģï¸ı
+mon o
+ðŁĴ Ľ
+stat ue
+ðŁĺ ³
+ra s
+te eth
+preci ous
+t ile
+p am
+swi ft
+v ali
+no se
+dr unk
+experi ences
+come back
+gen ius
+wor se
+sh ef
+ra d
+ed it
+hon our
+au spol
+lar ry
+h ire
+gor don
+achi evement
+.... ....
+su icide
+alter native
+su p
+sur roun
+sha ke
+ke ith
+pe pper
+tur k
+crimin al
+be ck
+su m
+w alls
+cn n
+an tic
+of fe
+col li
+win es
+high light
+hawa ii
+emb ar
+l fc
+ðŁĩ ®
+m v
+> >
+at mo
+wor d
+car l
+shout out
+bre wing
+ì Ŀ
+do f
+s ic
+hot test
+col on
+hh h
+shu t
+low ing
+volu me
+apart ment
+agre ement
+de stro
+we e
+religi ous
+iow a
+ro d
+land ing
+re present
+ðŁĵ· :
+la s
+usu ally
+h l
+c ac
+sal v
+al ong
+laugh ing
+be ans
+remin ds
+pha se
+some body
+ma sk
+ran ked
+dest roy
+sc i
+â̼ ï¸ı
+gab ri
+le o
+ro a
+fa iled
+si l
+refuge es
+re vi
+r ing
+ber ries
+coo kies
+y y
+conserv ation
+sh ab
+human s
+de termin
+a in
+ni all
+as su
+mb a
+fro m
+extre me
+vic es
+commer ce
+ght ful
+or dered
+suppor ts
+re cap
+v or
+dro pping
+correc t
+pay ing
+mean ing
+n j
+qui z
+" #
+busine ss
+ðŁĩ® ðŁĩ
+indi gen
+du st
+box es
+bl ind
+x xx
+zz y
+ðŁĩ¬ ðŁĩ
+ss els
+s ant
+dd le
+hilari ous
+desig n
+wonder ing
+vehic les
+k re
+ju d
+rece ption
+par ker
+Ã Ń
+pri vi
+hy dro
+sof tball
+pol lu
+lo cked
+ba h
+e ar
+scri pt
+di vi
+br ace
+geor ge
+the ast
+bel o
+j al
+tion ary
+dent al
+roc ket
+pur ch
+sh ak
+manufac turing
+e z
+it is
+con cep
+tb all
+ch s
+direc ted
+pra yers
+oo k
+phil os
+vari ety
+che ss
+ser ver
+g and
+bal ti
+ðŁĵ ¸
+sel y
+cru z
+spectac ular
+bur ning
+re present
+i z
+t one
+mer ce
+h ell
+bed room
+estab li
+bo l
+com mon
+ãĥ »
+ab or
+kit ty
+hei ghts
+re pair
+willi am
+qu ake
+alab ama
+popul ation
+re v
+re tt
+i sts
+n ite
+le m
+a ha
+clevel and
+r m
+po ver
+ob se
+mon tre
+man ia
+Â ®
+con ne
+car ni
+sh ah
+f y
+u a
+sc or
+strugg le
+bo b
+' '
+appro pri
+deci de
+ff ed
+ca ster
+s ort
+hun gry
+dra g
+ا Ù
+gr ounds
+d w
+sli ghtly
+car din
+dead line
+bron ze
+web in
+bar ry
+sil ence
+e uro
+op tion
+ear n
+ðŁĴ ĸ
+howe ver
+na ren
+na ils
+bath room
+v ine
+ph d
+min ing
+gar age
+( )
+shou lder
+defe at
+di r
+o v
+liber ty
+ple as
+x on
+com pre
+a v
+j in
+ab les
+sil ent
+fam ili
+vis its
+di pl
+ha bit
+milli ons
+regar ding
+innov ative
+sen ator
+r ts
+v on
+k l
+wh il
+requi red
+âĿ Ħ
+lu v
+presi dential
+po cket
+hun dre
+sho wn
+fro zen
+to ward
+fa st
+confi dence
+r ough
+indivi dual
+qu et
+ðŁı ½
+dom e
+fi fa
+engine er
+z en
+re mix
+ðŁĺ ĥ
+pl ant
+min or
+robin son
+as y
+pul led
+cer tain
+potat o
+( :
+pre s
+oc ca
+w it
+it em
+si e
+d ating
+thom pson
+own ed
+an u
+vi e
+te dly
+good night
+ex cept
+ðŁĮ Ł
+ira q
+ki e
+ren ces
+li p
+simil ar
+sau di
+vi g
+arth ur
+pic ks
+mil an
+hon da
+ma xi
+o g
+ste st
+ar ch
+analy tics
+ba sti
+pear l
+ter ry
+hor se
+ast ro
+ac ce
+laun ching
+inter national
+s no
+ta sty
+den ver
+ir l
+pe te
+tor n
+advant age
+var sity
+" "
+sol e
+g c
+lan g
+demon str
+ol ds
+un ity
+ne ts
+insp ire
+cre te
+nash ville
+nel son
+e ter
+wal k
+hy un
+m ack
+tre as
+see king
+ra ge
+bru sh
+ab and
+whil st
+co con
+h ong
+shel ter
+i p
+possi bly
+so o
+it ed
+â Ħ
+rac es
+war ming
+qu in
+tele vision
+mat ches
+ra pi
+ment al
+pal m
+jenni fer
+rol ls
+indi ana
+b ars
+cat ching
+resc u
+candid ates
+fa re
+âł Ģ
+se o
+vie tnam
+alph a
+michel le
+visi ble
+re gre
+wn ed
+app le
+li p
+f fe
+li z
+york shire
+ha il
+se asons
+be gan
+m d
+k c
+la p
+fascin ating
+hel p
+ur y
+u ms
+nu ts
+se m
+along side
+bri dge
+ori al
+o ve
+world cup
+briti sh
+comfor table
+i ve
+hot els
+fair s
+hor ri
+so x
+d ining
+stre am
+bar ri
+ss y
+w im
+ter ms
+v u
+pe re
+l ens
+wal ked
+r or
+l ars
+shi eld
+dou bt
+pro to
+cro ssing
+me ant
+medi um
+ad ding
+e b
+che ap
+fun c
+pap er
+bran ds
+ry an
+feed back
+col lins
+un known
+tro pical
+sand wich
+fal len
+for mu
+selec t
+lo ads
+answ ers
+or i
+mag a
+d or
+du o
+ali e
+dru m
+ur i
+de er
+sou l
+sh ut
+âĺ º
+sto len
+don ated
+bu zz
+patri ots
+ha l
+na sty
+nomin ated
+mon te
+ki a
+th ri
+ing u
+te sts
+pe tro
+ðŁij ij
+ho sts
+ne st
+to pic
+pat ch
+m my
+hu gh
+ab ilities
+ma the
+s miles
+g b
+ag enda
+insi ghts
+chi p
+ph an
+fail ure
+dg ers
+ha i
+signific ant
+sho ck
+ru ral
+gl am
+figu res
+pot us
+o ta
+mini stry
+appe ars
+fe ar
+r h
+americ an
+h att
+son y
+fi res
+e di
+n ou
+e qui
+wh en
+univers al
+mad ness
+i x
+sculp ture
+b ach
+t to
+swe den
+et a
+en to
+develop ed
+month ly
+ma ps
+ra h
+le d
+del ta
+sa ints
+is lam
+ben ch
+fif th
+v ard
+so cks
+wel coming
+j e
+tur ner
+v b
+ad i
+nor way
+ad y
+hurric ane
+por sche
+tra dition
+ex am
+newsp aper
+lu ci
+a ver
+ide al
+d na
+madi son
+ðŁ §
+wit ness
+ac ou
+insi ght
+si mon
+robo t
+sna ke
+n bc
+ac o
+ro ss
+sh ment
+religi on
+ch ann
+in su
+camp bell
+inst alled
+we ather
+hor ses
+ol i
+rober t
+k az
+ðŁı Ģ
+veter an
+th read
+quar ter
+ea sier
+cap ture
+hi pho
+law rence
+roman tic
+pas sion
+cl ay
+ox ford
+th ai
+stu dying
+fi a
+elec ted
+most ly
+c b
+tu mb
+âĢįâĻ Ĥ
+x l
+sh an
+fa ster
+ev ans
+sli de
+sh ri
+see k
+mi es
+chemi stry
+pump kin
+tu m
+, ,
+ro om
+fi red
+li ps
+pres ence
+af f
+brew ery
+arri ve
+sw ag
+photo graph
+pen gu
+chi ps
+at tor
+val ues
+accur ate
+con temporary
+princi pal
+cannab is
+ari o
+any where
+gi a
+democr ats
+buil dings
+li ved
+ap s
+neg ative
+m are
+bal lo
+li on
+diam on
+loo k
+re form
+tom my
+il la
+tre ats
+hundre ds
+port land
+wor thy
+ex cep
+ar ia
+ido l
+be er
+cd n
+y u
+aw k
+ðŁĩ ¨
+c ells
+Ã ³
+ident ity
+dra wn
+de vil
+f inger
+th am
+ðŁij Ĭ
+ear ned
+fin tech
+dol ph
+twee ting
+evolu tion
+ðŁĵ į
+est im
+m vp
+n one
+ðŁĩºðŁĩ ¸
+toyo ta
+au x
+mar in
+b old
+l bs
+ste ak
+mur phy
+it able
+lou is
+sol ve
+pi a
+sk ir
+ill ino
+webin ar
+ban ana
+lo v
+th on
+vo ters
+afford able
+defe ated
+lm fa
+air lines
+super b
+any way
+deb t
+bo red
+ver si
+me tal
+responsi ble
+m k
+s se
+f ay
+cau sed
+f p
+recomm end
+pla za
+spor ting
+alli ance
+au stri
+n n
+t ours
+surpri sed
+arti f
+th under
+sur ve
+wor e
+bri ef
+necess ary
+z ie
+ash ley
+dra ke
+r t
+kni fe
+im mun
+char ges
+a the
+bri de
+rep ly
+g av
+broad cast
+pu er
+brace let
+cap acity
+harve st
+id k
+perfor man
+d ding
+il ers
+par a
+jam a
+pro vince
+ch in
+id ers
+har i
+te aser
+ch en
+re stor
+r at
+fl at
+col om
+ðŁĴ ŀ
+ðŁĩ¨ ðŁĩ
+smoo th
+r t
+p itch
+stay ing
+isra eli
+t cot
+per spective
+do ck
+open er
+lo vel
+x o
+class room
+l ington
+go al
+kenne dy
+sh am
+sp aces
+mitch ell
+home coming
+uk i
+claim ed
+recru it
+ing o
+mu fc
+mon it
+g roo
+resi dent
+per cent
+per man
+otta wa
+int ment
+an xi
+stand ards
+wor ship
+sche me
+f x
+pot ter
+bi an
+athle tic
+af gh
+s se
+sat ell
+par ties
+âĿ¤ âĿ¤
+infra structure
+rela x
+mo du
+wor n
+smo king
+y ach
+practic es
+wc w
+am b
+dome stic
+tay lor
+k entu
+provi ded
+mo di
+ve g
+" ...
+ob serv
+ðŁĺ ©
+be ard
+m our
+an gry
+ðŁĺ ±
+startu ps
+woo den
+di ve
+na il
+anti que
+ro ses
+torn ado
+m at
+^ ^
+su spect
+far m
+de vices
+me ga
+tu l
+scholar ship
+ge e
+disa ster
+arri val
+po in
+mar c
+kati e
+bb ed
+fal se
+deser ves
+ric hard
+ju ana
+fre y
+tion ed
+hy bri
+r w
+sar ah
+ach i
+c ure
+o le
+mor ris
+ch ic
+broad way
+la bel
+pa k
+pover ty
+gol f
+e red
+f u
+er ies
+be es
+alo gue
+st el
+wire less
+je wish
+ti de
+blo cked
+life time
+b har
+sp lit
+am ster
+th i
+jo shu
+br unch
+ha ps
+s for
+oo ps
+ka poor
+hi king
+suppo sed
+ro of
+re as
+tra in
+ti ght
+tru mp
+bas ically
+r r
+ea red
+see ds
+entr ance
+c p
+wi e
+son ic
+vic tim
+he re
+e h
+ear rings
+sal mon
+arc tic
+an ne
+dou gla
+corru ption
+hann ah
+ha sn
+vo ices
+con ce
+att a
+fle et
+clin ical
+democr atic
+ton y
+st ood
+le f
+twit ch
+a il
+honest ly
+incre ased
+dro me
+don na
+accep ted
+visit ors
+ap ar
+ad or
+p ar
+jer ry
+ra i
+brand on
+ab u
+!! !!!!
+me me
+in gh
+glori ous
+b hu
+pu mp
+j ol
+li ke
+fi sher
+ma z
+ag an
+destin ation
+play list
+le tters
+gen u
+br ace
+celebr ated
+bann er
+r he
+dra gon
+ðŁĺ ħ
+sig nature
+gre y
+âľ Ķï¸ı
+al ice
+be red
+ph er
+ber n
+ca th
+ga thering
+sc oring
+influ ence
+sm iling
+de pt
+lo cal
+a x
+ac u
+reti rement
+hon or
+her self
+chem ical
+asse ss
+y all
+fre qu
+appreci ation
+ac a
+cho ir
+cu z
+so il
+c il
+repor ting
+u h
+enterpri se
+gr at
+jaco b
+ru m
+fe e
+j ak
+sp in
+bi kes
+phi a
+ste re
+p is
+bloo d
+t att
+ra ft
+war ren
+sh eri
+back stage
+mar sh
+hash tag
+ther ine
+re in
+game day
+guar an
+reci pes
+min ds
+stron ger
+issu ed
+bic y
+n ak
+ment ed
+sc ary
+u x
+pre vious
+tt le
+th ats
+ac tors
+u ma
+tin a
+bun ny
+promo tion
+u ss
+oli ver
+montre al
+what s
+appreci ated
+la kes
+excu se
+kno wing
+pri zes
+musc le
+shad es
+sco t
+ing redi
+electr onic
+ju an
+comb at
+s ri
+e h
+turk ish
+l om
+stri kes
+pri son
+re e
+po pe
+vi d
+ol dest
+dol l
+sw iss
+certi fied
+cli p
+re turning
+lat or
+le igh
+tt es
+wat son
+heal ing
+el im
+per haps
+ha ss
+k au
+d der
+mou se
+new castle
+indigen ous
+wel comes
+co le
+tau ght
+no ise
+appe ar
+jo e
+can on
+wedne sday
+u tah
+c tive
+dri ven
+i v
+c ell
+stri p
+ac c
+focu sed
+ar rest
+sto cks
+wo o
+â Ĺ
+notic ed
+shad o
+di spla
+ter ror
+bor ne
+secon d
+que ens
+wo ke
+ja il
+no tt
+cam bridge
+har t
+se af
+fa x
+ac cept
+âĺ ħ
+goo ds
+k at
+t win
+h s
+thou sand
+s ins
+su ite
+amp ton
+ar n
+rele v
+ric har
+hoo ps
+n bc
+class ic
+p ab
+soldi er
+de plo
+le ans
+install ation
+cla sh
+le ban
+ee e
+ti re
+belo ved
+fu sion
+travel ing
+ne i
+coo kie
+glo be
+phys ics
+s q
+co l
+wol ves
+d l
+ex it
+" -
+foo tball
+le af
+ster ling
+hi de
+minne so
+fresh man
+natu re
+indi e
+supp lies
+bri s
+iri sh
+ink tober
+doo dle
+ic op
+mess ages
+adul ts
+recor ded
+fix ed
+ar do
+offe red
+under ground
+dr one
+p ine
+ma inten
+and re
+ham mer
+s x
+r ound
+hi ke
+bra d
+ro me
+fu ll
+on ey
+ro ws
+colum bia
+archi ves
+appro ved
+bat ch
+illino is
+recogn ition
+shou ldn
+fo g
+nca a
+ke vin
+human ity
+al though
+pow ers
+p ou
+s ar
+pe st
+alco hol
+con sci
+phil adel
+en o
+t m
+ok la
+cate gory
+particip ate
+accu sed
+bri ef
+po em
+clu bs
+consul t
+ja b
+big data
+amster dam
+ac ing
+certi fic
+n u
+d at
+impro ved
+and y
+campa ig
+pale stin
+p ace
+mo bi
+feel ings
+wol f
+bra in
+pro pos
+inter active
+prin ce
+inde x
+c is
+cha e
+peace ful
+co vering
+ac o
+cour ses
+mon key
+re place
+b l
+bloo dy
+tal es
+brigh ton
+neighbor hood
+g ates
+spiritu al
+af raid
+bre ast
+b ones
+ðŁij ī
+vide o
+w au
+tou ch
+inju ries
+car l
+ri x
+une x
+âĢ ¢
+fre d
+consi dered
+thu si
+an ch
+on y
+u sa
+graph ics
+ac re
+ðŁĺ ©
+com memor
+com mod
+go ti
+guar dian
+star bucks
+pre vention
+haha haha
+admini stration
+portu gal
+fac ulty
+bet a
+ul a
+al bert
+bre ath
+er i
+le tting
+tr ic
+ment ation
+incredi bly
+ten nes
+v d
+ðŁĻ Ī
+ed die
+br ick
+gr ill
+bt w
+wat ches
+resear chers
+t ney
+ni e
+p as
+a ster
+vi br
+poke mon
+ch rome
+go at
+pitt s
+il ly
+festi ve
+y d
+can al
+ðŁ Ĩ
+fi es
+car los
+re que
+partic i
+tra ins
+sam ple
+temper ature
+sym ph
+pic king
+in door
+z ers
+playo ffs
+____ ____
+ap es
+ly rics
+islam ic
+performan ces
+d ick
+spar k
+se as
+hom a
+gr ound
+disc i
+employe e
+com mu
+alas ka
+al an
+fe ast
+dg ing
+ban king
+manu el
+slow ly
+tru cks
+mc car
+oo o
+sc rat
+orche stra
+indivi du
+m x
+bre ath
+stair s
+equ ality
+bla ke
+loc ations
+cocon ut
+balti more
+aa a
+l c
+ðŁı Ĩ
+har vey
+resi st
+immigr ation
+adid as
+fil i
+re f
+lg bt
+mo s
+pp i
+ken ny
+terr or
+ban e
+apol is
+s g
+social media
+ka i
+hon est
+as sas
+bol lywood
+âĢįâĻ Ģï¸ı
+ferr ari
+hor n
+cryp to
+bo om
+mainten ance
+i di
+s man
+w l
+ext ended
+in sul
+ve s
+go sp
+tr i
+pi g
+tar ge
+cel er
+st ati
+sm h
+ri dic
+appe al
+? )
+con clu
+cos me
+she ep
+christop her
+en thusi
+po lish
+me ts
+oun ded
+sustain ability
+creati vity
+con crete
+ra i
+ali en
+ble ss
+te es
+clu b
+ro t
+bo s
+ex ist
+perfe ction
+lu ck
+rock y
+expen sive
+mean while
+happy birthday
+pre t
+thr iller
+ca ve
+playo ff
+som er
+l u
+le x
+def ence
+am writing
+home less
+pro phe
+ch et
+past or
+ðŁ¤ £
+land er
+ww w
+Ģ ï¸ı
+tic a
+! #
+o tic
+rad ar
+po sters
+pow der
+po li
+ha un
+tra p
+bl in
+assau lt
+shor ts
+re y
+sh y
+squ ir
+rac ist
+gar lic
+fu r
+remo te
+sm ell
+impre ssed
+fing ers
+âł Ģ
+din o
+le ment
+s nu
+promo ting
+str ing
+produc tive
+b age
+ma son
+ra z
+direc tly
+j k
+ev al
+ðŁij Ĭ
+doc tors
+co w
+ri der
+st v
+re move
+w u
+na than
+ro d
+n r
+= >
+affe cted
+inve st
+mp tion
+g inger
+o d
+agricul ture
+s que
+mu g
+coun ting
+ke e
+mag nific
+coo k
+ani stan
+roo t
+plac ed
+sym po
+gh ana
+un d
+che er
+thro wing
+secre ts
+f illing
+opti mi
+butter fly
+bu bb
+ðŁĺ ī
+terri ble
+d g
+sil k
+obse ssed
+lo u
+ai de
+sal ute
+mon u
+philadel phia
+scienti fic
+i st
+u ae
+dess ert
+bott les
+can yon
+ðŁĺ Ī
+car ib
+o ther
+w ich
+re source
+guil ty
+un d
+le on
+e ss
+kan e
+el e
+tra iner
+he im
+an te
+man age
+roo kie
+tre ated
+po ses
+rs vp
+cau ses
+aw ak
+je well
+le tt
+on ics
+tit les
+cardi ff
+g aga
+bu mp
+use ful
+? !
+loo se
+bb ing
+: :
+argent ina
+de bu
+cy cl
+wh el
+dis gu
+j el
+k ills
+bio logy
+ex ter
+tra sh
+bo dies
+tr am
+circu it
+expe ct
+la ds
+w ells
+sho t
+ge e
+naren dr
+fa stest
+b ent
+b ills
+mar shall
+h ats
+intro duce
+citi zen
+im possible
+gi b
+az z
+net working
+r ant
+thin k
+in dy
+st ops
+f theday
+bri an
+* *
+amo di
+dom e
+coura ge
+pac king
+af fairs
+g n
+si zed
+ent ary
+pol and
+swit zer
+afgh anistan
+w u
+ten der
+subscri be
+mo sco
+att end
+republic an
+hon ey
+âĢ ĭ
+si mul
+we ster
+foo die
+or o
+midd le
+ab t
+co pies
+ma je
+narendr amodi
+ty pical
+inspir ational
+vit am
+wis con
+cu bs
+tiv ity
+h ali
+e ars
+k ay
+d are
+mari juana
+cu rious
+an ia
+tom ato
+re mind
+ðŁĩ ·
+sc ared
+cou p
+po et
+land ed
+ri d
+wra pped
+mor ri
+climb ing
+e ws
+fe eding
+con tra
+tho logy
+gri d
+ti vely
+read er
+la ser
+di ving
+di g
+lat in
+ti ed
+shake spe
+o ci
+ad m
+show ers
+chu ck
+mar cus
+oo s
+kne e
+o live
+ow l
+dy lan
+an no
+g ym
+deci sions
+well ness
+arri ves
+sati s
+chri s
+thur s
+ðŁ¤ £
+inter views
+thank you
+switzer land
+over night
+journ alist
+ser ves
+vol can
+.... ...
+plo t
+nic ol
+car rying
+mag ne
+tre asure
+ex p
+be ver
+ðŁĺ ¢
+mar ty
+mo le
+don ations
+recogni zed
+b h
+du s
+sh ann
+al do
+success fully
+ent e
+ðŁĺĤðŁĺĤ ðŁĺĤðŁĺĤ
+cab inet
+cu is
+tit led
+d as
+so l
+strate gies
+deli vering
+ad ds
+ani an
+ne ther
+ðŁĴ ĥ
+con tain
+su its
+pa irs
+to dd
+rel la
+ro pe
+ci o
+cro p
+paint ings
+su z
+re jec
+bu st
+d h
+fra ud
+m h
+contro l
+je al
+destroy ed
+al lows
+wo ol
+minneso ta
+om en
+j u
+sympo sium
+d af
+lim it
+accoun ts
+load ing
+inter n
+re solution
+hol land
+qu al
+meet ings
+gra ve
+cam ping
+v am
+re nov
+liber al
+am ber
+gre e
+hu mb
+fe ver
+el ing
+broo ks
+à ²
+be th
+ad ed
+al t
+ro e
+perform ed
+jo sh
+frank lin
+nic ole
+de ss
+bb s
+m g
+net works
+min im
+al t
+weap ons
+gu y
+jas on
+g ha
+harb our
+at on
+pra ise
+kentu cky
+bel fast
+st icks
+blo ss
+ho pes
+an thro
+famili ar
+wa it
+ch ile
+depre ssion
+la x
+je ts
+le ice
+recei ves
+si er
+an k
+de x
+inde ed
+fle xi
+fab ric
+lam b
+hel icop
+am anda
+âĢĶ âĢĶ
+compe te
+sn ack
+techno logies
+sy rian
+mom s
+mu ham
+cho sen
+an at
+dev on
+shar ks
+re t
+fundra iser
+selfi es
+st ations
+communic ations
+tennes see
+tu tor
+ro t
+valu able
+dynam ic
+nur se
+i ed
+earth quake
+deser ved
+a ve
+sar a
+stre tch
+dougla s
+ne pal
+Ã §
+ob viously
+d ame
+ra pe
+any body
+k w
+pat rol
+hol ders
+h anna
+info graphic
+ec o
+be ating
+stan ley
+bo ats
+ri bb
+e z
+wit ch
+inv a
+ac id
+boar ding
+- @
+gi l
+da ve
+care ers
+opp os
+l loy
+in ter
+do pe
+re su
+j agu
+sh ade
+in dy
+on ist
+rel ations
+ag en
+ab le
+inci dent
+me ter
+shar ma
+id r
+pro ve
+immedi ately
+tro ops
+am an
+g low
+gaz a
+blo cks
+person al
+chron ic
+all er
+si d
+sh r
+whats app
+lu cy
+ar chae
+ho u
+journ alism
+our selves
+go t
+the med
+shap ed
+we ak
+cas ual
+leng th
+sla m
+ab bey
+e v
+coun ter
+est a
+reci pi
+cha pel
+expan sion
+sel f
+suff ering
+sp ice
+n z
+sp art
+desp er
+boo king
+quart ers
+y on
+ðŁĴ Ĺ
+p k
+continu ed
+- #
+man hatt
+tal ked
+sh en
+com bo
+hybri d
+je ans
+liqu id
+se al
+re tweets
+ac celer
+collec tive
+t as
+: ))
+profession als
+ra w
+o tt
+su san
+ir ing
+okla homa
+re ven
+survi val
+cre ator
+tran sit
+st ac
+sur f
+i k
+ed iting
+ch illing
+bai ley
+ste al
+ra ble
+pa rent
+hun ger
+sn app
+collec t
+philos oph
+dedic ation
+c f
+c m
+le ep
+repe at
+re ha
+un fortun
+a er
+a ero
+abstr act
+mon itor
+ag ents
+bu l
+sci ence
+harb or
+drag ons
+floo ding
+ac compli
+d ash
+juli a
+the red
+tues day
+cy ber
+b low
+ta ined
+le m
+refe rence
+pp o
+ne goti
+char le
+con nor
+au lt
+access ories
+commissi oner
+rain y
+re ar
+advis ory
+luc as
+ma id
+co al
+k av
+pol o
+ðŁı ¾
+tran sport
+mar gare
+straw berry
+bur ns
+gre ens
+ne v
+partici pants
+col in
+belgi um
+col our
+in form
+d ell
+br on
+cal y
+kick off
+strate gic
+re union
+hon ors
+li b
+egy p
+âŃIJ ï¸ı
+hy po
+si zes
+regi stered
+bet es
+relax ing
+bloo m
+inten se
+valent ines
+insan e
+w wii
+p x
+tri o
+bla de
+wiscon sin
+con e
+plat in
+ali ze
+ra ven
+incre asing
+indi ans
+il ian
+bl u
+rabb it
+exten sion
+je f
+au di
+fer ry
+s ell
+a day
+us b
+swe at
+cham pag
+metho d
+mem ph
+assi st
+s by
+ca pe
+remo ved
+mag n
+v t
+r ams
+f bi
+tack le
+phe w
+h on
+motor cycle
+su spec
+eleph ant
+sub ject
+let te
+da iry
+whe at
+awk ward
+ac t
+tro l
+mit ted
+zay n
+sheri ff
+ene my
+con s
+ke tt
+bul ls
+ev alu
+bt c
+satell ite
+ho lo
+por ter
+dia betes
+bet ter
+rele asing
+sur f
+: -
+se basti
+collec ting
+en cing
+e thi
+go ds
+al ley
+health y
+m ills
+sma sh
+co pper
+cr ack
+read ers
+sp ac
+licen se
+bas ket
+bang la
+en tic
+om i
+m ere
+si vely
+anim ation
+lan es
+dent ally
+chill in
+fi e
+k aren
+dep th
+li pse
+n g
+ri p
+mel o
+sand y
+ðŁijı ðŁijı
+vin cent
+nu t
+hu g
+who le
+cre ates
+? ???
+âĿ¤ï¸ı âĿ¤ï¸ı
+bak ed
+up grade
+rober ts
+har a
+carib bean
+auth entic
+mb s
+mosco w
+attor ney
+wi ki
+ch lo
+hu ll
+cor k
+" !
+sty lish
+ðŁĵ¸ :
+di ary
+impro ving
+ex pand
+bri ght
+pollu tion
+k nights
+person ality
+chec ked
+fac ilities
+z el
+bow ling
+gu er
+ðŁİ Ĥ
+on going
+un its
+hoo k
+be ck
+confl ict
+to dd
+far ming
+educ ational
+k ak
+cla y
+stro ke
+bel ly
+explo re
+mill enni
+th m
+loo p
+sm s
+consi st
+cir ca
+br yan
+d ab
+youn ger
+soli dar
+pp a
+experi enced
+b ella
+bo ard
+shef field
+steph en
+consu mer
+sub mit
+spon sor
+t ang
+ag gre
+comb ined
+trac king
+sand ers
+b az
+survi ve
+fer red
+equ al
+se p
+re ed
+str ong
+priv acy
+st ap
+un g
+ac ry
+pa sta
+pir ates
+ag er
+fair y
+du p
+introduc ed
+wi p
+let s
+spr ay
+ðŁĵ º
+gre w
+a sts
+pitts burgh
+new york
+jo ey
+lau ren
+tra de
+ch op
+pi pe
+cla ire
+behavi or
+v ap
+cre ws
+lap top
+ðŁ¤ Ĺ
+che ster
+disci pl
+d f
+out doors
+k s
+go ver
+super star
+cas ino
+far mer
+; -)
+re turned
+ðŁı Ī
+ma il
+roa sted
+co sta
+v ill
+pe z
+gard ening
+distribu tion
+sh ining
+inve stors
+ra sp
+dec ades
+reali zed
+bar n
+p ti
+st able
+ut d
+pan thers
+m ens
+b n
+ca de
+bu cket
+yn n
+when ever
+wa ke
+da is
+ber nie
+lo dge
+ju lie
+atmo sphere
+ðŁĺĺ ðŁĺĺ
+major ity
+par ti
+exc it
+cu t
+me h
+musli ms
+be gun
+fli ghts
+vene ss
+ce me
+po sing
+so le
+g ou
+dark ness
+pe ach
+cel tic
+auth ority
+grand ma
+ful ness
+smi th
+speci fic
+gar cia
+co ins
+good ness
+aldu b
+recru iting
+den nis
+gar y
+sle eve
+weap on
+pl z
+disco ver
+harri son
+recruit ment
+ja i
+ch im
+com pared
+tom s
+mo thers
+am y
+archi ve
+t ask
+ben jam
+se g
+law yer
+al um
+inve sting
+mi e
+che z
+j p
+a ke
+fl am
+wall paper
+âĻ¥ ï¸ı
+t ton
+che st
+favor ites
+we igh
+coo lest
+r ating
+relev ant
+lo gan
+ma ple
+run ners
+pri or
+peop le
+ma ur
+terrori st
+te sted
+carni val
+su spen
+me asure
+m v
+cyber security
+app ren
+terror ism
+o z
+v ital
+ni es
+gon z
+fun ded
+twi st
+assess ment
+die sel
+en for
+colum n
+ad dressing
+ca sts
+pay ment
+x ton
+fi er
+, '
+la st
+ne e
+un less
+clo se
+sk ill
+cuis ine
+fun eral
+ti les
+a un
+k ru
+relation ships
+ðŁĴ ¯
+ev ent
+âĢįâĻĤ ï¸ı
+kind ness
+pro posed
+acou stic
+a es
+defen der
+dan ce
+h tt
+w at
+vo y
+ðŁ¤ ĺ
+au s
+cli ff
+sear ching
+beauti fully
+in qu
+at l
+speci alist
+ðŁIJ ¶
+da i
+tra ils
+class ics
+inst ant
+v ous
+re venue
+mar ch
+kir k
+fr inge
+fire works
+tri via
+âĺ ħ
+tr action
+wal ter
+mo to
+l ily
+att itude
+cli mb
+sc an
+sav ings
+c w
+fa ith
+cred its
+ab led
+gra ff
+auto graph
+he he
+ran ch
+ha d
+ro gers
+ðŁĮ ¹
+f in
+re qu
+fol k
+ad ditional
+lyn n
+u ber
+dol lars
+lo gic
+wor th
+so m
+the sis
+p ound
+bi c
+st ur
+cer am
+spen cer
+en tered
+v amp
+organi zed
+âľ Ī
+pp s
+tr on
+merce des
+no ti
+compet itive
+do w
+ous ness
+vic tor
+gr illed
+na i
+pu tin
+ab ra
+bl ame
+alex and
+anim al
+dec ent
+p ent
+inter ior
+:' )
+but ler
+bal let
+ðŁĴ Ķ
+albu ms
+down s
+la d
+si r
+pla in
+p ers
+blon de
+dis c
+paki stan
+se ment
+ga a
+w age
+ch as
+man i
+co ps
+terr it
+lo l
+lau ghter
+ri vers
+magnific ent
+lam p
+w b
+new sle
+char ts
+ble ssing
+p unch
+lon gest
+fl oral
+cu tie
+fare well
+sto pping
+mb b
+bu d
+chee se
+de cla
+si m
+mc donald
+de ter
+you th
+t ch
+fre der
+kin dle
+fer n
+at or
+as leep
+p ond
+spr int
+p ounds
+la zy
+gh e
+fundra ising
+dead ly
+gran de
+dou g
+he y
+lin da
+consi dering
+i um
+gol den
+vi k
+auth ors
+di ss
+u ally
+appropri ate
+mor ning
+y le
+hon oring
+foli o
+be c
+re bec
+fin land
+formu la
+corn wall
+sh ay
+cau sing
+bl end
+sig nal
+t ent
+kash mir
+nation als
+har mony
+sc out
+acce ssi
+he ight
+medi eval
+impro vement
+ke es
+prac tical
+car d
+de par
+hu n
+om ing
+cal gary
+ste l
+bu bble
+gur u
+ma h
+unex pe
+n h
+ed a
+me at
+i ge
+si o
+god dess
+in ches
+tun es
+br itt
+sti on
+ra j
+âĻ «
+mer cy
+ðŁĴ ĺ
+sen ds
+i est
+pol ici
+val e
+reduc ed
+as ap
+vi jay
+defen sive
+celebr ations
+ri ders
+med itation
+har mon
+g ing
+Â ¡
+program ming
+in au
+sud den
+m h
+replac ement
+sk u
+j ar
+gra des
+ta st
+k itt
+brand ing
+k aw
+boo t
+f ought
+p ays
+g f
+iz ation
+ho p
+k k
+activi st
+v end
+coast al
+cha os
+ðŁĶ ´
+se me
+bill board
+li fting
+cu mb
+sc al
+ðŁĸ ¤
+stru ck
+l v
+indie dev
+beat en
+jun gle
+al right
+destin y
+m ing
+k c
+ch ances
+om an
+q atar
+cra f
+tra ined
+pri x
+char m
+o tive
+s mu
+e c
+and ers
+hand ed
+al ban
+certain ly
+arri ving
+i ze
+sa i
+tr ack
+pain ter
+hu mble
+appo intment
+head line
+manag ing
+mo d
+as pe
+andre a
+Ã ¤
+ethi op
+un ited
+exi st
+bal i
+k ad
+n t
+d red
+re x
+recogni ze
+tam pa
+be ers
+ati a
+he els
+no te
+transport ation
+tur tle
+re de
+hipho p
+sp icy
+sp urs
+⬠ĩ
+cor p
+ther n
+to ast
+hur ry
+proper ties
+ma ge
+mar co
+ele ments
+bou ti
+syn drome
+ms g
+develop er
+gra ders
+he im
+re sil
+off ices
+del ay
+di men
+vin tag
+barbar a
+ðŁĺ ±
+vene zu
+cu lar
+fac ed
+bar n
+ðŁĺ Ĩ
+survi vor
+wor m
+confu sed
+passion ate
+Ø ±
+identi fy
+electr icity
+sou ls
+brad ley
+repor tedly
+lun ch
+shel f
+eli a
+swee t
+smoo th
+emplo yment
+am el
+manhatt an
+ste am
+oun ts
+ye p
+li ving
+un e
+descri be
+ca res
+man ila
+sha wn
+ac ted
+bas h
+st even
+re st
+pet ition
+div ine
+wel sh
+rac e
+platin um
+ðŁĮ ¸
+p b
+extra ordinary
+solidar ity
+m all
+on ion
+schedu led
+game of
+fer gu
+de ms
+nor m
+p k
+tri als
+polici es
+publi shing
+st ole
+fron t
+charac ter
+van ia
+ex ce
+sti e
+sc a
+resi dential
+sa iling
+ðŁĶ¥ðŁĶ¥ ðŁĶ¥
+spons ors
+th ick
+champag ne
+she pher
+continu ing
+ven ice
+per th
+na p
+a ster
+y ak
+un limited
+cho ices
+ne o
+hi v
+repor ter
+bru ssels
+f old
+dy s
+se mi
+la wn
+it alia
+wi fi
+as k
+em ed
+fr ame
+monit oring
+ste ad
+i da
+gr in
+is a
+fli p
+re stric
+offen sive
+atta ched
+di sh
+wh y
+philli ps
+gre et
+p als
+mix tape
+v ou
+fiel der
+spar k
+alber ta
+g len
+ca sh
+s ri
+u ri
+ro dri
+entreprene urs
+climate change
+p sy
+d le
+em ents
+lin ked
+nether lands
+acci dentally
+oppos ition
+vel vet
+ra ys
+c w
+om o
+m f
+lmfa o
+newsle tter
+: )
+toi let
+liter ature
+di sp
+phili p
+uni form
+sudden ly
+head er
+cool er
+-- -
+prou d
+bri g
+nis san
+scienti st
+j ah
+con centr
+pac ks
+appo inted
+so ap
+eng age
+cho se
+âĻ ¡
+se tup
+jeal ous
+har ry
+g ation
+tun nel
+te mp
+osc ars
+dec ade
+recomm ended
+child ren
+ab a
+anxi ety
+ve ments
+sal on
+pho too
+organi z
+mach ines
+ab s
+vil le
+hy pe
+ti ff
+emer ging
+av geek
+[ #
+contribu tion
+bra dy
+re sto
+g mail
+fit z
+photo shoot
+hel met
+h t
+eleg ant
+ug anda
+nur sing
+or leans
+pen n
+na h
+foo tage
+em a
+w o
+w ad
+concer ns
+ve re
+re mark
+who ever
+str ang
+p t
+qu it
+sh ang
+histor y
+s ick
+perman ent
+ill ness
+col d
+visi on
+he m
+ar row
+con vic
+pin k
+oc cup
+bal d
+ex hau
+u of
+am o
+on t
+ãĥ »
+adop t
+la id
+smo ked
+inter pre
+ess enti
+associ ated
+b d
+bb y
+fi er
+inst all
+dipl om
+con diti
+c f
+w ak
+any a
+gr aci
+fi sher
+s ss
+ap r
+il it
+mus ician
+symph ony
+cor d
+h ack
+le gi
+l v
+bless ings
+hum or
+sc ra
+e ti
+min ster
+trav elling
+bu sh
+jewell ery
+li me
+!! !
+pregn ant
+pe e
+lo b
+cap ital
+ip a
+pen cil
+la bor
+duc ks
+prou dly
+wedd ing
+dere k
+m w
+pe g
+valent ine
+an gu
+re treat
+pro spect
+dang er
+vul ner
+up set
+, #
+sr k
+x im
+thur sday
+n fl
+kis ses
+re ds
+cr ack
+re ward
+c u
+ko k
+me te
+aband oned
+it t
+me als
+sp ell
+stan bul
+del ays
+ru m
+le op
+gu m
+no va
+super man
+ch ick
+m is
+dram atic
+inno cent
+r ounds
+re c
+auti sm
+bangla desh
+mor al
+mo vie
+sp oo
+k la
+âĥ £
+ou ting
+mess i
+ab road
+loo kin
+a im
+q i
+st ack
+colla ge
+à ¯
+hud son
+sc an
+ho e
+ch au
+oc cur
+comm ander
+ho les
+ðŁİ Ħ
+bi as
+v on
+stick er
+ma k
+responsi bility
+colum bus
+sa int
+ed mon
+rac ism
+far ms
+w en
+gul f
+may o
+!!!! !!!!
+corpor ation
+ba chel
+el a
+inter nal
+je ep
+fol lows
+di alogue
+de rer
+smart phone
+he len
+rich mond
+equ ity
+s land
+b g
+ne ar
+av i
+memph is
+we ir
+discu ssed
+bad ge
+p up
+mi stake
+phen omen
+un ite
+ðŁ Ľ
+de pic
+ri des
+in augu
+n at
+sof twitter
+comb ination
+gosp el
+âļ ¾
+ad mission
+retro gaming
+ðŁIJ ¾
+sch u
+mb o
+jun ction
+al arm
+à ¦
+gr ac
+kh ali
+k ul
+m ale
+cap tion
+wi sh
+te re
+cor ps
+ru bber
+play station
+er in
+effici ent
+l or
+jo kes
+in ary
+nor man
+lu is
+inaugu ral
+ch ed
+âļ½ ï¸ı
+di p
+to e
+str at
+aa c
+am u
+pi er
+co tt
+comm and
+tt en
+sn oo
+cu be
+clo ses
+class ical
+s word
+expre ssion
+reach ing
+n app
+co st
+affe ct
+ric o
+gi f
+brea the
+tri be
+or tho
+h ay
+l g
+fri es
+n m
+hi ding
+richar ds
+en de
+mic ro
+capit ol
+cop y
+ro m
+regi me
+mary land
+tax i
+di al
+embar ra
+un believ
+ch t
+v s
+elim in
+o dd
+pen ny
+sound track
+l ings
+trans ition
+rema ining
+a is
+mali k
+? !?
+rand om
+def end
+ul tra
+tru m
+danc er
+st ol
+dri ve
+a ver
+ro ast
+defin ition
+se an
+excit ement
+partic ul
+su rely
+sh av
+ber y
+di shes
+com m
+is ol
+i am
+ob li
+gho st
+hugh es
+chi efs
+b as
+conserv ative
+speci al
+fe min
+sh ri
+n ancy
+inte l
+tu ne
+ðŁĩ ª
+jo el
+gg le
+mo to
+ðŁĺ Ķ
+bu ck
+d ag
+antic ip
+mont ana
+gu id
+fro g
+ec raft
+op e
+dri ves
+nu mer
+x y
+color ful
+wednesday wisdom
+illu min
+bey on
+inau gur
+deep ly
+pre fer
+for tune
+coo ked
+ti ble
+âĺ ķ
+swe ater
+it ter
+tt y
+u i
+gi e
+com plic
+~ ~
+tax es
+cu ps
+di verse
+sam anth
+âłĢ âłĢ
+ba king
+sy mp
+wa i
+be half
+mer cur
+travel s
+ðŁİī ðŁİ
+or ia
+eng aged
+jump ing
+reti red
+n aked
+p uni
+speed way
+sci ences
+rehear sal
+on ym
+dy ou
+pl ates
+r ati
+kri sh
+jaz z
+car ol
+ra f
+pen alty
+tim eline
+ru by
+engine ers
+ra f
+bel le
+do se
+che on
+esc ap
+me g
+ran k
+or d
+me gan
+mer ch
+ec lipse
+âĺº ï¸ı
+ple dge
+kir k
+per si
+leice ster
+sa k
+w k
+saf ely
+yy y
+je t
+promis ed
+j c
+en ne
+no ah
+re no
+re a
+ðŁĺĤðŁĺĤ ðŁĺĤðŁĺĤ
+tra il
+ðŁij Ģ
+f d
+soo o
+ri min
+w k
+ภ²
+i al
+x ox
+bis cu
+d ale
+fan dom
+particip ating
+fla g
+privi lege
+pe ach
+mach ine
+bo ston
+gro ss
+o g
+mir acle
+adop tion
+u ss
+mon sters
+be ij
+clar ke
+pu shing
+pra ying
+ar o
+d n
+ell is
+apol lo
+od ds
+refuge e
+to w
+b p
+ðŁĩ¬ðŁĩ §
+h end
+app eared
+memb ership
+pe an
+du m
+viol ent
+v y
+potat oes
+aw w
+greet ings
+t ts
+ac on
+sh ane
+photograph ed
+cra b
+temper atures
+cu ba
+c fc
+wel com
+he l
+in nings
+m k
+co de
+kno ck
+gra ss
+swe dish
+p ta
+ick y
+v at
+lin ing
+s q
+sa p
+ar c
+announ cing
+sk ins
+cit yof
+br ing
+co x
+gam er
+it arian
+i da
+h d
+ros se
+sad ly
+ge o
+âļ ¡ï¸ı
+tag s
+fa ther
+chan ge
+l ance
+whis key
+adel aide
+te c
+stick ers
+marke t
+class y
+bad ass
+flo rence
+lin er
+fro st
+k ate
+ac on
+scand al
+es sex
+ðŁĺ ı
+vi vi
+dr ill
+blo ggers
+recomm end
+d ha
+ac res
+ro ma
+bu y
+gro cer
+er ia
+ma har
+ff er
+patter ns
+ver i
+com pu
+st ev
+ang a
+ment or
+do o
+it ali
+cdn poli
+on ly
+conduc t
+elec tro
+de f
+wh ale
+prepar ation
+bicy cle
+vi ral
+turn out
+bra ss
+qu ad
+hospit ality
+pack aging
+den cy
+ceme tery
+abo ard
+dre aming
+pic ture
+t all
+inv ent
+ad mi
+o e
+tem ps
+qu an
+fun dam
+pro mp
+resi dence
+mu d
+sour i
+âĦ ¢
+graff iti
+gi f
+d nd
+com p
+s war
+pe eps
+pale stine
+devil s
+san g
+assi stance
+bi ke
+missi ssi
+inter viewed
+ne phew
+dru ms
+v and
+gentle men
+n sw
+inst a
+leban on
+ee ee
+oli via
+ver y
+rou gh
+industri es
+m ation
+ðŁĺ Ĵ
+bar rel
+n ay
+po ps
+moder n
+ill y
+are st
+on ents
+protec ting
+v ans
+e o
+vi kings
+restaur ants
+re ck
+jac kie
+andre w
+w illing
+he ath
+citiz en
+disc rimin
+๠Ī
+stu art
+m ys
+hi p
+tran sp
+" ?
+te x
+su shi
+ke d
+cro ssed
+dist ur
+pe dia
+f ate
+some how
+mo th
+proce ssing
+is s
+r in
+u ts
+yy c
+ver t
+lg bt
+re id
+on to
+arab ia
+habit at
+= =
+stre ak
+simp son
+addic tion
+wim ble
+deli vers
+challeng ing
+ðŁİ ¶
+fran ch
+e du
+s me
+ai ds
+hur st
+th am
+tari an
+remem bered
+palestin ian
+fe es
+tru m
+sket ch
+ur u
+fit ting
+jes se
+ðŁĶ¥ ðŁĶ¥
+---- ----
+ba ch
+ici a
+colo red
+da h
+associ ate
+int el
+s eller
+p u
+stu ffed
+ac s
+b s
+sh in
+cooper ation
+certific ate
+ab u
+ingredi ents
+re v
+in ge
+el der
+christi an
+bun dle
+th ic
+dir t
+beij ing
+comm it
+ted dy
+ed u
+to day
+s field
+w yn
+confir ms
+lo o
+j v
+ene ss
+al pha
+vir us
+ari um
+gr ind
+bri dges
+introduc tion
+pol ls
+bac ter
+z ach
+termin al
+ra iders
+fla vor
+zom bie
+vo d
+sp reading
+gameof thrones
+effici ency
+lat ely
+ale m
+twee t
+cri mes
+cl er
+de y
+dg ed
+hy un
+pay ments
+cir cus
+ðŁĺŃ ðŁĺŃ
+mis souri
+lu b
+episo des
+c age
+po s
+mat ching
+tumb lr
+lin ed
+ge st
+am bi
+nar r
+ing ton
+regu l
+blo wn
+is le
+co co
+on don
+joshu a
+tour ing
+sm a
+sau sage
+best friend
+bo eing
+desi re
+sav age
+ra pper
+de vo
+te ar
+take over
+cow boys
+po ker
+par ag
+pp e
+h int
+we ars
+se th
+ro les
+l anc
+man ga
+form at
+fl yer
+c ay
+mo or
+ba ke
+spla sh
+v ad
+ker ala
+proce eds
+sil ly
+reflec tion
+di str
+wi d
+su it
+ci vic
+yan kees
+by n
+migr ation
+di stin
+or ch
+fe mini
+quali fying
+tu ri
+o be
+hun dred
+cra p
+wan g
+mathe mat
+bu re
+expo sure
+fergu son
+seme ster
+re serv
+pl ym
+a hu
+fac ial
+wa x
+wor ried
+ca b
+vi o
+as a
+co d
+to pics
+p cs
+hal o
+rescu ed
+horiz on
+ar k
+âļ ª
+hol ly
+el f
+ul ti
+pu p
+quali fied
+attend ance
+ati vely
+destro y
+y c
+for th
+photoo ftheday
+c ents
+ic eland
+meas ures
+de sk
+port folio
+artic les
+direc tors
+dat ab
+e w
+creep y
+oun ding
+hon oured
+mi st
+j it
+men tioned
+port able
+iti c
+d ann
+friday feeling
+am id
+ti ger
+scri p
+helicop ter
+hard ware
+expl or
+work place
+austri a
+beat les
+ber nar
+spi der
+disc o
+cul t
+lim its
+shor tly
+fin al
+nin ja
+lu ke
+le bron
+wal mart
+o il
+van illa
+shi re
+ye g
+ak y
+c s
+bl er
+collec ted
+t g
+rol led
+speci als
+b ff
+pier re
+sh im
+vi er
+flash back
+restor ation
+individu als
+pro d
+fre aking
+tu rer
+o a
+re fre
+mor oc
+gre et
+re yn
+care ful
+our ing
+u sh
+is d
+g ill
+vie w
+thunder storm
+b led
+pic nic
+guar di
+pi g
+ar k
+syl vania
+bann ed
+u cl
+vi jay
+ori um
+av engers
+believ es
+eu r
+monu ment
+concer ned
+la bs
+ber g
+a ap
+vi sh
+sing les
+can cel
+z el
+ar ab
+ru th
+too th
+ar ta
+sh af
+chair s
+r ack
+dise ases
+crow d
+cl y
+fle x
+christ ma
+artif icial
+tom at
+fin e
+dra ws
+advoc ate
+fran ce
+Ù Ĭ
+ðŁĺ ³
+heav y
+s our
+compre hen
+no ble
+aa p
+hin du
+cor al
+g ars
+ow en
+n l
+st all
+yel low
+mar ina
+in ver
+suppor t
+tou gh
+promis es
+pi e
+master piece
+sco re
+for ce
+mor tg
+crypto currency
+o x
+r ors
+rock in
+pro vin
+ho g
+no stal
+oak land
+pat rick
+inclu sion
+tra ffic
+ah med
+a ha
+lux ury
+con secu
+de mon
+âĸ º
+b lowing
+st ag
+: "
+encoura ge
+ben e
+sku ll
+do dge
+bu ster
+kin son
+wit ne
+er ror
+lo west
+fel low
+à °
+sh re
+bl ur
+vir gin
+compos er
+sli p
+mor nings
+ga ins
+tab le
+gra in
+ari st
+braz ilian
+w we
+tu es
+ribb on
+an ag
+di st
+sac rif
+em brace
+entreprene ur
+af fili
+de o
+t ali
+touri st
+fat al
+ì Ĭ
+autom atic
+ðŁĩ µ
+we ak
+wel fare
+confir m
+benjam in
+fi ghts
+alleg ed
+me ad
+strugg ling
+pro secu
+che f
+Ã ¨
+propos al
+er n
+ðŁĺ Ħ
+dy k
+on gs
+hon g
+m ack
+mel on
+on ent
+ru sh
+d ap
+tol er
+pro pag
+c ze
+trans lation
+wal let
+cott age
+sa il
+constitu tion
+ðŁĴ Ģ
+mun ici
+fav or
+storm hour
+i h
+ðŁĺ Į
+approach ing
+pin ned
+j ed
+niger ian
+n ach
+sh at
+particul arly
+mc don
+camer as
+anni e
+admini str
+he at
+electr ical
+char ming
+gib son
+bouti que
+ex posed
+ac tor
+pil low
+beach es
+genu ine
+margare t
+ben nett
+lou isi
+pos itions
+el y
+shin y
+ten tion
+architec t
+ren tal
+ac qui
+goo gle
+sub way
+mom ent
+ðŁļ ¨
+ri m
+metho ds
+cy cli
+nor folk
+Ù Ī
+over whel
+ra pid
+we ar
+happy birthday
+progre ssive
+ðŁĴ ¥
+co gn
+pap a
+f ool
+philosoph y
+pol ar
+jim my
+wi g
+ðŁĴ ĭ
+oper ating
+reduc tion
+ph i
+fla gs
+to the
+o di
+a res
+k oo
+k ang
+ar kansas
+ash ton
+wimble don
+sci fi
+attrac tive
+mississi ppi
+logi sts
+ral ph
+la bel
+gradu ates
+ma ha
+home town
+âľĮ ï¸ı
+foun ded
+on the
+li z
+trans l
+mini mum
+pre sti
+ta m
+gener ations
+re bel
+journ alists
+par am
+mc m
+acry lic
+death s
+tes la
+w t
+bry ant
+jer us
+i stanbul
+muham mad
+ri ley
+k ris
+work shops
+is o
+coun ts
+stre t
+prote cted
+trin ity
+man ual
+r hin
+r il
+pleas ant
+le mon
+ner d
+har der
+dar ren
+bur y
+ra h
+bas is
+mi gu
+occa sion
+li sts
+âĿ¤ï¸ıâĿ¤ï¸ı âĿ¤ï¸ı
+e b
+de cre
+hamp ton
+ìĿ ´
+tra vis
+trans form
+puer to
+nh l
+av oc
+tri ps
+unexpe cted
+ve t
+di dyou
+bar ber
+st ages
+m son
+re presented
+for t
+l al
+pp le
+nic ely
+ignor e
+qu il
+qu inn
+h k
+carri er
+remin ded
+am ong
+pass enger
+el len
+gue z
+sc ape
+mu ral
+youn gest
+ma sh
+d ill
+rout ine
+stain less
+jack son
+gand hi
+th al
+on ers
+edit orial
+convers ations
+sd ale
+autom ation
+i ke
+า à¸
+ðŁĩ ª
+hau l
+la ying
+men tions
+am en
+abor tion
+i bi
+coun ties
+ca therine
+man ds
+jam e
+roll er
+au t
+n am
+o logical
+cep tion
+ran king
+tox ic
+sn acks
+victor ian
+bang kok
+psycho logy
+re g
+ang ela
+respon d
+sty le
+sophi e
+dak ota
+achiev ed
+mar ked
+imper ial
+in as
+glo ves
+sli m
+confi dent
+att acked
+gg er
+lon ely
+valentine sday
+re b
+craft beer
+orig in
+zim bab
+ce iling
+te ens
+other wise
+w b
+f ers
+day sof
+advis or
+y ah
+âĻ ª
+en der
+republic ans
+av a
+skir t
+pi pel
+chi e
+jan e
+ja x
+ðŁĺ ĭ
+âľ Ĭ
+j ays
+bre tt
+bal o
+cru cial
+d har
+as is
+de au
+lloy d
+chat ting
+âĿĦ ï¸ı
+rel ay
+remark able
+n s
+we t
+bris bane
+ðŁĶ ´
+tion ally
+f k
+la yer
+house hold
+consecu tive
+es is
+pend ant
+st ir
+crit ic
+su gar
+photo shop
+pa res
+arti stic
+do dgers
+c un
+cra fted
+am end
+bo at
+âŃIJ ï¸ı
+egyp tian
+sa w
+tra ge
+small er
+ox y
+pa ired
+nex t
+i res
+tac o
+o y
+u c
+st i
+a erial
+: //
+dr o
+dot com
+gg ins
+r pg
+ay e
+le an
+stri ker
+lo bby
+prote sts
+pri ority
+congre ss
+am ate
+inv it
+r ington
+mom my
+th us
+allow ing
+pione er
+enfor cement
+g ori
+tal k
+dra g
+du mb
+bul let
+san ge
+er y
+tar gets
+ðŁĩ ¦
+he ather
+consi der
+seaf ood
+ve st
+ris ks
+% .
+p g
+sac red
+he ating
+kick ed
+tto t
+. -
+chan di
+co ven
+po ol
+pul se
+i a
+ro ster
+shakespe are
+es a
+car go
+pean ut
+tro op
+ac tion
+tab let
+home work
+cast le
+stru ction
+mus icians
+free zing
+bu tt
+justin bieber
+j j
+bah rain
+an them
+au dit
+didyou know
+na vig
+guid ance
+âĸ ¶
+tur f
+n un
+fic ations
+ye men
+char ging
+x c
+bron cos
+su bur
+p ale
+bor ing
+among st
+for the
+em per
+om fg
+p j
+expe cting
+ðŁĴ «
+st l
+ad min
+expect ations
+sw an
+shoo t
+oooo o
+min ent
+ãĢ IJ
+wall ace
+stan g
+satur day
+adop ted
+dou bles
+hom ie
+ome z
+d han
+vent ure
+surroun ding
+fi le
+mob ility
+de es
+w ski
+broo ke
+emb ro
+re members
+kar a
+test im
+bo tan
+m tv
+sacrif ice
+jerus alem
+d l
+Â ´
+proper ly
+ili on
+as i
+leg it
+co pe
+m cla
+recy cling
+lar ger
+ðŁĴ ĵ
+pat ric
+gener ous
+ja red
+p f
+mol ly
+thom as
+ju dges
+h b
+sor ts
+bl vd
+o ven
+enter ing
+plan es
+be et
+integr ation
+boo ked
+fre ed
+ver n
+ash es
+to pped
+de pot
+welcom ed
+ren a
+m ick
+d and
+see ks
+gam er
+ran kings
+ren e
+mu t
+whis ky
+fire fighters
+gu es
+ga ther
+tour ney
+de men
+y ang
+new ton
+autom otive
+back yard
+deta iled
+mi st
+to bac
+fi ber
+un usual
+grat itude
+sp are
+ne ys
+: *
+per i
+flo ating
+fin alist
+don ating
+dre ss
+bro ad
+be the
+econom ics
+tai wan
+ed wards
+plu g
+pra iri
+val en
+bab a
+f ad
+an as
+har per
+dis order
+app lied
+p att
+bi kin
+li ver
+cu ri
+carol ine
+ann er
+juli an
+wal king
+mal col
+screen shot
+co ding
+skin care
+activi sts
+myster ious
+ex act
+blo cking
+mercur y
+bat ter
+du mp
+âľ Į
+en se
+li sh
+ridic ulous
+prote sters
+ðŁĻ Ī
+lu st
+swe at
+as s
+ali ke
+co dy
+re ments
+win ds
+as pir
+vi enna
+pra y
+.. .@
+bo i
+cand le
+assi sts
+te e
+der son
+p ony
+f ence
+con spir
+âĺħ âĺħ
+oo th
+e pic
+ba rely
+a unt
+b am
+diamon ds
+end less
+scre ens
+can cer
+gr o
+p st
+pro spec
+mo sque
+help ful
+ou ri
+bro ther
+gu jar
+cri sti
+ine z
+to wers
+ad dresses
+gra y
+bur ton
+re tweeted
+ðŁ¤ Ķ
+n ity
+du ck
+super vis
+jo an
+kin der
+sanc tu
+pi ed
+âı °
+ł ï¸ı
+m ati
+reven ge
+ce ster
+eli fe
+desig ners
+back ed
+bo li
+wei ght
+cou ch
+su res
+s its
+shri mp
+la gos
+auth orities
+os ity
+hol ly
+compu ting
+fac tors
+ab e
+pan els
+ram ad
+sent ence
+missi on
+hol m
+r b
+d ads
+shang hai
+mon ey
+she ets
+sk ate
+thre w
+cup cakes
+infin ite
+l is
+practic ing
+ess ay
+ka i
+as ci
+mo b
+u gh
+hol mes
+re gg
+ik h
+mo ck
+collec tions
+pe p
+o va
+sal t
+nan dez
+co y
+thre ats
+tex ts
+cin nam
+pregn ancy
+pen ding
+stam p
+flow er
+g is
+agre ed
+pay ne
+ro ver
+ph ra
+sof t
+f fin
+fa thers
+pass engers
+aw ays
+al a
+h es
+li van
+in s
+samu el
+ingu i
+h of
+j j
+chen nai
+cat al
+om ic
+he ath
+ni ece
+pump ed
+integr ated
+are l
+no m
+produc tivity
+wan ting
+vis a
+di ana
+tw il
+it v
+cam ps
+ro wing
+d ley
+black and
+gu ards
+b ells
+re verse
+vi be
+ric ky
+mo ss
+ny t
+âĺ Ģï¸ı
+el le
+tro y
+cu dd
+ev an
+women s
+fo to
+mi stakes
+wick ed
+mi l
+c led
+me mes
+co smo
+schol ar
+ren o
+ðŁĺ Ģ
+v ents
+# â̦
+terrori sts
+ca sey
+cardin als
+ðŁĺĬ ðŁĺĬ
+venezu ela
+bol a
+liter acy
+t w
+en o
+con tains
+au stin
+fin anci
+ev an
+har vard
+origin ally
+chev ro
+her ald
+nott ingham
+manag ers
+âŀ ¡
+accep ting
+wal sh
+tutor ial
+entrepreneur ship
+yach t
+requi rements
+glen n
+pe de
+unfortun ately
+ach ing
+dais y
+gi an
+night mare
+âĿ Ĺ
+r ina
+b art
+ema ils
+oppo site
+who m
+sa ke
+pu zzle
+da shi
+par ty
+blan ket
+bus es
+lo re
+beau ty
+reas on
+pun jab
+winds or
+func tional
+exi sting
+hel lo
+gli mp
+con vin
+la k
+scre aming
+rebec ca
+bli ss
+north west
+infin ity
+cosme tics
+pul ling
+coffe e
+pl ing
+op ho
+colom bia
+interior design
+( +
+emo tions
+sa c
+sun glasses
+sav es
+d f
+six th
+al y
+ðŁĺ »
+de en
+dev ast
+polit icians
+lac rosse
+g u
+pe i
+jav a
+comb ine
+coal ition
+er ts
+survi v
+ch ad
+stri an
+n n
+de vi
+coun c
+concer n
+contro ller
+bre ast
+j ury
+tu m
+introduc es
+la di
+mobi le
+al z
+ste ady
+nur ses
+h acking
+on line
+oce an
+ðŁİ Ħ
+a am
+ju ven
+ic c
+louisi ana
+ar te
+street art
+is on
+wn s
+fr m
+p anda
+no ir
+main tain
+del ay
+symp toms
+thor n
+ge ome
+ter n
+carri ed
+p ru
+pan or
+as sy
+per u
+clou d
+sp ra
+pe di
+e ste
+tag ged
+ðŁĺ Ŀ
+shado ws
+naz i
+ا٠Ħ
+cor ri
+âĻ¥ âĻ¥
+j ad
+ðŁĩ «
+form al
+spo ken
+ðŁĮ ŀ
+enjo y
+lo pez
+out look
+in ho
+w ander
+Ù ħ
+ma ya
+pe e
+d ine
+ãĢ ij
+brief ing
+suppor ter
+ar ily
+ght ers
+natur ally
+doctor who
+j en
+v ar
+new year
+re se
+si mm
+re x
+con sequ
+tomat oes
+bur st
+bra vo
+bur gers
+cr acking
+nor theast
+bi om
+mush room
+mar que
+dou ble
+ni er
+v ag
+tw enty
+key board
+win ni
+jama ica
+par ish
+: -
+mental health
+ali zing
+ren der
+wa king
+ðŁİ Ĥ
+g ly
+na than
+wa shing
+mel issa
+jun g
+loy al
+chil i
+song writer
+guit arist
+bo wie
+neighb ors
+onym ous
+as set
+ta i
+head quarters
+ðŁĮ Ī
+i hear
+ci gare
+sur g
+) "
+re pl
+dar ling
+ðŁĻ Ħ
+z ak
+sa re
+ãħ ĭ
+mic key
+ware house
+mass age
+ine es
+did nt
+i w
+hur ts
+eng aging
+mag ic
+women in
+k itten
+mor s
+c art
+tit ans
+colle ague
+compe ting
+er an
+k hal
+mar ble
+dem and
+del ight
+et ary
+bli zz
+lou ise
+m ls
+fini shes
+experim ent
+conduc ted
+electr onics
+itt ers
+car ing
+wh ats
+sym bol
+jun g
+e cu
+pi x
+con text
+char ger
+ðŁĺ ĩ
+re ig
+fra g
+ë ĭ
+ch ad
+tru e
+ker ry
+def ending
+a int
+au ton
+check out
+bar nes
+less ly
+d t
+m me
+clou dy
+second ary
+are z
+_ :
+app a
+const ant
+" )
+ve ts
+jo b
+i ent
+ðŁĺŃðŁĺŃ ðŁĺŃ
+m j
+fren ch
+di ver
+davi es
+hh hh
+e book
+๠ī
+mar iti
+bree ze
+susp ended
+mat o
+vi et
+ra hu
+se i
+bol t
+en ary
+le is
+kar l
+fr amed
+expla ining
+ab c
+de aling
+nat o
+ja ke
+exp and
+leon ard
+establi shed
+du b
+ar men
+el led
+voc al
+nichol as
+ori ent
+k yo
+illustr ated
+ah h
+danc ers
+milli on
+ge ta
+po pp
+as u
+mur dered
+gi ble
+sto ked
+gri ffin
+maxi mum
+adri an
+en counter
+ther o
+david son
+ðŁį »
+holi day
+ev o
+asse ts
+car son
+memor able
+âļ ½
+ob am
+represent ative
+cb d
+tr icks
+vo gue
+vo ice
+mm mm
+sebasti an
+cli f
+ath y
+par alle
+ðŁ¤ ·
+pa k
+ev acu
+e ats
+ا Ø
+tou ched
+organ ised
+spir its
+can ad
+gui ded
+frame work
+ðŁĮ Ł
+pe d
+natur al
+ag ar
+replac ed
+anch or
+ti t
+sha h
+organ is
+super ior
+r n
+ch ro
+eric a
+st ill
+cor on
+chu ck
+loc ks
+or gan
+ro sen
+sc am
+ben ed
+/ #
+ke en
+tre vor
+vamp ire
+sor ted
+! '
+af ford
+in tro
+gr ace
+ðŁĺ ľ
+sau r
+kick starter
+influ en
+v u
+y up
+po c
+ðŁİ ¥
+a ar
+s ang
+tre k
+et sy
+tb h
+scre am
+chevro let
+pix el
+shepher d
+an or
+gabri el
+tw ood
+sd cc
+me ters
+develop ers
+clo sure
+v w
+twit ch
+ì Ĺ
+se oul
+pr ice
+ho g
+n ish
+hill ary
+scrat ch
+in cen
+wag on
+dis ability
+pan ther
+ch ats
+g d
+wit z
+sus sex
+l ate
+den mark
+ger ald
+cancel led
+net te
+i x
+nav al
+bap tist
+te t
+y ad
+ma th
+ho y
+r andy
+po int
+intel lec
+fru its
+w ool
+gu in
+pr on
+the ft
+con dem
+mar ry
+n ola
+architec ts
+cin cin
+roc kets
+gentle man
+ex plan
+t ate
+do e
+ra ises
+wild life
+w l
+insi der
+blan c
+w p
+for sale
+ny c
+po well
+unbeliev able
+pen s
+goo dies
+mu stang
+p ens
+st ays
+squ ash
+xox o
+near by
+ever ton
+co co
+le agu
+k han
+stu d
+south west
+con struc
+s worth
+cro atia
+le a
+su ms
+aim s
+e an
+van ess
+iti ous
+pa thy
+arc ade
+b end
+sugge sts
+sac ram
+roy als
+ri er
+em ir
+in cl
+an k
+clar k
+ri ght
+vac c
+ठ¾
+tan e
+li b
+u sc
+sal es
+hu h
+s ally
+ver a
+p ga
+gro ws
+dru m
+tre e
+eth ics
+sug gest
+is ab
+se aled
+pre viously
+anim ated
+ab du
+ri ses
+glo b
+pre dat
+scar f
+del ic
+om ar
+ll i
+sx sw
+py thon
+ne bra
+fun k
+reflec t
+pav ilion
+tic ally
+ch asing
+bak ery
+inva sion
+ko h
+believ ed
+co hen
+con qu
+cra fts
+nat i
+cle ver
+govern ance
+sam ples
+fa ils
+â Ķ
+ti mo
+r itu
+stri king
+inclu sive
+sho cking
+can t
+requi res
+dra wings
+ภŃ
+purch ased
+du m
+z ach
+war ner
+con sole
+man sion
+foun tain
+circu m
+e sh
+is land
+mil k
+pro fits
+hali fax
+ri val
+âľĪ ï¸ı
+jen ny
+sand ra
+ny e
+k elly
+y al
+qu ad
+no s
+inste in
+fin alists
+mid fielder
+cu e
+excep tional
+a an
+sa pp
+gett in
+sa a
+f ati
+sl ice
+vol k
+s wal
+la sting
+sum mary
+it as
+sm o
+s z
+âĺ Ĩ
+ip l
+fl ames
+ene ws
+ha v
+hoo die
+pitch er
+win dy
+re vol
+centr al
+ton ite
+ðŁİī ðŁİī
+sol ved
+mil wau
+organiz ations
+wee ts
+re fin
+s th
+ãĥ ¼
+el in
+ton a
+cinnam on
+ðŁİ ¨
+ðŁİ ģ
+ron aldo
+pen insu
+ome ga
+el ds
+desig ning
+e igh
+blu et
+ben z
+nu g
+ash a
+robo ts
+su dan
+choo sing
+en do
+ser ge
+clo sely
+hand y
+fing er
+be ing
+ar te
+survi ved
+fl ame
+mile stone
+gu t
+d war
+fu tures
+é e
+el o
+fri dge
+eli c
+ou ch
+u b
+p v
+tit an
+col lar
+st ation
+nev ada
+aur ora
+r d
+dun can
+âģ ł
+bri en
+mar sh
+Ð ¾
+to tal
+ch ry
+s ers
+su ffe
+ra chel
+colle ge
+to days
+cour ts
+ch it
+re united
+gym na
+gen esis
+be side
+re presentation
+ch ant
+collec tor
+ra k
+ath ens
+ni gh
+mun ich
+langu ages
+fl u
+particip ation
+__ _
+c v
+spec trum
+so da
+co ver
+refe ren
+ab bo
+ap a
+public ation
+ed m
+mon ica
+ar my
+ðŁļ Ģ
+div or
+dr y
+stre ams
+robo tics
+ci der
+bull ying
+appro val
+sto ke
+plat forms
+sier ra
+ex tin
+i b
+ha yes
+succe ed
+suff er
+at ically
+da i
+lyn ch
+h ound
+del ines
+ack now
+d ated
+exclu sively
+he res
+fac ilit
+dam aged
+char ter
+la kers
+fal con
+unve iled
+wel ove
+e ase
+pati ence
+l one
+gent le
+gene tic
+produc ing
+g our
+shann on
+bil ities
+zimbab we
+p int
+dau ghters
+liter ary
+bel le
+cl am
+surroun ded
+k any
+ne il
+pir ate
+rang er
+hb d
+nat alie
+bel ong
+olym pi
+emb assy
+sc ol
+en er
+ak in
+lo ren
+b h
+: /
+di va
+den im
+hi pp
+ðŁĩµ ðŁĩ
+arn old
+? '
+we ren
+em power
+dis abled
+man or
+rasp berry
+b af
+aw ful
+dru mmer
+kar dashi
+n ash
+machine learning
+ch u
+rebel s
+tim ing
+mon roe
+ton gue
+ran ge
+pup ils
+re ss
+amaz on
+b z
+har ley
+pal mer
+ballo on
+s ings
+ic ec
+j b
+c ers
+g ps
+whi st
+ri se
+l t
+oo oo
+c attle
+shoo ter
+vod ka
+uc l
+mt g
+le sli
+jon as
+di spo
+at ric
+ste in
+vintag e
+fir ms
+flo yd
+cow boy
+soo oo
+is aac
+war craft
+disney land
+beauti ful
+be am
+franch ise
+bu n
+k ag
+an on
+tur bo
+swee p
+made in
+kar achi
+dete ctive
+penn sylvania
+contro versi
+vitam in
+a side
+chron ic
+descri bes
+remo val
+ha h
+ap er
+ten ed
+u to
+bad ly
+mir ac
+f ry
+ye a
+in jec
+ther mal
+comp act
+th or
+te ed
+ur gent
+l ite
+g illi
+sop hom
+ic o
+che m
+p m
+for k
+fre ak
+ch ak
+recipi ent
+i y
+ni k
+model ing
+c ans
+ðŁı Ģ
+del ux
+se am
+surviv ors
+rad ical
+investig ating
+reli able
+f m
+tur t
+ligh thouse
+to ol
+go wn
+) )
+bo ts
+auto graph
+a id
+bu ffe
+h mm
+horri ble
+ssi onal
+ann i
+๠Ģ
+k its
+sch i
+eter nal
+hu ss
+sens itive
+r u
+tast es
+chec ks
+im o
+por tion
+sk ate
+e den
+half time
+fri ed
+ri hanna
+ti se
+fl ick
+ca in
+s gt
+âľ Ķ
+sh au
+sta ined
+ra ffle
+dro ve
+sal man
+princi ples
+sh o
+ar u
+je ss
+gu ine
+gar bage
+my an
+jel ly
+dis ru
+z ia
+q ld
+ent ries
+la v
+fle w
+ad mit
+objec ts
+comp are
+ny times
+cann es
+p n
+suff ol
+ro c
+d ana
+e gg
+hi st
+coun sel
+' !
+phy si
+imag ination
+ad just
+explo sion
+plym outh
+hor ror
+elli ott
+bour ne
+de x
+bre ed
+au dio
+lob ster
+disappo inted
+nation wide
+( (
+incre ases
+austr ali
+ce dar
+star ing
+rac ial
+e is
+g mt
+visi ons
+stay ed
+discu ssions
+de an
+cur tis
+mai den
+stel lar
+happ iest
+h wy
+pre season
+car av
+mon days
+hospit als
+glimp se
+schol ars
+ja i
+ter race
+ann a
+goo se
+gra ded
+lot us
+hun g
+grocer y
+stam ps
+emper or
+sc oop
+in ser
+c as
+exist ence
+he al
+fal cons
+mar vel
+reduc ing
+terri fic
+magne tic
+perfor ms
+bar re
+p us
+tre ating
+ic on
+w h
+decla red
+tra uma
+do d
+come dian
+nik on
+bu gs
+as m
+mont gom
+ibi za
+comprehen sive
+ha s
+san ti
+fellow ship
+da sh
+p sal
+louis ville
+sp y
+fau lt
+d the
+fi led
+vi sta
+de sc
+fe ars
+you tu
+sp s
+es p
+ri g
+cri me
+ber ger
+wonder land
+k ent
+in formed
+stev ens
+my th
+ast on
+ir i
+visit or
+at ri
+produc ers
+al la
+person ally
+separ ate
+agen cies
+af ri
+il an
+spo ke
+n ina
+squ ad
+di ves
+de pend
+li v
+fier ce
+enter taining
+cha in
+sc at
+bor ders
+pal ette
+sp ro
+os is
+der by
+tobac co
+zi o
+willi e
+ju vent
+zoo m
+hol y
+enti rely
+af e
+mart inez
+be ds
+pe a
+bull dogs
+ðŁĩª ðŁĩ
+ib m
+ne on
+ethiop ia
+team mates
+plan ting
+tw er
+any time
+for bes
+ó n
+run way
+ner vous
+ro ger
+p ile
+ch anc
+apo caly
+u w
+o i
+dr ought
+territ ory
+br ick
+cre atures
+go in
+w aff
+gre n
+sou theast
+je an
+am bul
+ed ited
+stra p
+c v
+aar on
+ãĥ» ãĥ»
+t su
+descri ption
+kin dly
+clu tch
+im mer
+en or
+women sday
+or ange
+ra g
+ob vious
+hy der
+chann els
+man go
+me yer
+ra ining
+ge tty
+pil gri
+coordin ator
+up load
+ninten do
+don uts
+san chez
+app arel
+j r
+zz i
+, @
+jeff erson
+accessi ble
+great ly
+e id
+initi al
+budd ha
+par is
+ma scot
+â¬ĩ ï¸ı
+sch war
+si ri
+sp inning
+mortg age
+e cho
+end ange
+ge dly
+chlo e
+enh ance
+kar nat
+k ry
+explo res
+ðŁĴ ģ
+af fair
+ic als
+all a
+dar t
+dolph ins
+diffe rences
+squir rel
+au gh
+dr ones
+ell en
+re store
+pa w
+un for
+pi ke
+hil ton
+colla b
+consu mers
+co inci
+out comes
+pp p
+a q
+coup on
+li est
+si ms
+k ho
+av es
+spo on
+pu dding
+cor byn
+hat ers
+ex ams
+sla ve
+. !
+p sa
+app les
+tam il
+se d
+co ke
+zz o
+lo sange
+car bon
+cla ir
+... )
+k hu
+cra ig
+explor ation
+sanctu ary
+su e
+al way
+demen tia
+won ders
+super hero
+pakistan i
+brown s
+bluet ooth
+lo cker
+mar c
+ev entu
+delux e
+rodri guez
+âĿ¤ âĿ¤
+ro bb
+ðŁĴ ¦
+lin ux
+ten s
+intellig ent
+se ed
+vo ter
+s ler
+pe aks
+inter n
+teen age
+peninsu la
+hand ling
+ti e
+cou sins
+wen dy
+me e
+à¹Ģ à¸
+din o
+ðŁĴ °
+ðŁĺ ĥ
+ze e
+s bury
+trage dy
+b k
+bo re
+z in
+war ns
+idi ot
+tou ching
+contin ental
+tac os
+saf ari
+wa shed
+po dium
+morri son
+fore sts
+c bc
+al on
+partic ular
+be ads
+inv ented
+lo ch
+li ghter
+where ver
+i de
+docu ments
+a we
+k r
+no where
+min er
+st it
+ro x
+contribu te
+har dy
+cl an
+ob ject
+ca it
+ðŁĴķ ðŁĴķ
+happ ier
+vege tables
+t art
+g ag
+nom inee
+heav ily
+pan ic
+j d
+there sa
+at m
+u ph
+s fc
+su ri
+drin k
+n al
+re vel
+k l
+avoc ado
+nom ination
+ma donna
+shar on
+malcol m
+control led
+sh ers
+revi val
+legis lation
+shoo ts
+n in
+comm entary
+pro s
+human rights
+str anger
+mit ch
+pipel ine
+leg ally
+th u
+gil bert
+tol l
+gran ted
+gh s
+ir anian
+refre shing
+du k
+ab i
+pri me
+jose ph
+mo sa
+stati stics
+produc tions
+mer ry
+pat el
+sa x
+human itarian
+struc tures
+e missions
+town s
+fre el
+ster ing
+rat ings
+alle gedly
+cab in
+st l
+w ade
+fl yers
+tri m
+promis ing
+z u
+bal lot
+compar ison
+free ze
+ou ter
+great ness
+as sign
+snow y
+r ale
+tor ies
+med iter
+kno ck
+consult ant
+cincin nati
+analy st
+sc oo
+je ws
+appro xim
+pu re
+portra its
+cy rus
+ation al
+lo ans
+acqu is
+el u
+accep table
+uni on
+water color
+ru st
+batt les
+per fu
+seas onal
+ser ial
+mind set
+ri ot
+fel d
+enni al
+clo set
+pri est
+tan ks
+int l
+scre w
+bu m
+ab dul
+ou x
+expla ined
+ric a
+imag ing
+law yers
+bu ried
+ãĥ»ãĥ» ãĥ»
+ear l
+âĢ ķ
+l ton
+resto red
+stri pes
+fo ss
+de mands
+ste aling
+alex is
+mun d
+ak er
+ur us
+war dro
+hu gs
+gen re
+e go
+Ù Ħ
+particip ated
+bab es
+ban quet
+ti ous
+he mi
+ds b
+lo st
+milwau kee
+jen ner
+ge m
+ou tra
+lo ses
+id i
+re ps
+ðŁİ §
+regu lation
+fla w
+f ang
+vibr ant
+ram p
+ra ins
+well being
+so viet
+vie wers
+de po
+libr aries
+bi go
+ser y
+g ill
+de struction
+co z
+c x
+bri dal
+al ds
+plan ted
+amate ur
+lu d
+che ering
+show cas
+pro file
+i u
+ver tical
+pack ers
+wiz ard
+ski p
+s light
+be au
+air ways
+mu ch
+re ra
+ðŁĮ Ĭ
+ab sor
+pati o
+pack ages
+s ells
+ment ally
+ðŁĺ ¢
+reyn olds
+k are
+tri bun
+wal t
+kn it
+ta ste
+sur rey
+boun ce
+cre ature
+b are
+bet ting
+su re
+mi ley
+laugh s
+al ore
+cy n
+t l
+arti st
+ann ah
+war mer
+dynam ics
+lunch time
+mariti me
+vulner able
+ðŁĴ ĥ
+wol ver
+dur ham
+const antly
+am in
+si bl
+: @
+bul let
+k ach
+angel o
+wil der
+doo m
+desk top
+law suit
+k ca
+hen derson
+inv iting
+bet ty
+ta wards
+ra fa
+le aked
+and i
+ge ms
+af l
+vel o
+mediter ran
+pro be
+to tten
+steph anie
+sn ation
+com be
+q s
+over come
+assas sin
+ra v
+fil ip
+winni peg
+sh il
+determin ed
+k as
+ou tre
+regre t
+gui des
+aa a
+ðŁĺ Ī
+wi ves
+mani fe
+er ly
+sm y
+sh ima
+x ing
+pix el
+jac ob
+ac commod
+to y
+on o
+po o
+ti er
+an swe
+ðŁĴ ģ
+ro sa
+le ase
+bel ongs
+th ar
+eventu ally
+nei ther
+go a
+ski ing
+at ra
+ag h
+broad casting
+f ury
+py ram
+d ice
+volk swag
+wom ens
+provi der
+bom bs
+miss ile
+whi p
+d ick
+nor we
+back up
+el der
+mat ure
+concer ts
+gi ous
+sque e
+good morning
+bra ves
+^ _
+au ssie
+lun a
+mal es
+he ck
+for tn
+rome o
+steel ers
+p n
+pe er
+re presents
+Â «
+kat y
+migu el
+requ ire
+cha ins
+l ur
+immedi ate
+ti mber
+âĸ¶ ï¸ı
+advoc acy
+ex port
+an z
+tiff any
+auth or
+ðŁİ Ī
+du des
+chil ly
+hi d
+har m
+bu g
+mon ster
+terri er
+tu c
+story telling
+ta k
+in ti
+immigr ants
+b is
+reach es
+com passion
+john ny
+contribu tions
+ðŁIJ ¶
+mechan ical
+impre ssion
+ran ks
+ko be
+men ting
+bloss om
+pab lo
+buil der
+bom bing
+tw el
+sul livan
+om o
+pe te
+de mi
+ku dos
+w bb
+t gif
+mass ach
+neighb or
+che fs
+eng ines
+pun e
+ga ined
+phan tom
+s days
+ext end
+gr an
+cent ers
+jac qu
+dat asci
+sleep y
+el vis
+answe red
+s lot
+con y
+flexi ble
+ti ally
+le tics
+% ,
+andre ws
+si ble
+mom ma
+vin o
+do x
+invit ational
+twil ight
+j ade
+ill ery
+joh ns
+f ou
+p v
+-- ->
+break down
+billi on
+prin ter
+mon d
+c bc
+mag gie
+legi on
+du b
+kur t
+po or
+paren ting
+regi ons
+bikin i
+be ware
+si onal
+au burn
+kid ding
+amp les
+sp an
+con tempor
+c ic
+ha bits
+ak o
+pre fe
+bud dies
+it z
+em ily
+person nel
+moun tain
+ver sus
+ðŁĺ ¬
+ear ning
+s ink
+dar i
+u u
+s win
+i ster
+bru tal
+n ac
+kat a
+clo th
+am and
+ðŁĶ Ĺ
+ne o
+alu min
+week ends
+nebra ska
+co des
+delay ed
+brun o
+pro ven
+in c
+i ght
+fl an
+or o
+lam bert
+regu lat
+w f
+massach use
+kardashi an
+bern ard
+fi esta
+volcan o
+grand pa
+anc a
+d re
+st itu
+mean ing
+fo am
+au ck
+at ed
+r l
+hot el
+pers ons
+dy nasty
+ell or
+ma i
+am ne
+sty ling
+avi er
+e g
+vege tarian
+, â̦
+foun ders
+sta in
+g d
+cy cles
+sky line
+trac tor
+exi sts
+tra l
+kid ney
+mar il
+inst ag
+se tte
+addic t
+tri angle
+flash back
+controversi al
+z on
+p ins
+i as
+tr ay
+town ship
+deleg ates
+sp am
+h ms
+cr ane
+peop les
+o lo
+fac tion
+but es
+on ica
+deleg ation
+new profile
+eli er
+mc a
+w and
+g ely
+losange les
+ber ke
+ti ve
+dis rup
+zz a
+cas a
+jor dan
+ford shire
+ga thered
+ic hi
+atten dees
+à¸Ń à¸
+pe ppers
+co in
+bour bon
+ern ity
+ro tary
+behavi our
+jere my
+team work
+compli ance
+tre mend
+ðŁĩ §
+bu hari
+cam bo
+bu yers
+ha gen
+bu ds
+bay ern
+mon te
+sm ells
+an za
+ath lon
+descri bed
+work force
+gi ving
+ap i
+invest ments
+da il
+sel ena
+datab ase
+th um
+mor tal
+stu dent
+bu yer
+do ver
+gar ten
+att le
+loy alty
+gen oci
+holo cau
+theat ers
+ru ling
+ven us
+pat ent
+ch un
+ab by
+awa ke
+mass acre
+bang alore
+break ing
+simm ons
+ju sti
+hal e
+ed chat
+gg les
+haw k
+mar king
+head lines
+stro m
+co ve
+breath taking
+med als
+hair cut
+christ ine
+tele graph
+gujar at
+ju ra
+can e
+sho re
+propag anda
+mu eller
+.... ....
+sa vi
+stom ach
+thro ws
+ta b
+war m
+j ong
+reno wned
+hi r
+ra is
+mush rooms
+guaran teed
+bo a
+m j
+revolu tionary
+certi fication
+bru ins
+jo in
+w es
+pas sport
+c g
+sex u
+cap able
+w v
+ton es
+jac kets
+ac compan
+spin ach
+fore ver
+bla ir
+wat ts
+g l
+cou ples
+prairi e
+newprofile pic
+logi stics
+massachuse tts
+jagu ar
+o id
+we al
+under water
+mo z
+y i
+ma ths
+myan mar
+pre ps
+suffe red
+tr ace
+wal i
+ah hh
+bor g
+st itch
+cu lin
+real ise
+infe ction
+discrimin ation
+sh ame
+an kle
+hu mid
+y t
+brac ket
+tru ck
+tri u
+ea ster
+commun ity
+post card
+invol ving
+ty ler
+car amel
+over view
+ex amples
+integr ity
+base ment
+instru ments
+ani um
+at us
+gh er
+laun dry
+achi eve
+gen eva
+pr icing
+hyder abad
+beli ef
+me ta
+j aw
+accoun ting
+lead er
+cristi ano
+cou ture
+cy p
+vis ed
+, ,,
+k nu
+h ick
+break er
+br am
+ra b
+mo or
+ham as
+gradu ating
+pupp ies
+ak h
+ta h
+ach es
+ri e
+op ini
+g ta
+re ign
+tra gic
+re ver
+p ill
+pine apple
+tou ches
+da re
+le ys
+il o
+inter iors
+sc outs
+bar t
+en zie
+don o
+bro ck
+christi ans
+ense mble
+Â ·
+cine mas
+new port
+air line
+win ston
+le igh
+cont ents
+pre scri
+ur ge
+tr out
+fic ally
+il ia
+sub si
+are r
+âļ¾ ï¸ı
+w ounded
+ðŁĻ Ĥ
+pe pper
+ðŁĴ ŀ
+fit ted
+af f
+re sur
+thursday thoughts
+z ero
+archae ology
+di v
+je e
+i on
+awa iting
+co zy
+beauti es
+bal d
+dat a
+gri zz
+stal k
+kin ds
+cle ared
+jess ic
+regu lar
+ali ens
+plac e
+bo s
+bi zar
+thisi s
+ðŁĴ Ģ
+totten ham
+ma fia
+s lam
+ari ana
+car roll
+back pack
+care y
+uni v
+r g
+pe p
+dig it
+tatt oos
+ag on
+volunte ering
+diffe ren
+consu mption
+ka thr
+head phones
+t shirt
+o b
+ele ment
+re tail
+sh ru
+al gori
+contain er
+consci ous
+fi l
+com ing
+ra sh
+u rope
+def ine
+gi or
+femini st
+flow ing
+rout es
+gl aci
+fer t
+somer set
+ant es
+twee ps
+$ $
+h our
+endange red
+year sof
+ro h
+po pped
+bac king
+ba sil
+bra ke
+mon aco
+lgbt q
+pra gue
+ut ility
+cas si
+gate way
+haun ted
+sch ul
+ðŁİ µ
+shou ld
+walking dead
+comple ting
+dann y
+montgom ery
+pengu in
+ss i
+mer chandi
+ðŁij ij
+chur ch
+h ates
+cap tain
+brea thing
+ce t
+fair ly
+approach es
+compan ion
+surpri sing
+kany e
+pe y
+hin di
+targe ted
+lor ds
+de ut
+di gging
+ger man
+ru t
+ener gy
+close st
+y un
+apo logi
+ภ±
+s ack
+ru p
+dd y
+port al
+d ough
+b ats
+ðŁĵ °
+at ur
+graph er
+pi res
+mo tors
+ðŁĮ ¹
+j c
+dan g
+tu k
+clu e
+us c
+pag e
+d less
+bro ws
+ju s
+ad ing
+re marks
+oo m
+car dio
+ste fan
+arm strong
+âĢ¢ âĢ¢
+ni est
+belgi an
+bi op
+so y
+lo f
+í ĥ
+q t
+flashback friday
+ce e
+ģ à¸
+wre ck
+mar ines
+amend ment
+wardro be
+vo y
+bur ned
+guit ars
+ra inf
+li fel
+ssi l
+oun ce
+exter nal
+c key
+me sh
+she ikh
+inv itation
+sugge sti
+pop corn
+phenomen al
+an onymous
+tun a
+chic ago
+o val
+del y
+loc als
+( &
+pro f
+no vel
+fin der
+spar ks
+la ven
+in fu
+nic ks
+qu ant
+ra e
+exe c
+dist ingui
+st ances
+mu tual
+sh al
+unve ils
+edmon ton
+zan ia
+a dio
+vie wer
+brad ford
+audit orium
+qu is
+re act
+htt p
+l ero
+chee ky
+impac ts
+ta k
+ed t
+desper ate
+t ay
+ì Ħ
+sett le
+bar gain
+resu me
+un ite
+thro wn
+ke st
+se ys
+mar ching
+am it
+decl ine
+sch ar
+me tr
+stan ford
+lin ke
+ber ra
+dol ls
+rug by
+jam i
+b or
+road trip
+dino saur
+mi k
+sun der
+re m
+b k
+over seas
+nau ghty
+imple mentation
+iam srk
+lun cheon
+fir ing
+mi ami
+pere z
+the e
+z on
+gi fted
+con version
+ceram ic
+¡ ï¸ı
+pe dro
+ì Ĩ
+v ick
+! @
+he ed
+si d
+b w
+docu ment
+pl un
+gr ants
+fant asy
+predic tions
+vali d
+car ved
+gradu ated
+ðŁijį ðŁı»
+nation ally
+ch y
+af l
+re sso
+blan k
+ri vals
+j ig
+e ties
+om ics
+une mp
+b ound
+sk o
+inspec tion
+par al
+high s
+cri sp
+b ans
+ob a
+[ @
+co spla
+costu mes
+rec all
+mou th
+ni gel
+b ts
+ter a
+ko v
+do cs
+west minster
+dic t
+gra vity
+kar i
+ro gue
+t ted
+war k
+ida ho
+w end
+aw i
+queen sland
+proce sses
+cli ffe
+m ick
+com pens
+op ol
+the y
+cl ari
+wiki pedia
+salman khan
+haz ard
+pre ston
+swee test
+pd f
+che es
+tr ilo
+south africa
+bur nt
+( $
+con tain
+t p
+sub mitted
+sound cloud
+at u
+re z
+word press
+corru pt
+n f
+ma ker
+í ķ
+par as
+adv ent
+ri al
+ca fe
+fo ssil
+!!!! !!!
+co ws
+c j
+sp ur
+institu tions
+land mark
+ent it
+re ut
+h is
+alz heim
+we mb
+regg ae
+mo squ
+st at
+identi fied
+deal er
+re am
+re land
+ten sion
+ðŁĩ ©
+wra pping
+deep er
+fr at
+red dit
+ar is
+moroc co
+.. "
+b low
+ma pping
+pri orities
+ing a
+swa p
+re wards
+conspir acy
+creati ve
+c j
+congre ssional
+vau lt
+ple x
+sophom ore
+shad ow
+ele ss
+ðŁĺ ħ
+dar ts
+aldu b
+anno ying
+pro ps
+n as
+alumin um
+h bo
+offen se
+j ill
+oni ons
+la ur
+ta e
+har dest
+sh ro
+ga ining
+meas ure
+ed tech
+cyp rus
+tar a
+ang eli
+car lo
+go on
+all i
+im plic
+ju pit
+resil ience
+ha il
+bal anced
+) ...
+joy ce
+gr a
+th eli
+defin ed
+shi pped
+main ly
+min a
+l m
+sac ri
+o ber
+p im
+claim ing
+ent ers
+co rey
+bo k
+cri ed
+cool ing
+dani elle
+pharmac y
+thor ough
+ca ke
+k lo
+outre ach
+z ens
+digital marketing
+val ent
+sn p
+her b
+mr w
+caf é
+cap tures
+no tre
+triu mph
+pan cakes
+cu mber
+spi ke
+d ation
+bi gg
+sp er
+crit ical
+am al
+too th
+foun ding
+a stro
+' #
+quan tum
+th ames
+un c
+pri de
+air bus
+kno cked
+un defeated
+mediterran ean
+cal cu
+clo wn
+sens or
+ham mer
+for give
+cu shi
+ber ry
+maje stic
+elec t
+polit an
+g ta
+k ari
+bur ke
+sea hawks
+volkswag en
+re i
+landsc apes
+cas u
+grand father
+list ened
+/ /
+star trek
+rainf all
+fur ry
+vi er
+star k
+rif le
+ff a
+leg es
+hillary clinton
+min us
+correc tly
+architec tural
+pre ce
+up side
+box er
+ðŁĻĮ ðŁı¼
+is ai
+de t
+pro vo
+tis sue
+spoo ky
+ve led
+re con
+prospec ts
+que bec
+âļ «
+ig no
+anat omy
+shap es
+w p
+p interest
+hor e
+an es
+pick up
+ti p
+pra desh
+hu gh
+co e
+po k
+gram my
+well ington
+sti gate
+ri gh
+lea p
+king ston
+scen ic
+go sh
+v ani
+au g
+s ary
+zi er
+bure au
+lin son
+con te
+fra gr
+all an
+g aw
+lan a
+colli sion
+surve ill
+ren ais
+ar range
+s ali
+do in
+br ance
+bren dan
+our se
+in coming
+suspen sion
+à ´
+l la
+educ ators
+in tri
+da e
+bio graphy
+bul gar
+villa in
+go thic
+rw anda
+e w
+may or
+meet up
+democr at
+mor gan
+su dden
+te sco
+car rot
+bom ber
+mck in
+re ne
+fun day
+agricul tural
+haha h
+show time
+form ing
+col a
+scor pi
+quo te
+po ppy
+s life
+d az
+tu b
+ne n
+mo t
+ðŁĺ »
+s ore
+elder ly
+o ve
+skin ny
+um i
+anc o
+man ship
+we re
+g v
+k ah
+fol ding
+ne at
+samanth a
+dan ish
+uk rain
+humid ity
+nu tri
+jak arta
+cand les
+oooo oooo
+at ile
+streng th
+i bra
+bap ti
+charle ston
+fr ames
+girl s
+clear ing
+glu ten
+# #
+super natural
+ju bi
+ph one
+he in
+dr un
+le ak
+invest or
+y er
+dom ain
+ball room
+mi sh
+app li
+off shore
+bla ze
+dor o
+âĺķ ï¸ı
+win ery
+shar if
+ad ore
+n ir
+saf er
+si gh
+as cri
+strong ly
+trac y
+ck er
+ol l
+faith ful
+ey ed
+deli ghtful
+vis m
+karnat aka
+tit an
+wh ar
+jer seys
+re fur
+heav en
+gri p
+pan ama
+pre li
+glu ten
+o dd
+cont ent
+pon ti
+tion ing
+e commerce
+feder ation
+flaw less
+ge ar
+ti res
+by r
+pol ice
+cu ban
+tri butes
+tic ul
+chur ches
+nur sery
+di aries
+muse ums
+snapp ed
+i van
+wi ght
+touri sts
+ramad an
+t rent
+prophe t
+won dered
+focu sing
+hi d
+ic ons
+i q
+ambul ance
+pi st
+fun niest
+time less
+sr ilan
+bu ys
+ki ds
+colour ful
+a shi
+ch ir
+mu m
+ðŁĵ ļ
+let ter
+x en
+reut ers
+pre serve
+in ting
+ste p
+fu ji
+uni ver
+i u
+show down
+po ems
+surveill ance
+suspec ted
+ta e
+sol ving
+tom b
+mother sday
+car pen
+recru it
+pil ots
+bro c
+mix ing
+fri days
+ty r
+represent atives
+tra pped
+abdu l
+free style
+clu ster
+âļ łï¸ı
+k d
+sk ill
+pit t
+ex o
+commer ci
+muse um
+loc ally
+g ina
+no bel
+immun e
+fr ac
+cap su
+main ed
+attemp ts
+bull dog
+be spoke
+sing ers
+sp elling
+seg ment
+nat ures
+tic k
+lip stick
+clean er
+gett able
+preci sion
+â̼ ï¸ı
+th ood
+re ef
+no pe
+bill y
+di gi
+mu si
+ri val
+figu red
+tal ity
+sun ny
+ber k
+aw ww
+awa its
+un real
+co pen
+asy lum
+ex otic
+bu en
+mo ck
+en able
+arch y
+fr a
+pla stic
+al mond
+amp li
+displa ys
+abbo tt
+s me
+x p
+ðŁĻ ĥ
+graph ic
+i ved
+mar a
+cau tion
+lea ks
+en berg
+ul u
+unic orn
+cann on
+appren tic
+ðŁĺĺ ðŁĺĺ
+b ball
+wil low
+at ics
+am as
+manufac turer
+campaig ns
+port ers
+flo ors
+l su
+ty pe
+ke j
+honor ary
+it im
+to le
+min ecraft
+d x
+ma sh
+ri o
+consequ ences
+ron ald
+go ssi
+suffol k
+mu se
+r bi
+live music
+i van
+ðŁİ ¤
+le u
+patri ot
+man it
+lan ca
+home decor
+de ar
+sig ma
+ti de
+str ings
+v ita
+sequ el
+try na
+inve stigate
+bor is
+ve gan
+barri er
+mind fulness
+web b
+hu stle
+in da
+tan zania
+str ay
+tex as
+c ag
+diagno sis
+wom an
+g w
+ob session
+l ative
+nu fc
+fl ynn
+moment um
+sof a
+wal d
+vege table
+tu cker
+supp er
+se ab
+ar ro
+se ag
+ven ting
+counc ill
+sp lat
+cal cul
+.. #
+com fy
+odi sha
+sto pp
+war fare
+ca es
+à ¨
+co y
+price less
+in sec
+ðŁĺ Ľ
+contro ls
+empower ment
+datasci ence
+per pe
+gen ic
+e res
+tru deau
+man o
+sla very
+expand ing
+ma he
+fa iling
+s aga
+photograph s
+cre st
+re on
+surf ing
+hi e
+ðŁį Ģ
+ja e
+fel lows
+south ampton
+sol om
+ce ster
+tab ility
+hor n
+se ct
+he e
+cole man
+at las
+explo rer
+consul tation
+copy right
+organi zing
+den ied
+mon keys
+noo dles
+br is
+fl or
+dou gh
+bon ds
+sho cked
+eco system
+care fully
+w m
+apart ments
+cur ve
+san diego
+must ard
+comm en
+cere mon
+e ch
+ru th
+ðŁĻĮ ðŁı»
+hawa i
+fil med
+te ar
+as ingly
+ca ir
+wat t
+instru ment
+ou tta
+ye ol
+river side
+ë °
+. :
+nor wich
+alo g
+migr ants
+new man
+ri de
+spr ink
+targe ting
+beli eve
+tor ch
+reflec ts
+per mission
+ff man
+ene mies
+bas ics
+se ized
+sun days
+le i
+hass an
+en do
+h c
+st ad
+le ments
+kk kk
+nan o
+shar k
+man a
+on ic
+treat ments
+ear ly
+collabor ative
+shu ttle
+bran ches
+mis ses
+mained cm
+ap ers
+ky le
+carri e
+leis ure
+sh et
+bir ding
+adv ances
+ðŁĵ Ŀ
+popu lar
+di ane
+a be
+re war
+neigh bour
+k pop
+remem brance
+play ground
+ru b
+krish na
+e bola
+inqu iry
+ep a
+lu min
+organ isation
+abra ham
+norm ally
+pre ten
+jan et
+w t
+ðŁĴ İ
+encoura ging
+a stic
+bu mp
+syd ney
+s z
+ss ss
+gar rett
+ðŁĵ »
+consul ting
+roman ia
+spo tting
+chanc ellor
+ar ma
+presti gious
+ðĿ IJ
+t ad
+cry st
+compe tit
+rati o
+cat aly
+bro w
+j ur
+vi king
+commu te
+y day
+la yers
+du mb
+esc al
+genoci de
+f ill
+gu pta
+ste pping
+se i
+fo to
+wild cats
+col i
+projec t
+ear nings
+st r
+ge ons
+comple tion
+b m
+decor ated
+craw ford
+af ghan
+sc are
+visi bility
+hi b
+direc tion
+stro ll
+christ ina
+alter nate
+cl are
+sty list
+be hold
+s ance
+leop ard
+acqui red
+narr ative
+ash i
+the a
+?? ??
+pe as
+at ch
+sli des
+le en
+renew able
+eng lish
+qu ir
+co aster
+r x
+fo ols
+match day
+mis m
+amaz ing
+z ig
+ke ting
+won t
+to wel
+di ab
+sta ke
+n m
+mel t
+e than
+gra pe
+polit ician
+sm en
+í ĺ
+re o
+wedd ings
+cat cher
+or acle
+me mo
+ðŁĮ ´
+ec k
+rob bie
+norwe gian
+oper ator
+am or
+se wing
+ju l
+x ie
+u v
+fif ty
+me ga
+tatt oo
+liber als
+u pri
+traffic king
+richard son
+su v
+ki p
+mess y
+tremend ous
+gl ou
+cour tney
+la d
+stere o
+my ers
+i dio
+^_ ^
+man ning
+dy e
+w d
+thr one
+jun k
+as u
+provin cial
+k ook
+wr c
+fine art
+hamp shire
+renais sance
+b red
+fall out
+s j
+sn l
+al am
+tor ture
+fy i
+sh ines
+pa w
+ch ar
+hen ry
+c row
+aci ous
+di an
+pa ige
+ba re
+stock holm
+scen ery
+ðŁĩ ·
+jef frey
+pu sh
+decor ation
+ne d
+cu te
+brig ade
+laven der
+inv ites
+e sports
+vo ir
+dri ed
+tran spl
+sur geon
+no vels
+pul ls
+son y
+lun ar
+man e
+i vy
+fru str
+dor set
+sa i
+tor res
+ssi on
+shut down
+suggesti ons
+writ ing
+e o
+battle field
+u ga
+ðŁIJ ¾
+vac u
+spl ac
+g it
+u g
+high land
+% )
+mer maid
+sacram ento
+ta ils
+p w
+ka h
+t ell
+enh anced
+ì ķ
+auck land
+cru el
+ðŁ¤ ©
+au dre
+sail or
+gram mar
+g love
+de on
+infl am
+fresh ly
+k ell
+zi p
+christi e
+mil d
+di xon
+instru ctor
+g ence
+ãħ ł
+sub jec
+constitu tional
+crow ds
+in visible
+ru ins
+da k
+si p
+pla que
+p ouring
+comple x
+z ine
+ste ad
+f let
+trans mission
+lo way
+ar un
+incre asingly
+au d
+transp aren
+cro wned
+sc oun
+blizz ard
+lux u
+fi ers
+achieve ments
+hun ters
+rock ed
+bas in
+vio let
+pro ves
+achiev ing
+pro sper
+se ga
+flo at
+vi an
+xi v
+pol ic
+tur a
+approxim ately
+wander lust
+keep ers
+geta way
+co d
+pol is
+br yan
+col ts
+tal ents
+yo gur
+gluten free
+wri st
+gr y
+cze ch
+ðŁİ Ī
+ev ille
+ðŁı Ī
+to x
+dani els
+am er
+bi ds
+weare one
+me tab
+g t
+boy z
+pd x
+pos session
+pu shed
+shr ine
+reali stic
+tri gger
+na vi
+ru mors
+n af
+jen kins
+tr un
+comm uni
+Ã Ĺ
+gam ers
+arm or
+moham med
+bal cony
+y ah
+stron gest
+rhy thm
+unfor gettable
+k p
+ho bb
+custo dy
+greg or
+r ita
+aes thetic
+il ation
+sponsor ing
+n ay
+kid napp
+sh s
+ra jas
+me g
+signific antly
+butt ons
+la c
+ver sions
+essenti als
+opini ons
+k ro
+d printing
+wi dely
+d k
+ur an
+y al
+reque sted
+c n
+cur ric
+plu m
+gr un
+v m
+dev on
+m yo
+rel ation
+juvent us
+rou ge
+min ority
+min es
+jupit er
+n ine
+oxy gen
+fran kie
+une sco
+fab ric
+disgu sting
+sal man
+dete ction
+lan ka
+d ac
+ðŁĩ« ðŁĩ·
+argu ment
+shel ves
+cel tics
+rober to
+pi gs
+he dge
+fau l
+pow ering
+butter flies
+fi r
+re make
+att i
+com o
+emp ha
+kend all
+poke mon
+se ating
+d ans
+bald win
+ðŁij »
+lesli e
+one direction
+ti mber
+im an
+fon t
+e der
+di on
+ste ph
+for mat
+gre gory
+pro p
+he x
+ru in
+sor y
+inf er
+n aw
+bar ak
+sd gs
+kar ao
+lu sh
+v ander
+end ent
+g is
+a fro
+soc cer
+ay an
+t uni
+lun g
+da yof
+alex a
+mar ath
+addic ted
+ag ile
+hy gi
+light weight
+ì §
+mand ela
+jo ey
+anc y
+hu m
+bi r
+memor ial
+jim in
+ging er
+v ak
+jav ascri
+cro ps
+orig ins
+d ari
+pi per
+im port
+aggre ssive
+predic tion
+re pairs
+cr acker
+voy age
+ni ke
+mu mmy
+linke din
+country side
+bor der
+gla ss
+per t
+s als
+sho e
+autograph ed
+wal nut
+colle gi
+sal ary
+pa iring
+ðŁĮ ¸
+cath ol
+swee the
+defe ats
+streng then
+roof top
+impro vements
+barri ers
+ur u
+t ally
+ru led
+ðŁĨ ļ
+nai ja
+emo ji
+per cent
+gi o
+pro bs
+on ce
+adm its
+pa ths
+li ar
+day tona
+pe ters
+cal i
+cal li
+mu g
+o sa
+ap h
+ab y
+hy de
+eth nic
+pla ins
+ol f
+haha hahaha
+holi c
+?! ?!
+su bli
+bl acks
+mo t
+gh ton
+lo vin
+b rent
+bar u
+l ati
+de w
+ate au
+q a
+pain ful
+bu sters
+st atic
+ðŁĩ¨ðŁĩ ¦
+note book
+out fits
+si es
+r f
+floo ds
+Ñ Ģ
+thro at
+su ici
+ro vers
+beng al
+pre pares
+blo g
+mini ature
+Ø ¨
+am phi
+com b
+r sp
+in timate
+green e
+Ì ĩ
+al tar
+surg ical
+ves sel
+... ?
+gav in
+g ator
+threat ened
+z ar
+rob bery
+di er
+promo ted
+y g
+x s
+su bs
+inter viewing
+threat ening
+do zen
+me ado
+water fall
+nintendo switch
+cal um
+mini sters
+dro p
+univers ities
+war ned
+tac tics
+ðŁĩ ²
+refu se
+ad ju
+v ast
+ðŁĺ ´
+mc fc
+lib ya
+no filter
+distribu ted
+re ser
+ron nie
+de co
+javascri pt
+mon k
+intere sts
+fle x
+mar tha
+sti es
+oo d
+ðŁ¤£ ðŁ¤£
+e un
+b ali
+g omez
+sti mul
+moder ate
+d ity
+ir is
+stra w
+consist ent
+direc tions
+adop t
+sal sa
+cro o
+reco vered
+black friday
+lan caster
+accep t
+weareone exo
+buil ds
+free man
+air plane
+diti on
+bel ong
+jam ie
+pit ching
+li f
+om in
+cri spy
+pre pping
+ve g
+chan g
+accompli shed
+graci as
+dolph in
+elec tor
+culin ary
+super bowl
+wal a
+pur suit
+black berry
+be an
+cardin al
+pro ved
+immigr ant
+stric tly
+holocau st
+pass age
+ha us
+cou p
+pur se
+har ass
+< <
+le ed
+ado be
+st ad
+legis lat
+par ked
+pri yan
+sil va
+kri st
+s the
+fun ky
+ig a
+sett lement
+ph s
+t mrw
+stre ssed
+hun t
+ho ckey
+treas ures
+cham bers
+ol u
+hu t
+mar ley
+tex ture
+wilder ness
+mm ing
+poten tially
+om aha
+ju dy
+to es
+spo iler
+distingui shed
+feli x
+ah u
+recommend ations
+zom bies
+hit ler
+tri ple
+colla pse
+motiv ated
+ulti mat
+gg ling
+so y
+ci gar
+fo ren
+vine yard
+gl itter
+fin dings
+colon ial
+hun ter
+eri k
+den s
+beet le
+lot te
+sub tle
+s matter
+tru sted
+experim ental
+nam ents
+ðŁĺ Ĩ
+regi on
+acquis ition
+bre eding
+quarter back
+am reading
+oo td
+ru de
+initi atives
+st out
+hy ung
+out come
+al fred
+mic s
+exper tise
+bacter ia
+pengu ins
+jump er
+valen cia
+bar k
+ing day
+sell ers
+contrac ts
+hou ston
+commissi oned
+adap tation
+swan sea
+santi ago
+common wealth
+ju dging
+sub mission
+sco rer
+tom my
+ñ o
+ex quis
+fil ing
+explan ation
+alli son
+wemb ley
+ri dge
+chev y
+san tos
+own ership
+cogn itive
+favour ites
+sh ed
+phil anthro
+dele ted
+go dd
+s nor
+gui delines
+ff ing
+je ep
+cli ps
+sw amp
+an or
+guil d
+bol ton
+spring field
+munici pal
+goal keeper
+ye on
+ðŁĺįðŁĺį ðŁĺįðŁĺį
+ãħĭ ãħĭ
+water front
+gra ve
+contempor ary
+ar ity
+ÃŃ a
+sle eps
+sy rup
+al am
+pi re
+co yo
+moto gp
+ty son
+kej ri
+cir cul
+sing ly
+cr unch
+complic ated
+nostal gia
+k op
+mo ve
+k ale
+mac ro
+mid west
+h ans
+tri bal
+nu de
+௠į
+bey once
+congratul ate
+cat er
+leagu e
+ðŁĻ Ĭ
+la dder
+cra shed
+tech nic
+karao ke
+harass ment
+ro ts
+experi encing
+kri sten
+ðŁĩ ³
+ðŁ¤ Ĺ
+reflec tions
+guin ness
+illustr ator
+ðŁĻı ðŁı»
+cen ter
+nar row
+comm ons
+regul ations
+Ù Ĩ
+har m
+cro ft
+cu ssion
+hong kong
+st ical
+intern ship
+zo e
+cho p
+hoo ds
+estim ated
+batter ies
+berke ley
+smooth ie
+shau n
+cro s
+~ ~
+cam pe
+hu mp
+b g
+proto type
+cl ick
+shaw n
+re viewed
+tem pl
+p f
+jed i
+blo gs
+ray mond
+as th
+ba h
+av ail
+scot ch
+leaf s
+nik ki
+to k
+hol low
+ur ges
+of t
+un like
+lat in
+u e
+cat ering
+mil i
+alter nati
+ma ver
+Ð ¸
+ag le
+pre order
+lu x
+cu cu
+ðŁijı ðŁijı
+t art
+âĿ¤âĿ¤ âĿ¤
+arab ic
+rapi dly
+ar rang
+all en
+travel tuesday
+pa ws
+flo ws
+st ability
+flu id
+ca pp
+can berra
+uu uu
+sp ani
+demon stration
+m la
+plac ement
+m w
+presi dents
+awe som
+bever ly
+ani st
+ne al
+father sday
+referen dum
+la hore
+o aks
+deb bie
+half way
+gho sts
+de bor
+matthe ws
+fi at
+t fw
+pre sen
+rob i
+de d
+bro ck
+laugh ed
+am ounts
+bam boo
+kinder garten
+eat en
+mtv hottest
+break out
+u sic
+fra ser
+legis lative
+p ang
+modu le
+sam my
+go ver
+ear ns
+expe dition
+gar h
+concep ts
+char lie
+la va
+bachel or
+veg gies
+deter mine
+el lie
+un locked
+fru it
+dal la
+cou pe
+wash ington
+depo sit
+iv ory
+pau la
+chic ag
+gu cci
+ðŁİ ĥ
+cul tiv
+pier ce
+li fted
+stu mb
+re cover
+musc les
+conduc ting
+cb s
+mcla ren
+sophi a
+cel lu
+oce ans
+up loaded
+game play
+mal dives
+kim ber
+avo i
+rac er
+ca ine
+cav s
+h ana
+li ga
+ra ven
+inter vention
+inaugur ation
+oo h
+at traction
+merchandi se
+tune in
+li king
+juni ors
+int ended
+att acking
+aqu arium
+i wd
+comp onents
+sur ing
+cent u
+yogur t
+ðŁı ĥ
+show room
+op tical
+ty our
+ju dge
+yi eld
+an to
+pl c
+transparen cy
+recy cled
+chi ef
+ar om
+ambassad ors
+plan et
+âĿĦ ï¸ı
+om ed
+vaness a
+cour t
+mar gar
+hal ey
+v r
+reg ina
+pd ates
+hi span
+live stream
+âģ £
+ya hoo
+gal la
+secu red
+w ir
+bene ath
+off l
+n il
+am b
+ye g
+out let
+u te
+pe ep
+lind say
+bent ley
+... !
+he el
+trilo gy
+vo s
+ty re
+there fore
+tor onto
+ab i
+simp li
+ja e
+exten sive
+eleph ants
+s or
+orient ation
+im peach
+re play
+constru cted
+peter son
+pa is
+por ted
+custom s
+colla p
+ad u
+high lands
+sal em
+shel by
+ko vic
+stra in
+ro sie
+sen ators
+snap s
+bo bb
+suz uki
+bla des
+k p
+lo lo
+gener ate
+si ght
+ma e
+struc tural
+predic t
+jump ed
+ah mad
+sun g
+just ice
+gla m
+vol vo
+jubi lee
+de tention
+lo sses
+pu ri
+every time
+Ð °
+ra o
+ed ge
+li mer
+rese mb
+har old
+re tri
+sacri fic
+surpri ses
+am c
+srilan ka
+bar bie
+men s
+fin n
+ag s
+ukrain ian
+em brac
+î IJ
+flav ors
+hom er
+lau re
+ou th
+pr iced
+ver de
+fir m
+ah s
+cu b
+tre y
+par anor
+pro fit
+in dv
+who a
+har sh
+al ot
+crit ics
+hu bby
+fi gur
+gi ra
+ca stro
+chan el
+in put
+origin als
+ten ant
+yy yy
+ture rs
+lincol n
+co on
+lear n
+ch ou
+ac are
+o les
+din er
+hy p
+bizar re
+mc r
+let sgo
+decor ating
+ðŁĮ İ
+al ison
+ar vin
+f d
+reha b
+mccar thy
+lot tery
+da h
+minne apolis
+eli gible
+diagno sed
+emer ald
+destin ations
+s ans
+or y
+bla zers
+n v
+ba il
+digital art
+no c
+mal ta
+sol ar
+pi pes
+alleg ations
+no ck
+po pe
+bri d
+premi er
+n x
+present ations
+ef a
+bo ws
+val ve
+opp onent
+Į ë
+visu al
+ing le
+cate gor
+e ter
+po is
+dan i
+at tract
+neu tral
+th ene
+cra shes
+fred die
+ut ili
+c st
+awak ening
+slo ven
+quali fy
+pro of
+fair y
+le v
+fre ight
+enjo ys
+cup cake
+flav our
+â ķ
+protec tive
+ðŁijı ðŁı»
+is u
+ad mir
+h mmm
+continu ous
+ai res
+rap tors
+showcas ing
+y uk
+pa ste
+follow er
+instru ctions
+sp ru
+@ __
+the o
+debu ts
+ve tte
+sto w
+es of
+ach ed
+sul tan
+sand wich
+som alia
+franc o
+car ne
+flu ffy
+al pine
+jas mine
+he ated
+viol in
+ple ss
+divor ce
+per former
+phi es
+port sm
+dar a
+kir by
+lo p
+chill i
+for th
+sky pe
+ðŁĩ®ðŁĩ ¹
+celebr ities
+ed y
+ve e
+po ison
+ey el
+gra bs
+ssi c
+un o
+wester n
+rail road
+am er
+numer ous
+s v
+fo w
+fi st
+âĢ ĭ
+reque sts
+mar tial
+em my
+accept ance
+lau ra
+ภ´
+er up
+hyun dai
+out lander
+u tt
+wrest le
+esp resso
+demand ing
+g dp
+geo graphy
+sas kat
+tro ll
+confe der
+su es
+se m
+be ts
+t ful
+to sh
+teach es
+col oured
+gal way
+mac y
+dis orders
+bb cra
+at em
+fen der
+lit ter
+e sh
+provi ders
+renov ation
+nomin ate
+ps g
+nomin ations
+jen na
+shar p
+some day
+z ur
+bra ins
+che shire
+pre y
+hu go
+Â ¿
+to ken
+r v
+car r
+tac tical
+zel da
+kay la
+fern ando
+photograph ers
+j our
+umb rella
+woo dy
+congress man
+du mp
+le vy
+ju an
+d azz
+sign als
+la in
+an u
+mic hel
+por ch
+al den
+sibl ings
+y ale
+pe el
+sw ick
+gg in
+ll c
+k ale
+s con
+il d
+pat reon
+re el
+qu in
+wit t
+mar ty
+moo dy
+ton i
+der y
+g ators
+speci fically
+dd in
+ly on
+tr ick
+meado ws
+p j
+bor gh
+vi k
+tu r
+bron x
+pu ff
+lan tern
+ðŁ¤ ¦
+g ently
+be stie
+fac t
+refu sed
+fas ci
+mp y
+ðŁĶ µ
+cross over
+mead ow
+indian apolis
+duc ation
+sle y
+loo m
+mix er
+new music
+film maker
+prosper ity
+li m
+week end
+cre amy
+neu tr
+lu ther
+h v
+nor thern
+tw o
+h ra
+cat ches
+appear ances
+ha bit
+kitt ens
+n v
+illa c
+inf an
+regar dless
+liz ard
+dun k
+cur tain
+ac om
+in tu
+ve z
+e min
+fl ats
+calend ars
+em power
+ru ined
+hun gary
+vi d
+we x
+u lum
+aber deen
+o sa
+k t
+ma ssi
+se emed
+s den
+' ?
+tele phone
+de fi
+insp ires
+me ow
+z ones
+bl ind
+pl y
+tuc son
+advent ure
+ge d
+oy ster
+ðŁijıðŁijı ðŁijı
+out put
+tt t
+metal lic
+sma sh
+ucl a
+sco ts
+perfe ct
+lu cy
+regular ly
+sp ic
+rel ative
+ath ers
+mis e
+batt ling
+deci des
+mat a
+occu pied
+random ly
+cat softwitter
+gi an
+ball y
+al ties
+al lies
+im men
+sy rac
+ðŁĴľ ðŁĴľ
+l lan
+au r
+k ut
+lam ar
+affe cts
+n ra
+star war
+ðŁ¤ ĺ
+sc ram
+en chan
+pro cess
+luxu rious
+ar ray
+sher lock
+comp ati
+dor f
+stre ss
+m su
+s with
+sal a
+sof instagram
+fo il
+under stood
+qu ay
+r p
+c ade
+ja w
+en ab
+en coun
+ðŁİī :
+do ck
+satur n
+mu ll
+lay out
+ra rely
+happ ily
+fix ture
+or ph
+over looking
+her bs
+m itt
+pil lar
+nol an
+pe tty
+str y
+u i
+mu k
+o res
+o vers
+á µ
+re creation
+we sley
+ri t
+kejri wal
+sto cking
+g v
+subscri bers
+moo se
+ma e
+ber t
+opp re
+assign ment
+u ro
+high lighting
+cal vin
+we igh
+cambo dia
+av on
+ke m
+dis abilities
+read y
+char gers
+p ads
+iz ing
+illi an
+tru ste
+col leges
+associ ates
+alban y
+mil ton
+cr on
+bu r
+har dly
+si ghts
+anti ques
+e cho
+surpri singly
+ha iti
+cap t
+ph p
+op io
+ine quality
+equ al
+ken y
+sch mid
+autograph s
+ren t
+qu er
+cit rus
+challeng ed
+te c
+epi de
+fe st
+z hou
+li me
+citizen ship
+cry stal
+convin ced
+mess enger
+copen hagen
+âĿĹ ï¸ı
+war ran
+develop ments
+ï¸ı âĥ£
+fore x
+hi ro
+sne akers
+xi de
+vi va
+stere o
+bat ting
+ss el
+ho st
+beng al
+critic ism
+q c
+cr un
+attemp ted
+ry e
+determin ation
+cre ations
+d read
+label s
+pos se
+anc er
+joh an
+si ster
+partner ships
+les bian
+k st
+guaran tee
+bar o
+fix ing
+ma son
+m ous
+chem icals
+t less
+bio diversity
+par o
+bhar at
+ac ol
+refu ge
+en te
+t iti
+dys sey
+respon ds
+lef to
+in er
+se vel
+rahu l
+ol ine
+frank fur
+cho reo
+enjoy able
+c to
+strugg les
+wood land
+heavy weight
+gen s
+rece p
+ac cred
+ðŁĺ ¡
+trans formed
+list en
+at op
+n k
+sur ge
+be re
+gover nor
+prison ers
+clau de
+t ill
+mu lator
+emo tion
+water loo
+star t
+ðŁĩ º
+clean ed
+grand mother
+fear less
+afric an
+astron omy
+ðŁı ģ
+ภĻ
+the world
+su itable
+anth ony
+k and
+tt en
+meaning ful
+disc lo
+jaco bs
+Ã ¸
+tom linson
+ghe tti
+ty pho
+sub stan
+as co
+te k
+nag ar
+mu d
+am on
+vacc ine
+f ty
+fle sh
+no el
+infl ation
+portu gue
+glam our
+tra m
+v re
+te qu
+roun dup
+w yn
+rejec ted
+mosa ic
+si ghting
+cal f
+o ta
+com position
+go pro
+gonz ale
+e ed
+b ard
+tu e
+effec tively
+we en
+al to
+ri bs
+rel ate
+thir sty
+fu rious
+di m
+ch ard
+perfu me
+s ny
+chur chill
+k of
+master class
+wa ve
+ðŁĶ µ
+er in
+own s
+to be
+sk illed
+te m
+go f
+en i
+tor i
+cra zy
+l ick
+resi stant
+ici al
+ag ar
+! :
+g ali
+del aware
+bl itz
+koh li
+pu ck
+avail ability
+hi malay
+influ ential
+cro chet
+victor i
+read ing
+ho bby
+vie t
+j as
+en gra
+sk ul
+ðŁĩ² ðŁĩ
+educ ate
+tech no
+distric ts
+blu es
+se tt
+seven th
+lear ns
+ee ee
+apocaly pse
+hang out
+cru el
+mu tu
+bru h
+hel en
+she er
+c tion
+kle in
+tex ans
+ce real
+sh ine
+ne red
+gra s
+am bro
+f ella
+hin du
+matthe w
+li ma
+mir anda
+je wel
+so ho
+euro vision
+neighb ours
+chand ler
+be sides
+ðŁ¥ °
+ast ros
+thu mbs
+ren ault
+ra ve
+hi red
+ðŁĸ ¤
+it ary
+z or
+bla zer
+k ine
+ea u
+kat y
+dc comics
+pe c
+ro dgers
+water proof
+kill ers
+super int
+pre serv
+as so
+brew ers
+promo tional
+sc am
+villa ges
+sket ches
+ju icy
+for life
+au dit
+so lo
+fundam ental
+len e
+philipp ine
+t end
+conserv atives
+sponsor ship
+dd le
+a ine
+h tc
+os i
+hul k
+w af
+ภĻ
+evalu ation
+ant ine
+sle e
+robert son
+roo sevel
+ag i
+sophi stic
+emplo yers
+bubb les
+ko wski
+inter action
+sh u
+bou le
+ic an
+j are
+han k
+leg itim
+k nicks
+kar ma
+recei ver
+per ks
+u h
+sta ir
+sun i
+labor atory
+gra ves
+voc als
+oo t
+c ture
+thri ve
+tic o
+ãĥ ³
+b w
+carto ons
+mcdon alds
+dra w
+y ung
+pl er
+li d
+eth ical
+groo ve
+ent a
+international womensday
+pat ron
+wor ries
+ðŁİ ħ
+ðŁij ĭ
+ka therine
+di az
+tor i
+bach chan
+tru st
+min eral
+ic om
+buil ders
+bor n
+col oring
+lat te
+ca se
+revolu tion
+tra der
+ox id
+chi pot
+inst antly
+sou thern
+se hun
+pro b
+her nandez
+lis bon
+hu awe
+p ong
+me a
+ro oney
+wheel chair
+ke en
+be tt
+cor in
+regulat ory
+di splac
+ka ren
+sch em
+sun sets
+wh ales
+remin is
+he p
+hi de
+mar cel
+pand ora
+do yle
+th fc
+ot to
+no kia
+trans gender
+ko v
+hawai ian
+sha ve
+so vere
+exc er
+nick i
+pu g
+st or
+ro th
+wee t
+leg al
+dig nity
+po w
+hom age
+ðŁĩ³ ðŁĩ
+s re
+can on
+la x
+wo ah
+quart z
+ñ a
+gree ting
+flick r
+nai robi
+advoc ates
+an c
+vi i
+eu gene
+th ra
+c re
+el an
+pen sion
+th letics
+ton i
+re agan
+x v
+sto re
+ben ch
+har lem
+todd ler
+sent enced
+âĻ¥ ï¸ı
+glob ally
+che aper
+u f
+ma m
+nic o
+ik u
+tho u
+ni st
+dam i
+th ala
+rho des
+sal e
+bow ls
+â Ī
+las vegas
+sanc tions
+adm ire
+mat ched
+un able
+travel er
+ele ven
+straw berries
+âĢĶâĢĶ âĢĶâĢĶ
+stu dio
+jac ques
+im s
+valu ed
+s no
+cheese cake
+n xt
+e os
+s x
+f x
+ton ic
+hat ch
+chic ks
+gra ds
+hand ic
+r ory
+as p
+ri pped
+denti st
+n en
+lu fc
+âľ Ĭ
+di ge
+hop kins
+sher man
+f da
+for all
+ash ley
+str and
+h y
+liqu or
+buffe t
+ess ence
+phar ma
+suri ya
+ðŁĴĻ ðŁĴĻ
+festi vals
+z an
+re fresh
+pur ple
+uni forms
+kenne th
+= )
+as an
+hel sin
+transform ers
+k ali
+person alized
+chal k
+bo bby
+â Į
+the mes
+depar ture
+prin t
+illustr ations
+qui et
+agre es
+gri ff
+Ø ³
+m iti
+toge ther
+conven ience
+ab ar
+car lo
+turt les
+info sec
+some what
+ar lington
+scholar ships
+emir ates
+mu ms
+st ella
+auton om
+fe ather
+g ore
+nom inees
+fragr ance
+Ñ Ĥ
+w ong
+thea stern
+gr e
+z illa
+is i
+bump er
+go o
+do zens
+ab duc
+âļª ï¸ı
+o ils
+don ors
+sil icon
+i pod
+fortn ite
+ðŁĴ ¨
+tor o
+spark ling
+consci ousness
+pal a
+nu m
+moun ted
+ffin s
+thi eves
+team mate
+pra b
+om er
+ta pes
+bo d
+mit su
+ste w
+e re
+p bs
+tu sc
+lo we
+ra de
+parliam entary
+h m
+ed gar
+ðŁijĩ ðŁijĩ
+to a
+a gh
+hon i
+s late
+ge ek
+ap t
+hard t
+ta p
+horiz on
+grow th
+make over
+hi l
+paper back
+id an
+reha bil
+gi u
+possi bilities
+let tu
+fran co
+bo ss
+ach er
+does nt
+mo e
+ta ker
+huss ain
+ml k
+di l
+th ia
+ham a
+real ised
+raven s
+curric ulum
+m ith
+k night
+ted x
+r v
+isai ah
+cumb ria
+birth days
+f ing
+pre z
+mu barak
+exquis ite
+clear ance
+y en
+par i
+ev o
+Ã º
+modi fied
+app lying
+imple ment
+disco vering
+chap man
+indie game
+dis k
+crowd funding
+mach in
+li vel
+sty led
+âĿ Į
+ma king
+rehear sals
+nutr iti
+subscri ption
+and ro
+cre ators
+car ries
+ky lie
+cam den
+appren tice
+tax pay
+c ca
+tuesday thoughts
+pis sed
+er man
+dete c
+freed om
+mer i
+.. !
+psal m
+sun light
+per spec
+be ings
+book store
+rock star
+fun ctions
+p ence
+fav es
+z n
+obam acare
+sp ill
+coven try
+pi geon
+pi vo
+ba it
+kol kata
+av al
+don or
+wa h
+privi leg
+tra ditions
+rajas than
+ten ess
+portugue se
+yn es
+tack les
+de fic
+tor n
+pol ling
+thor ne
+in a
+bened ict
+bar ry
+cal ories
+ver dict
+save the
+nor ton
+off ice
+main stream
+impro ves
+fr on
+respon ding
+real tor
+scotti sh
+de clar
+r l
+shi v
+supp lier
+re sting
+swee ts
+qu i
+. â̦
+whit ney
+startu p
+thank you
+teach er
+h alls
+ha ve
+hand made
+pro ving
+quar tet
+ro chester
+li an
+virtu al
+mend es
+of icial
+mid lands
+x box
+meas uring
+o vo
+accommod ation
+bri des
+collegi ate
+intellec tual
+in car
+ni ag
+ðŁį ·
+sf w
+coco a
+co ats
+civil ians
+presi dency
+mat rix
+sweethe art
+tri athlon
+wag ner
+ra dic
+plann er
+the o
+execu tion
+k um
+the walkingdead
+sc ar
+ro tation
+blo gging
+bom b
+re son
+bb les
+st are
+assi sted
+e do
+brand ed
+war nings
+thor pe
+acknow le
+satis fied
+sho res
+ri d
+dor a
+phys ically
+bi gh
+appro ves
+ha h
+ric al
+vers atile
+pret end
+lu m
+ab hi
+ye e
+sp it
+ãĢ Į
+dj s
+ash tra
+j t
+ven ues
+gram mys
+cy clo
+tr acker
+over watch
+repl ica
+el yn
+nr l
+lind sey
+hom o
+ballo ons
+kitch en
+si s
+am os
+ende av
+ðŁĴ »
+a rec
+thu g
+hoo ked
+hr c
+new york
+bur gh
+americ as
+patric ia
+ug u
+ap athy
+ha st
+psy chi
+cor k
+petro l
+ðŁİ ¬
+ak u
+po pping
+psycho logical
+au x
+g ma
+cad illac
+wa ste
+auth ent
+bri stol
+nam e
+que er
+to ber
+jer ry
+com in
+ch ant
+privileg ed
+op ar
+lo ser
+tex t
+mar ker
+stri es
+equ ally
+ak i
+christ mas
+gare th
+ble w
+em ma
+imag in
+se als
+che at
+conditi oning
+j ana
+ren s
+dar ies
+o asis
+disc ounts
+coun cil
+i ka
+shir ley
+vou cher
+al ps
+w x
+q r
+dri ft
+attemp ting
+ut c
+Ø ª
+gonzale z
+m f
+jo ker
+paralle l
+pa re
+aspe cts
+proce du
+n p
+am a
+rale igh
+bright en
+gu ire
+radi ation
+cre scent
+ho b
+il le
+str and
+v ore
+n ard
+che st
+di wali
+av atar
+al der
+d ling
+pa thetic
+ðŁĴ ĺ
+spir it
+jor ge
+film making
+ðŁĻı ðŁĻı
+challeng er
+b j
+down town
+ht ml
+ade qu
+twi sted
+in ely
+( '
+wra ps
+oper ational
+y ne
+n us
+mag net
+market place
+health ier
+snap shot
+dam on
+inter ven
+fe derer
+ow ls
+biscu its
+j p
+ro deo
+blue berry
+lec tion
+fron tier
+summ ers
+re yes
+pede strian
+go l
+caf fe
+refur bi
+bou lder
+me ghan
+speci alty
+la ss
+e i
+suspec ts
+appro x
+rr r
+ra th
+st im
+cru shed
+he d
+wh un
+lo af
+cr ore
+river a
+gene tics
+so ck
+wa sted
+ny pd
+answ ering
+do ve
+bel la
+ol in
+du n
+fi ji
+pre tty
+spar kle
+y un
+j d
+euro pa
+li fts
+am ber
+mu r
+te k
+boy d
+roy alty
+in do
+ri b
+go tham
+ti est
+inst alling
+ke mp
+the photo
+cos mic
+) ))
+whole sale
+loy ment
+eas y
+su ing
+sett led
+af p
+pro ver
+suppor tive
+re es
+ne ath
+deli ber
+c é
+wel come
+pic oftheday
+new born
+pat ty
+sun s
+si est
+fl int
+diffe rently
+spo ilers
+troop er
+g ins
+cor y
+look out
+equi pped
+ta pe
+to by
+resear cher
+u sh
+ke yes
+al ma
+induc tion
+k w
+k har
+sl ick
+bri de
+e ur
+cra ving
+book ings
+ch es
+tr unk
+vern on
+sp her
+cryst als
+rel atively
+pom pe
+uni ons
+val ley
+par a
+w ant
+ok c
+de af
+ser gio
+len non
+sh ay
+cr a
+v at
+he e
+t we
+liqu id
+pol y
+ðŁİ ģ
+b ent
+be aring
+motor sport
+bar be
+te sti
+han i
+fin ancing
+astron aut
+water colour
+ri sh
+comic con
+gar t
+wr ong
+ber n
+it an
+ste pped
+fil ters
+c low
+me x
+dem ons
+all o
+expand ed
+comm and
+et ers
+go ats
+si ri
+y r
+pot tery
+mari on
+i le
+el an
+san to
+person a
+du ke
+hom eless
+li ghted
+wheel er
+chang er
+cab bage
+sur real
+ham burg
+sma shed
+str an
+k not
+i art
+ob i
+be dro
+di al
+th ick
+b ingo
+fu s
+vacu um
+con ve
+ati ve
+accur acy
+accoun t
+re fer
+ri z
+spider man
+ban a
+r ite
+u b
+ab s
+medic al
+lin k
+si em
+> >>>
+be tra
+g lowing
+re actions
+pupp et
+spa ghetti
+ang s
+re medi
+pray for
+roy ce
+char lotte
+£ ï¸ı
+gh et
+affe cting
+ro de
+soci alist
+mo ses
+az i
+o it
+re porters
+cd t
+ap ing
+s nat
+minim al
+wa ist
+sie ge
+>> >>
+ri g
+schmid t
+h are
+ec a
+thor n
+he mp
+es the
+cly de
+th a
+don ut
+moham ed
+ling erie
+le gg
+carpen ter
+perform ers
+de a
+imag ined
+cur se
+la sh
+ct r
+agu a
+ro ar
+gr i
+ro le
+j fk
+resur rec
+roosevel t
+maril yn
+sm alle
+will is
+wa ited
+char ities
+the res
+li k
+origin al
+car i
+c ough
+cru ci
+la gun
+contra st
+k ou
+arm our
+re moving
+t ent
+maz da
+bri ghter
+thi ef
+cor ner
+tequ ila
+buzz ing
+al bi
+p am
+az ure
+disc oun
+pixel art
+possi bility
+ham ont
+tra des
+bu da
+hi ve
+vers y
+fin ch
+tran spa
+em i
+terri fying
+in qui
+g ba
+sub stitu
+collec ti
+plac ing
+cin dy
+k ann
+pa tho
+diamon d
+mour inho
+guine a
+anthro po
+air s
+pu mps
+ì ļ
+pas o
+cur ling
+an ita
+resi dency
+ne wh
+jo on
+cigare tte
+que ue
+ex trac
+gam es
+spl en
+ex press
+public ly
+bon nie
+tribun e
+ba ek
+reason able
+c or
+timo thy
+she eran
+Ä ±
+f dn
+su tton
+concentr ation
+carav an
+x avier
+al ger
+cy lin
+freder ick
+ner ve
+pe ak
+lettu ce
+j ail
+pre game
+kav an
+up graded
+eco logy
+squad ron
+gra pes
+goo g
+pa stry
+ðŁĹ £
+ãĥ¼ ãĥ
+mil ano
+awa z
+presen ter
+ðŁĮ ¿
+her d
+king s
+tem plate
+fl our
+h v
+k ley
+i ya
+spe c
+at er
+frankfur t
+co ch
+tex ting
+del i
+communi st
+regi ment
+ele anor
+anticip ated
+ðŁijĮ ðŁı»
+thephoto hour
+ran o
+survi ving
+simul ation
+daw son
+ar in
+aqu a
+m or
+â̦ .
+cin o
+ira qi
+sh az
+dun dee
+we s
+dra u
+hann ah
+s news
+occup ation
+ste en
+x m
+ang les
+sett ings
+gur u
+kno x
+or ca
+shap ing
+w ent
+dr illing
+zz ie
+br i
+kis sing
+fin d
+ma ine
+âŃIJï¸ı âŃIJï¸ı
+ðŁĮ į
+lar ry
+bu sted
+ta vern
+acti vely
+- "
+replac ing
+no d
+un lock
+. "
+âŀ ¤
+affili ate
+to w
+l n
+happy newyear
+di f
+j m
+green wich
+contro versy
+daw g
+con dol
+sav annah
+compens ation
+touch down
+te o
+amb itious
+embro i
+convic ted
+iart g
+bar ack
+tr ance
+testim ony
+au dition
+thum b
+my ths
+be x
+que z
+orch id
+den y
+entit led
+hoo d
+gr ant
+in box
+blue jays
+r illa
+smalle st
+bur den
+in famous
+divi ded
+boun daries
+t ter
+el t
+wy oming
+be verage
+me sm
+one ws
+budd hist
+y ana
+as sad
+is ms
+bar rett
+predic ted
+back to
+tw it
+e there
+cap tains
+escap ed
+ay o
+lam borgh
+gard ner
+la ps
+k al
+adverti sement
+insec ts
+na po
+am en
+ac y
+r and
+g k
+te h
+k athle
+tri dge
+pan cake
+at ro
+pyram id
+bu la
+paral ym
+gau ge
+en cies
+tom y
+biscu it
+but cher
+quali fier
+coun ty
+ke i
+po ols
+dar ker
+should ers
+ðŁĩºðŁĩ¸ ðŁĩºðŁĩ¸
+sp re
+( "
+writ ers
+g m
+ðŁİ ĵ
+k nit
+hu ff
+mt b
+philli es
+o st
+den is
+g art
+licen sed
+inter face
+ex cel
+d well
+from the
+co fficial
+az zi
+appear ing
+fore st
+n ana
+ke ith
+manufac turers
+beck ham
+) ?
+e se
+col ony
+delic ate
+ut ter
+mc in
+transpl ant
+pre ferred
+par d
+ari e
+hu b
+po ds
+perspec tives
+pic t
+del u
+app er
+be than
+p mo
+crimin als
+femin ism
+sh ack
+circum stances
+fel las
+prote sting
+wa x
+sugge sted
+t ator
+dre w
+om ni
+fa ke
+kath y
+re b
+del ine
+ber ni
+mi sty
+ðŁij ©
+er able
+break through
+men swear
+millenni als
+chan yeol
+la z
+inser t
+rep lies
+phra se
+n x
+ihear tawards
+audre y
+gran ite
+rac ec
+ori e
+ter ra
+innov ations
+britt any
+at eral
+pe ar
+bio logical
+sh ments
+institu tion
+m sn
+frequ ency
+d man
+neg lec
+t f
+ste fan
+fox news
+ty po
+comm s
+sequ ence
+car men
+wh ites
+econom ist
+exe ter
+se um
+re sorts
+cas ually
+bun de
+divi de
+Ø ¹
+ga g
+cre ed
+reti re
+cau cus
+rapi ds
+wrestle mania
+tul sa
+sunder land
+fundam ent
+o di
+yam aha
+v ary
+intri gu
+el se
+be acon
+an gie
+tra ded
+tran sm
+g ents
+kn itting
+gal ac
+ðĿ Ĺ
+u to
+sea side
+hol t
+re rs
+far go
+train ers
+mon soon
+b ale
+sou ght
+mad die
+h w
+co li
+fr an
+fav s
+ðŁĴ Ķ
+int ent
+r ally
+s bs
+lemon ade
+barack obama
+bre ad
+stick y
+explo sive
+chel ten
+t j
+as soc
+ram en
+hom ies
+v log
+mi ster
+lor d
+âĢįâĻ Ģï¸ı
+aly ssa
+sketch book
+ru mble
+cat ch
+migr ant
+discipl ine
+un likely
+chronic les
+fl ora
+sl ams
+am id
+s boro
+coo p
+ju mps
+tran qu
+mel is
+sof ia
+en ri
+gab e
+sy ri
+nicol as
+cha i
+w v
+be cky
+foo ty
+ta o
+suppo se
+ðŁĺįðŁĺį ðŁĺįðŁĺį
+plu sh
+ri sh
+ðŁ¤ ĵ
+k ha
+satur days
+ac cent
+he c
+lim it
+carl ton
+wi red
+taylor swift
+ðŁĺ ij
+sq l
+har ro
+recipi ents
+g at
+go p
+th of
+amaz ed
+gh an
+ðŁıĨ ðŁıĨ
+por to
+cla re
+di stant
+na c
+ohi o
+ðŁĻı ðŁı¼
+mt n
+anti bio
+dino sa
+me sa
+par tial
+b v
+lear nt
+lov ato
+questi on
+ex tract
+gossi p
+gi bb
+niag ara
+ðŁij ¨
+displa yed
+so oner
+ste vie
+nug gets
+ml n
+bro m
+tur b
+give aways
+stu pi
+bl ink
+c ili
+conven ient
+mo h
+vi ve
+f ric
+cau se
+cham ber
+cu les
+ne arest
+is se
+small biz
+t j
+canadi ans
+smar ter
+bra sil
+ra re
+que tte
+w ha
+cand le
+at omic
+ðŁijį ðŁijį
+warri or
+relax ed
+stri ps
+ne ur
+k ka
+r fc
+jen sen
+reco vering
+respon ses
+sal am
+ortho dox
+acti ve
+ell ers
+n it
+âŃ IJ
+metro politan
+centu ries
+vi da
+gra ding
+transpa rent
+sim ple
+do ts
+superint endent
+elev ator
+autom ated
+red skins
+ima m
+summer time
+jona than
+ge aring
+michel le
+confl ic
+m ice
+to te
+publi sh
+pa x
+) -
+na iled
+á ´
+tele scope
+ser bia
+ba b
+ape u
+st ically
+sen ti
+r ats
+isol ated
+grou p
+hat red
+paranor mal
+stan ley
+ali on
+safe ty
+l s
+ठ°
+nex us
+alexand ra
+mas ks
++ +
+tr on
+au k
+brother hood
+brow se
+mix es
+sim one
+mu sk
+appro ve
+lo la
+ex p
+per th
+fu turi
+un seen
+d m
+chel se
+sc outing
+o we
+portsm outh
+k ram
+mi ze
+di spen
+su p
+d lc
+adver t
+tere sa
+is le
+cy cle
+met all
+shi elds
+marin ers
+ra z
+ing en
+fun d
+an go
+jon es
+o ka
+mad den
+broc coli
+domin ic
+situ ations
+mer o
+cric ke
+puni shment
+d b
+sha king
+ðŁĺ ļ
+m q
+ari ans
+le h
+cla w
+we ds
+d ure
+ni el
+j elly
+gour met
+tra ders
+le vi
+w ages
+kne es
+wi se
+heaven ly
+avi d
+melo dy
+z ack
+ban anas
+apprentic e
+pro p
+fun ny
+o de
+respec ted
+me gan
+fe wer
+dra fted
+med it
+gra pe
+us army
+cru sad
+vo cali
+prepar ations
+non sense
+us age
+th r
+ro th
+wiz ards
+insi de
+promo tions
+mon a
+red sox
+si g
+eleg ance
+ch ia
+univer sal
+ãĢ į
+ra ja
+un ga
+pol lin
+filip ino
+ak a
+t sun
+ik on
+bi king
+decor ations
+z ac
+cade ts
+hum our
+ag m
+re ppin
+vac cin
+elo ve
+u w
+dia be
+galla gher
+az er
+do l
+a while
+pro minent
+wel sh
+t ann
+' )
+bi en
+wa g
+in al
+c wc
+wic ket
+ur st
+q anon
+x e
+out door
+dun n
+star r
+co logy
+ric ky
+u efa
+reb ounds
+s music
+inf ant
+ðŁĻ ĭ
+so p
+u mber
+hand ing
+beg in
+sor ting
+ha sh
+sp ati
+re k
+buda pest
+black hawks
+dele te
+ro m
+can did
+auth ori
+de bris
+spe cul
+inter section
+marri ott
+im ran
+ðŁĺģ ðŁĺģ
+cru ises
+ram sey
+rafa el
+aware ness
+vas cular
+beyon cé
+ru g
+ðŁĺ Į
+festi v
+ar am
+s able
+bas il
+p ill
+flo oring
+un beaten
+implic ations
+u f
+w ound
+for ge
+poin ting
+po ts
+popular ity
+ðŁijı ðŁı»
+mani pul
+s lots
+deb ates
+abs ence
+ver mont
+never forget
+wri st
+gl oria
+ren ce
+hu sk
+mel ting
+ðŁİ Ł
+br aces
+tim ely
+transform ing
+am ps
+ma k
+po e
+ah an
+gener ally
+nd p
+ale ppo
+unic ef
+pro fs
+nor d
+ma sk
+jackson ville
+v v
+sh ells
+bloom ing
+oper ators
+char coal
+ne ville
+ma gi
+chi p
+sam a
+ir an
+re forms
+accu mul
+ru e
+æ ľ
+web sites
+ga on
+devast ating
+sto s
+glaci er
+ra pp
+chipot le
+pr a
+or ous
+rom ney
+seas on
+decor ative
+c isco
+dit ch
+compla in
+ll o
+assu me
+ðŁĺĤðŁĺĤ ðŁĺĤðŁĺĤðŁĺĤ
+n els
+cent ric
+ft w
+car rots
+tat a
+can ter
+per ience
+li ers
+demo s
+bl unt
+oper ate
+reserv ations
+le ah
+sub stance
+di son
+an te
+elec tion
+v ue
+squ are
+non profit
+ca a
+f su
+y am
+ãĤ ¤
+v ladi
+comple tes
+mar i
+philli p
+ne ill
+er as
+ka it
+men do
+mahar ashtra
+g p
+dan e
+provi dence
+ther apeu
+juven ile
+me mo
+in corpor
+aa aa
+seven teen
+teen ager
+Ã £
+or ns
+wi de
+cu teness
+tw d
+ff les
+bar a
+com edy
+over time
+y az
+bar on
+unemp loyment
+ðŁij ĭ
+exter ior
+den se
+cent res
+match up
+history month
+artif icial
+qu it
+e sk
+war n
+cr itic
+j af
+ðŁĵ ²
+inform ative
+fu els
+recy cle
+nam ing
+stri pe
+sol ic
+mole cular
+dee pi
+con vo
+s sel
+na e
+de scent
+ti z
+accoun tability
+ter ry
+r ito
+sl ay
+em o
+dem ol
+sens ation
+co v
+tor e
+round table
+y ol
+excu ses
+ॠį
+tur quo
+hh hh
+pod casts
+cele b
+me ssi
+li o
+man n
+contribu ted
+u z
+gener ator
+ele ts
+veg gie
+indu l
+en suring
+detro it
+pun jab
+tran spor
+instru ction
+ad d
+por cel
+pan eli
+cir cles
+persi st
+clay ton
+sp n
+dog softwitter
+is nt
+sp r
+retail ers
+p w
+hun gar
+el ena
+mon aster
+gu atem
+je ssie
+an z
+ra shi
+fle e
+car ving
+fau x
+l al
+hen ri
+d jo
+du ll
+s ana
+lar a
+glo be
+cri mson
+com pass
+pau se
+na b
+lion el
+ba ths
+u fo
+invent ory
+sin gh
+sat an
+ðŁĩ ¸
+ce ments
+in form
+gener ated
+bi den
+av g
+tas ks
+de er
+sa u
+ja iled
+pa stel
+sc c
+na il
+steel e
+per is
+lamborgh ini
+pur sue
+mar gin
+u ch
+bo sch
+dra in
+cl ara
+bo m
+lat ino
+web ster
+rose mary
+r ha
+s oun
+billion aire
+not ch
+percent age
+con or
+' "
+hom es
+earth day
+h ort
+big gest
+di sin
+wal ton
+edit ors
+im ma
+om ar
+equi valent
+pharmac eu
+ah med
+cam eo
+han ni
+under rated
+ge ment
+micro bi
+v oo
+honor able
+obe sity
+âļ ¡ï¸ı
+limer ick
+invol vement
+st agram
+boule vard
+bur g
+blackand white
+liber ation
+fi ve
+inter im
+sm m
+rival ry
+cap abilities
+stat ements
+thu mb
+ve d
+sw ans
+bar ber
+e que
+seren a
+hel m
+noo dle
+sam pling
+n awaz
+sing le
+thunder storms
+sh on
+in ev
+ë ¯
+to pp
+orch ard
+bi an
+ðŁĺ Ķ
+door step
+salv ation
+marke ting
+r ons
+cle mson
+ra vi
+in take
+stand with
+sin a
+ha iku
+ple y
+elector al
+ph illy
+la ys
+electr ic
+cap turing
+u pp
+er gy
+believ ing
+cul tures
+es day
+inva sive
+ed ed
+spee ch
+end ur
+viet nam
+boy cott
+pe de
+deli ver
+ðŁĴĸ ðŁĴĸ
+mer chant
+st ir
+den ies
+poc kets
+o ti
+cu ddle
+ro land
+mm ed
+den ed
+lear ners
+hoo p
+sour cing
+h acked
+di m
+environ ments
+ben son
+jud icial
+wor cester
+pear ls
+govern ments
+arri vals
+cor ners
+tun ing
+la bour
+y m
+or dering
+le wi
+i fe
+hygi ene
+thou ghtful
+indone sian
+campaig ning
+princi ple
+assau l
+ru bb
+at v
+wil ly
+en tre
+il i
+ph on
+du ties
+âĻ¥ âĻ¥
+sn akes
+lo op
+am ar
+conver tible
+bon ding
+ment oring
+max well
+ethere um
+destro ying
+ax is
+ca iro
+fin nish
+sho ck
+ðŁĺ IJ
+cal eb
+com a
+pe dal
+co re
+contin ent
+el son
+temp o
+helsin ki
+ac p
+tack ling
+st ated
+bl a
+dou b
+sma shing
+a ja
+camer on
+disru ption
+warm th
+being salmankhan
+bullet in
+o de
+syrac use
+ar an
+mc gregor
+bul k
+an ton
+confir mation
+sp ine
+im ran
+instru c
+jac ks
+chi o
+pal m
+str e
+embarra ssing
+un t
+elimin ate
+to ss
+c ise
+a ws
+oni sts
+sh inee
+jo s
+ho se
+li vely
+opp onents
+mo vements
+recogni zing
+sandwich es
+sh akes
+exerc ises
+se at
+profe ssion
+merry christmas
+lu gg
+adopt dont
+mar vin
+byr ne
+un le
+he t
+ku wait
+rah man
+aspe ct
+humb led
+gen es
+f and
+long time
+) ;
+cam pu
+an gus
+ðŁijį ðŁı¼
+q uran
+sle eves
+s lic
+¸ ë
+twel ve
+your e
+i ke
+go gh
+b st
+dic tionary
+reflec ting
+to on
+yar n
+em bed
+ðŁı ´
+re serves
+floo ded
+ver iz
+du sk
+estab lish
+pro li
+au d
+ritu al
+or bit
+declar ation
+recor dings
+cam o
+cas sette
+good luck
+cu tter
+bo p
+b ho
+che ating
+paci fic
+ma res
+tim er
+col t
+tr ous
+tomor row
+han sen
+ci e
+w ang
+ban i
+circu lar
+ac ute
+far mer
+co ys
+p se
+ir ving
+w j
+haw kins
+b ison
+ur day
+cru ising
+o te
+k ath
+whi stle
+your selves
+ant is
+sla sh
+thorough ly
+ke sh
+ser ie
+ex em
+en ig
+guil d
+sh red
+ho gan
+ap o
+ä ¸
+pu zz
+ne tball
+au ssi
+panor ama
+ws j
+av is
+ar ming
+hum ph
+brow ser
+cri es
+fo ggy
+mat te
+ðŁĮ »
+it er
+tal lest
+by ron
+cap tiv
+je su
+any ways
+flag ship
+p ton
+we y
+fay ette
+financi al
+f oul
+solom on
+jenni fer
+cucu mber
+ar gue
+tex tile
+wrest ler
+john ston
+pa stor
+ðŁĺŃðŁĺŃ ðŁĺŃðŁĺŃ
+cac tus
+edi ble
+re served
+ric hie
+met res
+ingredi ent
+h ella
+un to
+ch ol
+cele bs
+po ets
+gra ham
+hay den
+coinci dence
+b aw
+communic ate
+flet cher
+/ -
+tole do
+ecu ador
+coun sel
+s laughter
+line ar
+at p
+os u
+jo el
+ev ed
+conqu er
+ru stic
+plic ity
+recogn ise
+room mate
+cr acked
+jas per
+ph er
+ðŁĮ º
+wo ven
+mo ist
+ff c
+ste ering
+ni sh
+stand ings
+frequ ent
+ar di
+haz el
+as msg
+bau m
+d art
+si dd
+nat h
+ch ero
+card board
+c ss
+n sfw
+pa ir
+ðŁĺį ðŁĺĺ
+occur red
+homeless ness
+mal one
+ph e
+xi a
+pad dy
+decl are
+theat re
+b f
+per sian
+ta d
+ax e
+susp icious
+lam b
+mu cho
+sen ior
+st as
+k ite
+st ing
+gra d
+k af
+wat ering
+Ø ¯
+spi ral
+th ms
+educ ator
+jer ome
+of c
+clo ck
+su l
+pe mb
+.... .....
+park way
+de aux
+restric tions
+m ons
+need le
+e j
+le agues
+water melon
+am an
+pl enary
+max im
+w ab
+coming soon
+bry ce
+vi gil
+super market
+fortun ate
+turquo ise
+presi dent
+li v
+inter ns
+feel in
+fix tures
+stun t
+st aged
+premi eres
+lo k
+prac titi
+shor tage
+log ne
+ve c
+con cor
+roc ke
+li g
+com posed
+syn thetic
+di p
+cam ila
+ch is
+j ou
+su san
+eye brows
+supp lement
+satis faction
+moham mad
+ti bet
+house of
+pu n
+as sam
+shado whun
+psy ched
+se duc
+mand atory
+her bert
+sc allo
+stream ers
+proto col
+block buster
+produc es
+sch nei
+lau rel
+tri be
+time hop
+pl a
+mod elling
+tv time
+mtv stars
+wi dow
+me tric
+ch am
+con do
+flow ering
+ale c
+d ms
+inten sity
+Â ¨
+mccar tney
+islam abad
+k b
+f fi
+ph al
+anal og
+f ond
+h acks
+positi vity
+treat y
+sub marine
+conne ct
+sel en
+categor ies
+cu b
+organi ze
+si k
+quote oftheday
+remin ding
+am or
+loc king
+ðŁijı ðŁı¼
+comp ound
+et te
+b out
+rec ur
+fe rence
+mi zz
+tren d
+hip ster
+for tress
+forth coming
+preli min
+o dyssey
+ang p
+del ici
+even ings
+ðŁĶ ¹
+i q
+d w
+da ir
+kathr yn
+christian ity
+moon light
+ha b
+wh oo
+f bf
+se th
+genu inely
+pa x
+char ity
+deplo yed
+b nb
+bu cs
+ju dg
+con ge
+plant ation
+im press
+car a
+sc lub
+sco py
+land ers
+compla ints
+b ama
+re build
+x y
+real ism
+sh our
+le in
+brac elets
+mer a
+assas sin
+an chor
+ðŁijĮ ðŁı¼
+lin en
+con fron
+chronic le
+comm ent
+cat alog
+il les
+gor ge
+me try
+jung kook
+love my
+sent in
+se em
+fit ness
+alli ed
+ts man
+digital transformation
+pr an
+lo ft
+min ton
+alden richards
+en vel
+cher ish
+certain ty
+zz z
+rhin o
+per kins
+en rich
+cape town
+ome ter
+sec tions
+ske leton
+def enders
+ðŁĺ Ŀ
+pen c
+bri t
+ja h
+capital ism
+ðŁ¥ ĩ
+baz aar
+re me
+ex t
+kk k
+conver t
+stor my
+b ye
+kar an
+chry sler
+ad os
+pre ssed
+syn c
+ation day
+dang er
+bad ges
+refu ses
+em powering
+ly m
+ex ports
+adoptdont shop
+ðŁĩ ¯
+th c
+awa ited
+focu ses
+fin ed
+o at
+haha hah
+âģ ©
+n family
+fi ona
+luck ily
+thr illing
+ty ping
+out break
+di es
+he u
+craw l
+ne sses
+o ath
+scri pts
+gee ks
+ðŁIJ Ŀ
+p b
+mathemat ics
+al is
+________ ________
+gymna stics
+acti vism
+recommend ation
+gre n
+wa in
+cour ty
+n apol
+cau li
+hor nets
+g als
+jo ckey
+dir ty
+at ar
+enor mous
+pe st
+greg ation
+an os
+ii ii
+def ends
+black historymonth
+at x
+mb c
+lugg age
+wit ch
+co b
+la sts
+cu m
+gg g
+ba thing
+n ar
+ce bu
+ðŁį ĥ
+navig ation
+min e
+re jo
+ðŁİ Ģ
+gif tide
+re ta
+use less
+pu ll
+defic it
+al lu
+ati me
+it v
+tr illion
+pu e
+ac ies
+proce dure
+l ori
+jen ny
+c ad
+ul ously
+dr ac
+promo tes
+ing the
+can u
+woo hoo
+na omi
+zar dari
+ts u
+be ir
+sd g
+le ver
+we ber
+ab ud
+lun d
+crow ded
+deplo yment
+ter rain
+ken ny
+ho f
+witne ssed
+lo ch
+j k
+bul ly
+w ren
+poe try
+do ff
+ww i
+mo red
+din i
+cul ture
+promp t
+Â ¥
+maur ice
+to pps
+r m
+cor respon
+ab out
+jewel s
+gi br
+eag le
+ðŁĺĺ ðŁĺĺðŁĺĺ
+l ending
+sou ven
+ç Ķ
+contemporary art
+establi shment
+j ong
+â̦ "
+gat or
+patri otic
+mc coy
+v ape
+human e
+feli z
+coach ella
+re posting
+ste als
+fu ller
+n ering
+at ra
+( -
+bla ke
+he ather
+wor ms
+discipl inary
+rede mption
+y ard
+am in
+" @_
+d nc
+t ds
+k appa
+ne wark
+comm its
+spe ars
+j ams
+t and
+msn bc
+inter medi
+aim ed
+at ic
+teen th
+observ ation
+kash mir
+kavan augh
+ou l
+san francisco
+re u
+bel ated
+cho w
+pass word
+st ills
+deta ined
+sar i
+day ton
+dar ren
+itali an
+ar th
+amu sic
+ar bit
+w m
+v m
+he m
+dou g
+my r
+a sho
+pre v
+vin d
+bra h
+sta g
+ภµ
+pre views
+gu k
+con taining
+leon ardo
+sad dle
+ru shing
+st av
+lon gh
+gam bling
+ve gas
+reserv ation
+end ale
+bal a
+fl a
+vari ant
+he dge
+bulgar ia
+nat ali
+we aver
+sol st
+encoura ged
+ap c
+as parag
+ne st
+cycli sts
+fe l
+ìĬ ¤
+overwhel ming
+pey ton
+j it
+a post
+mb le
+ble eding
+neighbour hood
+a very
+expre ssions
+mac donald
+gi gs
+mon ds
+illu sion
+n ct
+cam ero
+over head
+my th
+ol y
+vi o
+et v
+lau rie
+unve iling
+pri or
+con n
+iron man
+di ff
+day in
+crit ici
+con go
+re vision
+wal e
+direc tor
+p ines
+black pink
+gar ner
+cur ated
+manit oba
+h ac
+common ly
+bar ton
+.... #
+mor tality
+live smatter
+philos op
+shor ter
+con vince
+fre ak
+vend ors
+insi ghtful
+el ly
+sens ors
+e led
+s berg
+weight loss
+u kip
+sp ur
+priv ate
+qu a
+ss c
+, ...
+supervis or
+advis er
+amaz ingly
+less er
+at es
+mah on
+oooo oo
+sar as
+pmo india
+waff le
+un ders
+toler ance
+sculp tures
+her sh
+kno cking
+smo ke
+cathol ic
+gri m
+tra veled
+fli p
+ge off
+dinosa urs
+sle pt
+scar let
+ok i
+compla int
+ob sc
+nam i
+la g
+cross fit
+u fc
+mc cain
+refe ree
+sad ness
+pen ny
+li eu
+mo de
+ki er
+vol s
+w is
+el on
+she a
+ba o
+son ia
+cla ire
+em manuel
+moist ure
+di gest
+vi ii
+t eller
+ch on
+access ory
+night club
+foss il
+aw an
+hu sky
+ab original
+brand on
+ffici ent
+cou gars
+ste d
+ad mitted
+igno red
+content marketing
+ag as
+v ase
+execu ted
+negoti ations
+she ad
+n and
+tab lets
+go th
+ts al
+d fw
+on ep
+protec tor
+sp ho
+gaz ette
+andre as
+ss er
+comp ilation
+ha v
+contain ers
+bro ker
+soc al
+porcel ain
+hy uk
+air ing
+ðŁĴ °
+publi sher
+scen ario
+spart ans
+re viewing
+itu des
+ed el
+pear son
+ba sh
+mau i
+a ad
+ðŁĮ Ĭ
+li u
+ul ate
+program mes
+fav our
+web design
+real ty
+motiv ational
+cro sses
+' ...
+bus ch
+adjust able
+ar jun
+mist ak
+dimen sion
+pi stol
+weigh s
+en y
+unve il
+indy car
+gor don
+f ade
+fran ken
+qual ities
+bet t
+loc ate
+ker r
+sp c
+confu sion
+ne e
+luck y
+bas es
+dep ends
+fire fighter
+ol a
+re t
+mar oon
+ðŁĶ Ĭ
+w am
+defin ing
+whe at
+bi l
+é s
+b hai
+psy ch
+ta u
+ic ans
+thi k
+ob ile
+inspec tor
+ìĨ Įë
+ill on
+go s
+ev angel
+fa i
+si st
+voc ation
+bur ge
+chi stan
+renew ed
+enthusi asm
+en ting
+ag ri
+ike a
+m sc
+aero space
+sens iti
+memo ir
+hosp ice
+co caine
+der ry
+mechan ics
+Ħ à¸
+tin o
+reduc es
+collec tors
+in justice
+supp re
+v ana
+ab un
+nap a
+su sa
+os lo
+e ff
+en core
+lic ence
+ched dar
+z al
+moun t
+ðŁĴ IJ
+threat ens
+!! "
+archi e
+fu tsal
+scu ba
+jo s
+gn on
+se xi
+s official
+compar ing
+domin ant
+tof theday
+fa it
+propos als
+gi ft
+y as
+cn c
+l r
+ha b
+reser voir
+beli efs
+gener al
+mar ti
+t d
+est e
+ì ł
+wi l
+ðŁij ¯
+ðŁĶ «
+sp x
+et work
+excer pt
+e instein
+hir o
+sil hou
+team ed
+per ception
+corri dor
+mental health
+hin ts
+ben ny
+induc ted
+sw x
+wi desp
+spe ak
+cher yl
+dru g
+ðŁĺ ķ
+h f
+asparag us
+myster ies
+fitz gerald
+off er
+therap ist
+care er
+dam aging
+ts d
+per u
+wei bo
+y ay
+phoeni x
+disc re
+mac book
+bar ker
+stig ma
+sp read
+roc kies
+kang ar
+bri dg
+pa i
+bi shop
+ta iled
+capsu le
+ðŁĴ ĵ
+ge of
+roy ale
+short listed
+o ste
+ash amed
+ch app
+key e
+cl a
+screen shot
+austri an
+nati ve
+en ight
+juli et
+michel e
+ðŁĮ ´
+travel ers
+pi l
+football er
+win chester
+ðŁĻ Ħ
+azer bai
+gold eng
+organis ations
+interpre tation
+predat or
+ofthe week
+lo gan
+pok é
+mari e
+cal la
+t nt
+cin de
+ge tic
+fit fam
+gra v
+ow ens
+ðŁĮ ±
+shoot out
+sal is
+commissi ons
+co he
+p tic
+ni xon
+hi a
+amb ition
+mar ine
+cruel ty
+t k
+cru de
+sal ty
+jim a
+mon go
+ir ony
+on wards
+arre sts
+strang ers
+ig er
+cycli st
+ra g
+exten ds
+tra dio
+bour g
+mo i
+el la
+e able
+lex us
+au l
+der a
+histor ian
+mor ton
+ti ff
+man ner
+ko t
+d k
+po inted
+mar qu
+a an
+en ey
+du blin
+on poli
+em ili
+secre t
+fl o
+âļ ¡
+ba j
+ste ep
+accompan ied
+rum ours
+dev i
+purch asing
+fi g
+pu b
+sch oo
+autonom ous
+go alie
+x ia
+autom atically
+re vers
+ter o
+fu ku
+titan ic
+shoo k
+sand als
+see kers
+exc av
+nor dic
+bigo live
+ba ke
+r att
+z ak
+ne p
+ðŁĺ ¤
+cand y
+billi ons
+book worm
+pp et
+à ³
+sur faces
+sc ars
+phil ip
+do gg
+ci gars
+co te
+transl ated
+cur ator
+sin dh
+han gover
+bre wer
+on es
+el ton
+ðŁĴª ðŁı¼
+mar cu
+elli ot
+righ te
+di oce
+ru ss
+rail ways
+grand son
+as cen
+apo logy
+awa it
+mob ili
+re spir
+parti san
+oli vi
+stri ke
+yo o
+white house
+expre ssed
+pu ps
+bed ford
+cul tur
+fro gs
+fly ing
+cav ali
+c ds
+fri ger
+street photography
+re solve
+tali ban
+kan g
+cru shing
+ju m
+ðŁĺ Ĵ
+william son
+tan g
+cur ly
+t man
+veter an
+fa ire
+artificial intelligence
+un anim
+pre n
+back drop
+fr ances
+oc cer
+doro thy
+work ing
+ar thr
+conver ted
+day light
+serv ant
+pad dle
+compla ining
+thir ty
+nad al
+ak u
+ibra him
+ad dressed
+p iss
+green house
+batt alion
+si mulator
+out lets
+embroi dery
+ðŁĵ ±
+fis cal
+ger ard
+sas sy
+ðŁİī ðŁİīðŁİī
+vent ures
+mer it
+public ity
+ðŁij Ī
+sophistic ated
+c tu
+conven tional
+condol ences
+isra el
+tra dition
+ar an
+te ss
+gla d
+ðŁĺĬ ðŁĺĬ
+correc tion
+ge on
+am d
+or ship
+be ast
+ch ment
+ì ŀ
+nic o
+wk nd
+wel s
+cushi on
+beli e
+vo c
+idio ts
+under neath
+pu ma
+corn ell
+en ation
+lu l
+swa ch
+ab ig
+u rer
+mi e
+form erly
+ca f
+er nal
+chor us
+juli us
+sen ator
+âľ į
+wh ir
+salv ador
+ph d
+uni fied
+boo ster
+graph ical
+w rec
+son ny
+mi z
+dere rs
+s all
+ven s
+tusc any
+wi d
+y ong
+kur ds
+w az
+trol ls
+mac ro
+cat urday
+pre ssing
+sa sha
+cent ennial
+gu sts
+em c
+be fore
+den ise
+cu st
+ðŁĵ ¢
+lo oo
+base l
+eng land
+y olo
+ar du
+manife sto
+do ha
+ì ľ
+kni ves
+bourne mouth
+bi bl
+bar b
+al icia
+Ø ©
+com er
+cycl one
+g it
+ane ws
+character i
+vent ura
+in tra
+sf giants
+hu t
+be a
+dar win
+ell er
+al v
+re ese
+bl y
+kar an
+conclu sion
+man ny
+fla kes
+unite blue
+nad u
+co pp
+ed ges
+lanca shire
+i als
+o tta
+philipp e
+l ent
+che e
+ment ors
+festi val
+an ism
+compli mentary
+r j
+pu g
+d ine
+we i
+cli ffs
+sar my
+ti veness
+treas ury
+il and
+after math
+rabb i
+ou n
+bou quet
+herit age
+zi on
+sur render
+shen an
+in ks
+kar l
+gh ty
+pol icing
+exam ination
+ce y
+per su
+measure ment
+hydro gen
+lu han
+âłĢâłĢ âłĢâłĢ
+war i
+о Ð
+j y
+fow ler
+mis h
+al fre
+âĺ ij
+bb naija
+cat alogue
+recogn ised
+sa ver
+hu skies
+col in
+mun do
+si va
+p ng
+discoun ted
+man utd
+fre sno
+de vin
+prelimin ary
+tro phies
+pla stics
+du g
+pro cu
+indi go
+g ard
+dy lan
+pit ches
+ground breaking
+in son
+bl ac
+an thology
+f h
+expl ic
+r ard
+admi ral
+so chi
+la shes
+splen did
+en vy
+ad v
+sex y
+festiv ities
+stic king
+bi b
+thr ill
+op p
+ari el
+botan ical
+endur ance
+fe males
+br icks
+vat ican
+black pool
+ber mu
+br ough
+roll er
+bi d
+sue de
+sloven ia
+mm ing
+ml b
+med alist
+di ans
+rehabil itation
+ne on
+s go
+li thu
+ram os
+z ed
+pi anist
+inten sive
+broad band
+stu dy
+peter sburg
+lu ca
+ah hhh
+phys ician
+dill on
+tele com
+gri ef
+mu n
+ac ro
+si ded
+s ly
+blo ws
+classic cars
+tri um
+ar gy
+? :
+h ri
+marsh mal
+âĢ ĵ
+to pping
+war saw
+tran sc
+preserv ation
+b av
+re friger
+experim ents
+ä º
+gl it
+sli ga
+g age
+fac tor
+flav ours
+br ony
+sp o
+cook book
+carri age
+aw ay
+ny fw
+on ian
+w g
+simp sons
+ro lex
+ðŁı ¿
+cro sby
+ãħ ¤
+cre di
+syn dic
+pu bs
+ali fe
+poor ly
+mac ed
+ðŁĺ ŀ
+behin dthe
+w enger
+n ats
+ðŁİ Ł
+rubb ish
+procedu res
+typho on
+opho bia
+er do
+fu el
+vi era
+bu mps
+millenni um
+new zealand
+lec tures
+it on
+mil ky
+respon ded
+ê °
+landsc ape
+.. @
+bo ther
+âĸ ¶
+z hang
+huawe i
+tu ition
+s worn
+in u
+y or
+pa olo
+au ditions
+ab il
+malay sian
+ho ps
+fe athers
+mp le
+au ts
+ã o
+boun ty
+ic he
+ì ĺ
+sh q
+pin ot
+ge ars
+disapp ear
+video games
+t na
+alzheim er
+ðŁĮ ŀ
+a ji
+under wear
+swit ching
+sign age
+o scar
+ec on
+dro w
+cl int
+pl ated
+gun dy
+emb lem
+ho es
+ici st
+nel ly
+juni or
+road show
+miner als
+at le
+alexand ria
+ac claimed
+v ell
+shi va
+ad he
+en ne
+amne sty
+h ounds
+councill or
+ðŁĴ ¦
+aes the
+part nering
+influ enced
+mag no
+fl are
+extin ction
+civil ian
+maje sty
+va il
+law makers
+rac ks
+mc c
+ori an
+sp ices
+er rors
+may er
+co ca
+pa i
+s ooooo
+reti ring
+ba thro
+ðŁĻĮ ðŁĻĮ
+âĸ ª
+su f
+endor sement
+buil ding
+broo ch
+pal la
+arvin d
+ag ent
+kar ate
+r hi
+c tv
+ta ine
+um m
+ba x
+reig ns
+uni of
+enterpri ses
+adel e
+fla ke
+at tire
+bru ce
+ba hamas
+gra vy
+sa in
+che ek
+tri vi
+lo v
+e en
+bb lo
+lady gaga
+itt a
+. "-
+du stin
+observ atory
+eigh th
+bloom berg
+kh s
+f cc
+gi st
+commemor ate
+ve er
+sexu ality
+ed c
+nic ole
+vac ancy
+u ser
+son a
+:' (
+dipl oma
+t end
+up grades
+Å Ł
+jura ssic
+cardi ac
+dr s
+widesp read
+Ã ł
+dail ies
+vend or
+sim plicity
+wi der
+len ses
+supp lements
+de pos
+ob served
+vin es
+parti ally
+renew al
+collabor ate
+ali g
+fin ity
+ph u
+zz y
+pe tit
+ðŁĵ ħ
+z in
+i gu
+sm ack
+fall on
+ðŁĵ £
+back wards
+comp onent
+o so
+compati ble
+bin ding
+zur ich
+thom e
+w ounds
+ly ric
+fresh men
+sne aky
+fi bro
+di et
+emplo yer
+in sect
+h ated
+sch er
+raz or
+n sw
+boo ker
+califor ni
+av fc
+Â °
+preten ding
+pep si
+al is
+un titled
+k art
+grand parents
+e the
+o ck
+lux emb
+visu als
+small business
+abdul lah
+min ho
+su baru
+h ra
+reve aling
+heart breaking
+clar ity
+am g
+sl r
+** **
+âŀ ĸ
+recor d
+ici ary
+min ded
+ye h
+exce ssive
+knu ck
+icec ream
+tru th
+ev ic
+ta stic
+ant arc
+ren dering
+, ,
+mit t
+loren zo
+st patrick
+bound ary
+zi g
+vo cab
+osa ka
+fur n
+tu n
+gu l
+s ounding
+blo gger
+utter ly
+g af
+adv ancing
+l cd
+mar gin
+lifel ong
+solst ice
+sh ra
+wa its
+ple ar
+bre ach
+en ligh
+ad er
+itt le
+c ation
+ho on
+stu died
+?? ???
+k ash
+ev angeli
+ps l
+wei ghts
+met als
+ty res
+tur no
+wi e
+car b
+g ale
+se al
+sun ite
+am ic
+patter son
+á n
+eu ph
+up stairs
+quali fiers
+khali fa
+apple music
+ìĨĮë ħ
+vau ghan
+al ter
+cru iser
+mu a
+t ana
+kat rina
+id ols
+spo iled
+secre tly
+fi bre
+part nered
+um es
+gi ov
+com et
+screenshot saturday
+k eller
+fil tr
+fe t
+con way
+pe u
+bad minton
+gi d
+m ound
+don key
+bu ff
+lea ther
+lar gely
+bro ch
+int ments
+am use
+r k
+sto ve
+impac ted
+con t
+cr acks
+prison er
+bar i
+contrac tor
+ori oles
+domin ate
+pol ar
+am elia
+dr c
+ðŁijĮ ðŁijĮ
+vi st
+su arez
+injec tion
+blo oms
+ðŁļ¨ ðŁļ¨
+sti ff
+pay pal
+sno wing
+thur sdays
+goo se
+we dge
+educ ated
+weak ness
+de cker
+abud ha
+bree zy
+Û Į
+hope ful
+o bi
+rai der
+gh am
+de u
+se ve
+par tly
+fu t
+infu sed
+mer ri
+than e
+some time
+hu e
+me in
+cre dit
+sli ding
+ran de
+cher ry
+dead pool
+sh ol
+ar am
+under wood
+sky e
+distur bing
+m nt
+poli shed
+guardi ans
+ha dn
+pic asso
+ari us
+ak shay
+ir ri
+j h
+happ en
+la kh
+dal ton
+at the
+s well
+mar sha
+re h
+cour s
+j kt
+top us
+serv ice
+r ink
+hack ers
+dono van
+hor o
+tc m
+may hem
+cha se
+dev ops
+ken sing
+sc up
+sh ere
+quali fication
+c live
+ton g
+n ancy
+mar is
+der dale
+ber man
+cinde rella
+jol ly
+ci c
+loo t
+collecti bles
+hom icide
+g ge
+epide mic
+su ites
+mu ddy
+gi mme
+e rec
+- *
+tal la
+lis le
+embro ide
+ðŁĩ© ðŁĩª
+veriz on
+ve ctor
+be anie
+arti san
+ga in
+flo res
+vi gil
+u so
+ðŁĻı ðŁı½
+grin ding
+gh er
+air ports
+respon sive
+shaf t
+can cel
+ceremon ies
+e me
+at ari
+bru shes
+eag er
+bo hemi
+children s
+yan kee
+ma a
+suspen se
+mor an
+mac ar
+sun flower
+cre w
+vo id
+ke ar
+fashi oned
+jen nings
+sunday funday
+sub missions
+me ad
+her man
+wa i
+crit ically
+le um
+baek hyun
+for cing
+co bra
+ãģ ®
+acqu ire
+al k
+ge ology
+pri mar
+import antly
+ire z
+bunde sliga
+curi osity
+sen a
+stric t
+con soli
+win ters
+ven om
+chelten ham
+ðŁį º
+cen a
+t at
+ba in
+glo ver
+under cover
+as ses
+car n
+memorial day
+am eli
+i rene
+ch on
+syn thesis
+spe edy
+mitsu bi
+sla yer
+compos ite
+under stands
+pe w
+inter rup
+hen ri
+mor row
+an om
+thof july
+g lee
+thre e
+ðŁĺ ®
+and hi
+ch att
+renew ables
+ye s
+trans fers
+!!!! !!!!
+bab u
+du ter
+lo ops
+pe ers
+o ilers
+pau lo
+ic ation
+h mu
+war a
+mer cer
+hom eland
+fu ji
+ale y
+year book
+re m
+re en
+ab sur
+bo is
+] :
+caes ar
+shot gun
+kur dish
+o ren
+ra e
+anci es
+ty pic
+f h
+def ault
+re plic
+lu k
+trans actions
+r ys
+infan try
+ðŁį ¾
+cho w
+chick ens
+ba gh
+wy att
+ay e
+gg i
+bre ws
+ed itions
+mi ra
+commen cement
+pre su
+peris cope
+ic hi
+guatem ala
+zam bia
+pain ts
+wit ches
+wan i
+un dere
+cro y
+vo ws
+us mc
+hear ted
+theat res
+shu ffle
+le vel
+mul tic
+squee ze
+fer n
+app et
+post al
+mal t
+on board
+ld nt
+co o
+s sc
+k ac
+ðŁĺ ĩ
+sc rap
+mar cos
+deal ers
+ann u
+mill er
+co ve
+ul ary
+vladi mir
+be ef
+th ur
+pick led
+se same
+bengal uru
+mo tt
+kathle en
+hi st
+no tor
+dr ank
+du chess
+snow fall
+e ff
+tin y
+j n
+sy our
+speci alists
+scot us
+bay lor
+eve rest
+mali bu
+pre m
+harm ful
+l ali
+b ates
+g ye
+differen ti
+and ra
+geome try
+el over
+black out
+== ==
+ko ta
+inter act
+asi an
+la yo
+samu rai
+fi del
+exhau sted
+gla di
+pd t
+spher ic
+anti qu
+guit ar
+stu ri
+ho pper
+ang le
+f ills
+sla p
+mi th
+rod ney
+ong i
+in som
+pre venting
+cassi dy
+ap ho
+ore gon
+lo in
+ham mond
+contribu ting
+f n
+gar ri
+ori on
+comp elling
+escap ing
+aim ing
+plu mb
+bi stro
+be asts
+concer ning
+bo e
+do pp
+shop local
+stumb led
+âĤ ¹
+naz is
+âĢįâĻĤ ï¸ı
+gest ure
+war ts
+us open
+hi ggins
+char li
+hang s
+bom bers
+° :
+fe eds
+c ch
+st il
+nic ola
+ðŁĵ º
+clam ation
+tro pic
+af ro
+ou k
+expen ses
+der rick
+al ine
+fa w
+reg ard
+im er
+sat in
+thi um
+ry der
+pear l
+te ss
+mm mmm
+sen ses
+ðŁĩ ¹
+positi ve
+exhau st
+occu r
+nor ris
+lil ly
+is les
+direc ting
+yo fficial
+count less
+sam ar
+on stage
+flo ck
+mir rors
+arch er
+mo i
+k d
+vi v
+in os
+si kh
+le i
+sen sory
+br its
+kno x
+chest nut
+op y
+coli seum
+z af
+di vin
+adap ter
+:) ))
+tem ple
+ku n
+hel mets
+t df
+gu ide
+m old
+o ids
+lu ther
+he is
+monaster y
+sp ree
+k lu
+brit ney
+jagu ars
+gre ats
+c cc
+ky rie
+machin ery
+cric ket
+re ro
+ab o
+aspir ing
+semi finals
+ale ss
+sig natures
+var d
+me th
+her bal
+hol den
+king dom
+ap or
+reg gie
+ore o
+palestin ians
+em mys
+sec tional
+ro i
+ney mar
+qu el
+cu ll
+l ka
+haz el
+estim ate
+ul ties
+go w
+be a
+purch ases
+bel ts
+protec ts
+m é
+gue ssing
+bb o
+clau dia
+fr acking
+jon ny
+el k
+cel tic
+al mighty
+ra je
+courty ard
+ig i
+can es
+ðŁĴª ðŁı»
+bank rup
+le thal
+âľĮ ï¸ı
+graphic design
+vad er
+penc ils
+rough ly
+dan te
+m fg
+const ell
+cam el
+j b
+bloss oms
+en to
+balo chistan
+cine mato
+ill ard
+jer sey
+con sent
+dent ed
+con templ
+sch er
+hol i
+lou gh
+st our
+a yo
+begin ners
+cur b
+v hs
+a jax
+du ff
+av eng
+dom est
+commit ting
+ai red
+cha p
+hedge hog
+disappo inting
+freel ance
+in land
+char ms
+ðŁĺį âĿ¤ï¸ı
+ai sh
+m x
+buck le
+ti dal
+per mit
+bo ating
+ra cha
+kend rick
+b ello
+b hi
+ple a
+estim ates
+l b
+apo logies
+jay a
+bb l
+ast oni
+inter state
+main taining
+el bow
+mu p
+ep it
+ðŁĺ ¡
+viol ations
+def end
+be h
+sl c
+am ir
+pur i
+ti um
+fi fa
+blur ry
+scri m
+ðŁĻı ðŁı¾
+ma ple
+rel atives
+âĺ Ŀ
+cho c
+con nor
+⾨ ⾨
+whi sp
+list ings
+ma ze
+than king
+ri dd
+grass roots
+shi fting
+desper ately
+gor illa
+den i
+ju les
+stra th
+g ley
+ja in
+bu ick
+t anner
+ðŁĴ Ŀ
+ga e
+pri m
+it ors
+n ano
+separ ation
+armen ia
+bor deaux
+ðŁ ħ
+pj net
+bu rial
+e bon
+glo ss
+re new
+gri er
+spe eds
+comic books
+sym boli
+pur poses
+ãħł ãħł
+spati al
+no table
+ci on
+n ps
+ho ffman
+nor man
+rt g
+du sty
+situ ated
+tr an
+k fc
+em en
+nic kel
+hast ings
+sett ling
+gr it
+l ena
+w aw
+art s
+gu m
+ca regi
+le wis
+sapp hire
+rememb er
+embed ded
+t lc
+bl at
+serge ant
+el sa
+boot camp
+bow man
+photo graphic
+pill ars
+direction ers
+classi fied
+no is
+ve er
+barre ls
+wh oop
+ðŁĺ± ðŁĺ±
+fe male
+petro leum
+medi a
+e fc
+poké mon
+ठķ
+enthusi astic
+var un
+pro files
+pedi atric
+acci dents
+con rad
+jan g
+jo jo
+ac or
+ob server
+l f
+live stock
+for gi
+fo s
+el m
+an and
+go e
+c ere
+avoi ding
+gri t
+om an
+thank fully
+scat tered
+nick y
+cylin der
+chees y
+di ver
+mahe sh
+cav es
+ear liest
+qu inte
+subjec ts
+b end
+gul f
+vocali st
+glu e
+pat ches
+un stopp
+sny der
+demonstr ating
+pi o
+hor ns
+wic kets
+and the
+r ama
+yo on
+stra ight
+bed time
+or ang
+bul lets
+sa urus
+min ers
+inci dents
+! ...
+ðŁİ ¸
+ag ers
+hand les
+stat es
+in ity
+d ons
+incredi ble
+emin em
+avi v
+ru dy
+moz art
+folk lore
+appli ances
+mt l
+fre y
+di as
+hu a
+page ant
+stri ve
+im prison
+bul lish
+r ana
+al erts
+bb mas
+hy per
+derby shire
+re cre
+re dd
+debor ah
+cosmo s
+law son
+mel anie
+psy cho
+ho or
+doo dles
+sni per
+shad y
+man tle
+canadi an
+new year
+inter actions
+separ ated
+cor ds
+spiritu ality
+ap u
+it o
+p ct
+pel osi
+rebel lion
+se iz
+wor cester
+sec tors
+ul i
+san ta
+Ð µ
+ðŁĩªðŁĩ ¸
+bi ased
+class ical
+gam ma
+dee plear
+emer ge
+back er
+sur ance
+hand crafted
+ðŁİ ¥
+franc is
+mill an
+ic i
+cro wn
+wo w
+stri ped
+un fair
+relax ation
+³ ï¸ı
+embrac ing
+she alth
+pale o
+martin i
+dist illery
+wr ink
+or k
+na th
+hay ley
+cour thouse
+si ber
+sa di
+quiet ly
+mel t
+m sm
+me h
+smart phones
+rel ent
+pp ing
+war wick
+co logne
+gli a
+cot ton
+pro g
+lon e
+ip sw
+star ters
+expan ds
+u mp
+su ed
+ski pper
+infe ctions
+ing le
+Ã ¡
+cler k
+demonstr ate
+ac ar
+ðŁĺĤðŁĺĤ ðŁĺĤ
+ti bet
+bun s
+alo m
+demol ition
+ssi a
+g st
+[ ]
+so ar
+âĺ Ģ
+ðŁĺ ª
+ðŁĵ Ĭ
+dee pest
+beyon d
+are t
+att ends
+activ ated
+di mit
+âļª ï¸ı
+high lighted
+magaz ines
+rum or
+az za
+steph ens
+dol ph
+sho ckey
+mat s
+we av
+mel an
+serv ers
+tra um
+ku sh
+æ Ĺ
+bab ys
+pa z
+a al
+la use
+break ers
+canter bury
+ul ture
+mi ri
+euro s
+tane ous
+impre ssions
+du tch
+il d
+gh i
+pur due
+adequ ate
+l p
+sy ner
+ang ler
+du rable
+gal ore
+ro wn
+mg mt
+ðŁĵ Į
+lu cia
+âĺij ï¸ı
+zay n
+bor row
+. (
+north umber
+cru sh
+eng a
+su sh
+extra vag
+t out
+ma hal
+ali stic
+ther mo
+gall eries
+es se
+chi bi
+attrac tions
+lex ington
+legislat ure
+docu mented
+resi den
+brow nies
+w f
+st ool
+plan ets
+sho ppers
+conduc tor
+ms p
+tr icky
+fru ity
+end ra
+feel the
+whi pped
+hair style
+re fer
+oo k
+oc topus
+audi ences
+ku mar
+after no
+op tim
+c fl
+ni p
+gen i
+alpha bet
+ann ab
+lam in
+accep ts
+l ng
+ðŁĺ «
+t ine
+ac om
+cheer leaders
+t k
+gr on
+v g
+k ung
+ja x
+dha bi
+r ss
+mack enzie
+beir ut
+clean up
+gy psy
+st ell
+bur ger
+hurric anes
+educ ation
+st ina
+âĻ¡ âĻ¡
+unfortun ate
+jere mi
+bad ger
+at ers
+: â̦
+ter ra
+subli me
+stu d
+y mca
+mr u
+duter te
+bren nan
+bul b
+mel o
+yl on
+hack er
+c red
+gu d
+as an
+pad illa
+embroide red
+vietnam ese
+pione ers
+projec tion
+re boot
+id c
+an ey
+pri mer
+suff ers
+win ding
+p on
+sto day
+mor n
+u ch
+all in
+adid as
+eliza beth
+tu ck
+o graphy
+ðŁļ Ģ
+be g
+os borne
+ghet to
+r h
+cn n
+ir ma
+ma kin
+cab les
+mur ders
+oc ks
+inst a
+al as
+si k
+cu ff
+la re
+foo dies
+o vic
+at om
+geome tric
+em pathy
+ภµ
+cent enary
+newsp apers
+administr ative
+ðŁİ Ĭ
+sti ve
+contrac tors
+le tt
+tas mania
+awesom eness
+den sity
+ve en
+prince ton
+frequ ently
+re ject
+gh i
+modu lar
+ceram ics
+sh ag
+ki wi
+can vas
+sweat shirt
+an j
+ti mm
+napol i
+il er
+appe als
+hamil ton
+ma yo
+we ave
+arrang ed
+whar f
+occu py
+b vb
+as aki
+ot ter
+nor m
+vi es
+de tox
+tion al
+dere k
+id ad
+ad missions
+constitu ency
+u pper
+woo t
+allo y
+se ve
+lu b
+un comfortable
+ed win
+ab re
+d wight
+ar che
+virtu ally
+sp ol
+pri e
+ai i
+er r
+swit ch
+bar ack
+se ok
+cou l
+wn t
+pou l
+o live
+caffe ine
+cardi ff
+notor ious
+de mp
+ex cess
+bar r
+t ford
+a jay
+bump ed
+my thology
+shel ley
+fal con
+shakespe are
+must angs
+no ted
+bon e
+civil ization
+sy d
+par sons
+un official
+hy ped
+sp ends
+oppo sed
+v ings
+space x
+noti fication
+deci ding
+bio tech
+out si
+sal ah
+! .
+fe d
+ss y
+c ms
+bad gers
+cr o
+ela ine
+n ba
+dy our
+n ant
+honey moon
+climb ed
+conom y
+ath a
+m ell
+ne bula
+nature photography
+juli e
+bm x
+inve sted
+mon o
+lieu tenant
+wat kins
+techn ician
+o se
+ka e
+ì Ľ
+mc queen
+pre ach
+trav eller
+flexi bility
+ze bra
+reta iler
+p ant
+ben der
+brand t
+squ id
+war rant
+veri fied
+cas s
+pier cing
+hon ours
+t ying
+mor ris
+kis sed
+op rah
+panor amic
+me i
+splat oon
+wich ita
+ari as
+gal li
+indy ref
+good times
+athe ist
+confe ssion
+ow ski
+re pping
+ad ditions
+mechan ism
+z im
+j ans
+su f
+cho pped
+beg innings
+vitam ins
+ãħ¤ ãħ¤
+or th
+po les
+ru b
+antarc tica
+indie film
+web cam
+ket ch
+bre tt
+cle ment
+her on
+defe ating
+hydr o
+buc ket
+wand ering
+sid ney
+future of
+b inge
+on ies
+knock out
+administr ator
+syn the
+l ent
+jan i
+bar ley
+premier league
+ner ds
+cr m
+bra s
+bot any
+evol ved
+rot ter
+ro wed
+tum or
+weal thy
+Â Ń
+mon arch
+li shed
+da hl
+ðŁİ ĥ
+bu ch
+ken yan
+Ø §
+red ness
+assemb led
+se mit
+hud der
+shro p
+ran i
+lear ning
+mor y
+iti a
+geo graphic
+worl dof
+f b
+pho sp
+boo gie
+am ped
+? ...
+che w
+dwar f
+ar us
+s sen
+ru sty
+recru its
+h k
+gar de
+app lause
+vol umes
+invol ves
+ta c
+hand bag
+trans late
+ffe l
+se ym
+aqu atic
+trans fer
+zo di
+and r
+acade mia
+cr ater
+te z
+ar se
+adap t
+col oni
+snow man
+mal i
+hang in
+di schar
+oy sters
+pho e
+colon el
+w ba
+hispan ic
+thri ving
+sh y
+ag les
+sales force
+cre me
+so les
+la fayette
+â ī
+ter ia
+ach a
+sp erson
+go go
+car ly
+the ore
+am ore
+vo x
+af t
+ãĤ ¹
+stap le
+mu ffin
+di agram
+ino x
+su stained
+av ent
+me ta
+arbit r
+dec ay
+ado le
+Ð ½
+ec ol
+ph o
+n k
+o cu
+gr anny
+ç a
+luxemb our
+stad t
+alber to
+le vit
+am as
+d x
+or phan
+co bb
+as c
+lo gy
+immen se
+chan ts
+off line
+p ent
+bre x
+w inger
+plan e
+i el
+nichol s
+ca thy
+nar uto
+low ed
+/ //
+ignor ance
+cat astro
+you ts
+sch en
+buil d
+haz i
+s ine
+critical role
+du g
+dete ct
+lo gs
+en amel
+stpatrick sday
+ed die
+co pa
+cigare ttes
+ho ff
+kay a
+la goon
+ra pha
+air borne
+choo se
+puer tor
+ke v
+gui ding
+fro sty
+bor ough
+mir a
+ðŁİ Ĭ
+cade t
+anu sh
+yo gi
+e ger
+fl ing
+slo pe
+nin th
+we ston
+foot wear
+f n
+may weather
+a am
+pla in
+stair case
+witne sses
+work outs
+ro bust
+dex ter
+co hort
+ðŁļ Ĺ
+sp ell
+ha ze
+o om
+organ ising
+wild fire
+cont acts
+av on
+min o
+upd ating
+ðŁį »
+li thium
+ing ual
+k is
+au ga
+lo com
+de duc
+u da
+th ak
+boy le
+mp er
+hot tie
+eri k
+re vised
+is la
+travel photography
+oo za
+en qui
+confe rences
+clo ver
+g room
+cur ves
+live on
+per f
+displac ed
+bo log
+xx xx
+ðŁĺ© ðŁĺ©
+te al
+ve ssels
+rain forest
+cal ci
+pan ther
+gira ffe
+ta sted
+imag ery
+pad res
+day time
+bas s
+ri pe
+opio id
+nu e
+vin yl
+invent or
+sen s
+process or
+mu t
+gad gets
+bibl ical
+shann on
+jacqu eline
+car y
+the resistance
+ali en
+n vi
+co sy
+bi har
+fo ley
+ren d
+mu gs
+fa ken
+cl one
+ni allo
+gra bbed
+chi hu
+power house
+n tt
+chero kee
+spon ge
+imple menting
+rh ine
+le one
+ðŁį Ģ
+pret tiest
+infra red
+impro v
+swit ched
+tu bes
+con tr
+bl k
+projec ted
+be aver
+yo t
+bbcra dio
+thi gh
+per secu
+apologi ze
+w ack
+po ster
+oli ver
+az a
+lou d
+( ?)
+f the
+women shi
+spar row
+blu sh
+us able
+sc ales
+it ative
+peu ge
+ne eding
+legg ings
+glam orous
+mat ur
+c z
+wat t
+da b
+tam ar
+et sym
+bau er
+heart felt
+h n
+else where
+bir ch
+alu mini
+hu ck
+e me
+j l
+traf ford
+d z
+por tions
+ana sta
+arthr itis
+esp n
+ber gen
+viol ation
+yo shi
+c z
+northumber land
+clo sures
+ðŁĩ¯ ðŁĩ
+smi ley
+r w
+tel ugu
+inten si
+gre gg
+ve ga
+dun geon
+south bound
+ba il
+domin ican
+semi final
+chap ters
+h itch
+van ity
+trans iti
+recomm ends
+sati sf
+bar ca
+queen s
+( (
+de struc
+stra it
+ra vi
+dess erts
+in tru
+har am
+k os
+fo e
+fat ty
+pais ley
+magn itude
+dri dge
+com ey
+schem es
+vision ary
+our t
+down loaded
+ðŁĻĮ ðŁı½
+gd pr
+lan i
+p wc
+gu ad
+nic est
+stake holders
+re ferred
+george town
+arvind kejriwal
+schnei der
+in doors
+all star
+strand ed
+gen der
+ze pp
+ma sses
+ðŁIJ ±
+pati ently
+bl dg
+z ab
+we arab
+vi vid
+he ck
+d ella
+sy mb
+je opar
+la ger
+à ª
+comb ines
+ne c
+br ay
+flo p
+tx wx
+jo ys
+pon t
+pro found
+sur round
+mad hu
+ma ble
+ay r
+te as
+n sa
+open ly
+er nest
+ãĥ ©
+to po
+g na
+anti oxid
+ti an
+e tr
+c ello
+ma thi
+gener osity
+b iting
+man ic
+kel sey
+chee ks
+ten der
+w th
+pron oun
+ultimat ely
+gu sta
+ari anag
+ger ry
+ble ed
+red dy
+mic h
+mitsubi shi
+oper ated
+sex ually
+ma u
+cl lr
+vi ds
+co c
+mel ted
+ðŁĮ Ī
+q ld
+ite ch
+instru mental
+end game
+ðŁĵ ĸ
+ener gi
+brow nie
+tam il
+at in
+domin ated
+pra ises
+fire place
+sens ational
+men a
+k arti
+un prece
+ru pt
+ori ental
+mc cor
+tour naments
+scen ter
+re eves
+prescri ption
+sam e
+fra u
+tru ffle
+em bo
+roman s
+bla sts
+techno logical
+pr at
+b sb
+y ar
+tren dy
+ac l
+al ad
+ðŁį ģ
+o hh
+bankrup t
+tho ven
+regar ds
+is er
+war wick
+vine yards
+real m
+niallo fficial
+do ta
+ge mini
+to do
+v able
+¨ ¨
+la u
+wre ath
+ju ve
+nat asha
+le ver
+lor i
+hor ser
+cc tv
+air bnb
+es anders
+sin clair
+ema biggest
+high school
+con test
+optimi stic
+t te
+ðŁĴķ ðŁĴķ
+ss d
+ye e
+hel ena
+con sen
+ric ks
+jes se
+an ic
+ðŁİ ¯
+re acts
+ro be
+independ ence
+vol tage
+m ington
+s ant
+à¸Ļ à¸
+-------- --------
+sentin el
+ke tt
+rehear sing
+aaaa aaaa
+sof the
+stir ling
+sear ch
+wi gan
+stand out
+sna il
+pent agon
+Ä ģ
+ch lor
+cru st
+net any
+chemi st
+disapp eared
+ric ardo
+sp iders
+bo se
+war ren
+me ssing
+bann ers
+gu el
+par ach
+ma id
+coun ted
+epi le
+bon fire
+speech less
+se tter
+meas ured
+rejec ts
+nik ki
+le ster
+foren sic
+fab rics
+alo ha
+pre served
+wat ford
+deta iling
+dar th
+bo u
+car ly
+... '
+tail gate
+noti fications
+å ¤
+pas sive
+trous ers
+balo ch
+ro ther
+typic ally
+Ã ¥
+sp it
+wi z
+sic ily
+technic ally
+ex pose
+st age
+hu bb
+cre am
+cap s
+po ke
+sle ek
+ju ne
+tempor arily
+de z
+awak ens
+l ame
+_ -
+ji ha
+tues days
+advis ed
+advis ors
+exi sted
+dis agree
+news room
+lo sers
+world tour
+dr ying
+al di
+har ness
+foot print
+hobb it
+p mln
+i ro
+que red
+asse ss
+gaz e
+sa b
+th ian
+í Ĭ
+ti f
+ob serve
+ev il
+dra wer
+swee p
+cor y
+co dy
+kyo to
+cal lum
+n inj
+lau rent
+be i
+sket ching
+custom ized
+du r
+regre ts
+knox ville
+ìķ Ħ
+mess aging
+grac ie
+abun dance
+bi dding
+bre wed
+fl ouri
+therapeu tic
+alt itude
+ho gs
+bur ner
+elec tro
+wonder fully
+he ater
+post pon
+li very
+r all
+ad as
+a ac
+sau l
+brook lyn
+play house
+âĻ¥âĻ¥ âĻ¥
+char itable
+in y
+z ah
+compet itions
+be av
+plu gged
+o is
+do om
+astron om
+speci alized
+max i
+ta ps
+cellu lar
+depre ssed
+folklore thursday
+cri b
+e mul
+ë° ©
+fi gh
+ru z
+car lisle
+spe ar
+side walk
+de i
+depend ent
+lac es
+nh s
+ðŁĮ Ļ
+reali zing
+net work
+ric he
+re gin
+re fresh
+st ral
+pa thology
+pla id
+psyched elic
+hin d
+u ka
+algori thm
+lin king
+progre ssi
+fe y
+d ade
+hydr ated
+b ant
+fam ed
+cot sw
+bo ise
+as c
+rac ing
+ja vier
+ww en
+mar lins
+poo p
+swe pt
+toni ghts
+we f
+ani me
+slo vak
+âŀĸ âŀĸ
+cla us
+lem me
+cli ppers
+re ls
+arianag rande
+r te
+ko t
+thal apathy
+hungar ian
+zu ma
+y von
+is u
+jour neys
+clin ics
+be be
+ww f
+n ws
+super heroes
+er it
+sle ague
+identi fication
+mo tto
+ba i
+sour ced
+ill er
+ap i
+pri se
+unprece dented
+dam as
+tuni sia
+dra in
+undere stim
+e ther
+quarter ly
+rewar ding
+al ham
+wolver ine
+cab ine
+hyp no
+nad ine
+hav ana
+da e
+ðŁĵ Ī
+dr on
+read ings
+b ati
+pic o
+mer ci
+iti an
+wal kers
+el ope
+mi key
+god zilla
+bur lington
+abu ja
+social ism
+at ility
+sh ell
+harry potter
+g no
+ab ur
+re leg
+fel ici
+ro gen
+neuro science
+inst in
+ath am
+vou chers
+j arre
+fu se
+def ici
+monte rey
+de port
+mid day
+pp ard
+fre ed
+ame ter
+wil t
+n ingham
+pr att
+liber ty
+slo gan
+o to
+pr i
+co ated
+c pd
+ne tt
+il las
+mal awi
+evol ve
+accessi bility
+ðŁĶ¥ðŁĶ¥ ðŁĶ¥ðŁĶ¥
+or nament
+b p
+el is
+son line
+chi ro
+fl ick
+ib m
+ar ak
+en ables
+gar land
+san e
+cu ties
+tri p
+rotter dam
+n ys
+lam ps
+lu cas
+bo g
+ra ils
+travel led
+hic ks
+en u
+sab ha
+scru b
+hi er
+hart ford
+fo o
+fer nandez
+tre vor
+mat tress
+appo intments
+ale j
+fe i
+o logist
+saf ar
+oc ta
+sr c
+sha un
+ambi ent
+dri c
+bi ker
+she e
+must ache
+h ta
+bo one
+her ty
+car dio
+bra kes
+rec ital
+consi sts
+overwhel med
+cau l
+robb ins
+im it
+al th
+ur l
+bi bli
+on ne
+black livesmatter
+diffic ulties
+tel ang
+tall er
+ðŁĵ Ĩ
+deb ating
+bur rito
+mo vember
+strength ening
+bo e
+te stam
+mirac les
+base ball
+re nee
+ðŁijī ðŁı»
+al fa
+âĺ ĺ
+unstopp able
+ec s
+g mo
+giftide as
+path way
+fen cing
+ðŁİ ¤
+b ham
+ra s
+sk o
+d led
+thel ast
+magn um
+bin ary
+wil de
+wil der
+wh ati
+barbe cue
+h ism
+can oe
+kur di
+eli ve
+advant ages
+mad ame
+bi er
+mis sing
+enter tain
+air force
+y ama
+c is
+hash tags
+j is
+ve il
+dream y
+ten se
+may ward
+ch ateau
+hunt ington
+âļ ĵ
+v all
+up on
+bl ouse
+dun es
+ðŁĺ ´
+fert ility
+m ole
+curren cies
+st u
+ber lin
+toa sted
+div as
+wal t
+lar k
+por a
+hit ter
+um er
+chil led
+bal ancing
+fa is
+y in
+or tiz
+east enders
+h ate
+ur al
+ap ril
+tim el
+à ±
+per o
+sto cked
+respec ts
+th t
+best friends
+giving tuesday
+be ad
+inv ent
+im i
+nap les
+comb ining
+tok ens
+thir st
+ma sc
+par rot
+sp u
+dent on
+* -*
+t res
+subur ban
+wid th
+si ve
+con tender
+siri us
+lo k
+troop ers
+outra ge
+tur bo
+frag ile
+me ssed
+do h
+disc ord
+netany ahu
+re sign
+forgi veness
+mo han
+mun ch
+cam ou
+identi fying
+enab ling
+hot ter
+thorn ton
+jai pur
+ar ya
+ðŁı» âĢįâĻĢï¸ı
+mu staf
+maj ors
+o ke
+du ffy
+roh ing
+til t
+ðŁĩ®ðŁĩ ³
+rock star
+she ep
+hend rix
+ra v
+in vention
+do u
+lagun a
+gru mpy
+sw is
+im pe
+) '
+you ths
+bun ker
+st ache
+oppo se
+indi es
+acceler ate
+ml p
+ed en
+w ann
+k ail
+akshay kumar
+su pt
+pol ym
+midd leton
+extra ordin
+wil son
+australi an
+alumini um
+way ne
+alum nus
+mat ics
+gri m
+er nie
+opp a
+competit ors
+rand all
+h ence
+decla res
+pre aching
+sha he
+can e
+sustain able
+stap les
+le dge
+ad ena
+doctor al
+bur gundy
+decor ate
+ren dered
+ri sen
+pr ank
+di or
+bee thoven
+flo or
+ac com
+to t
+ho dg
+touri sm
+say in
+objec tive
+mar kers
+premi ership
+en abled
+camou fla
+gi ant
+Ñ ģ
+smo key
+ric ket
+pan g
+de pending
+s ation
+evol ving
+inter cep
+cen sus
+tof the
+re en
+mendo za
+trum pet
+marke ters
+an it
+ðŁĻ Ĭ
+north western
+v la
+foto gra
+blackand white
+che wan
+wi g
+tro om
+ginger bread
+k n
+ro mero
+n fc
+or chi
+fun ko
+sour ce
+f s
+ra ped
+o st
+tar ot
+ann ually
+ðŁĺ ¬
+r ill
+del av
+.. !!
+se s
+can n
+medic are
+ph el
+ape x
+guardi an
+rema ined
+r pm
+a ñ
+story month
+instag ood
+neighb our
+p ing
+sem ite
+my stic
+as cot
+mat er
+hand ful
+dang ers
+ti d
+ana heim
+opol y
+sh allow
+nami bia
+tor ia
+procu rement
+big bang
+announ cements
+prosecu tor
+beng als
+sal le
+en roll
+ga stro
+sugge stion
+ba k
+ha ul
+budd hism
+berni esanders
+flu te
+fati gue
+cyn thia
+cho i
+ir win
+gu a
+str ous
+h p
+ba p
+satisf ying
+play a
+ðŁİ ¼
+inst ap
+al ice
+t p
+irri gation
+ðŁĩ¬ðŁĩ §
+in tric
+clu es
+ple x
+sa x
+he pat
+dump ed
+signific ance
+by u
+medic ation
+pro v
+tough est
+corn ish
+âŀ ľ
+kel ley
+u v
+si zz
+si bling
+me st
+di stor
+diplom atic
+aun tie
+b hat
+son ic
+bren da
+pump kins
+ro ch
+black burn
+ur ged
+shi a
+arrange ments
+floo d
+sa unders
+lec turer
+nou ri
+popul ations
+diplom acy
+consist ently
+ðŁ¤ Ļ
+t mund
+cauli flower
+l ily
+vocab ulary
+vari eties
+coo ker
+up town
+qu ent
+mo sa
+re inde
+velo city
+spru ce
+social medi
+i ber
+volun tary
+proce ssed
+bal tic
+y ang
+leban ese
+d p
+dol ly
+arrange ment
+y uri
+cran berry
+kal yan
+elev ation
+cli ff
+pu shes
+ìĬ ¤
+sil ic
+co wx
+eter nity
+sla ves
+vine gar
+glou cester
+con tained
+breaking news
+aga inst
+renov ated
+norm andy
+hero in
+ys m
+mo ds
+gre ek
+un di
+tren ch
+v h
+encoura ges
+head ache
+gr ange
+: '
+ever green
+Ù Ĭ
+reck on
+ab used
+th ru
+cho ice
+ti dy
+col der
+scho ice
+ha in
+bru m
+li ars
+bre it
+yor ker
+sh ack
+he idi
+micha els
+sco pic
+fasci st
+play ful
+ca c
+yas ss
+sh ad
+.. ?
+qu en
+ram irez
+clif ton
+pr s
+best fan
+âģ ł
+gener ating
+head set
+disappo intment
+abstr act
+bo iled
+paren thood
+azerbai jan
+exhib iting
+bom bay
+oli vier
+ko so
+un lea
+mat ernity
+iz er
+si ves
+r hu
+col l
+saskat chewan
+fre akin
+de k
+na g
+stab ili
+ðŁį ķ
+organi zer
+bo sses
+ar u
+u va
+at able
+ta un
+after wards
+fert ili
+ver ge
+az i
+mor ph
+๠ģà¸
+jer k
+cosme tic
+ko w
+stru st
+ap ache
+post cards
+for mul
+ì ĭ
+spin al
+jack pot
+elec tri
+Ã Ń
+lo y
+gra der
+diab lo
+ar di
+he sit
+f w
+arch ery
+pa sh
+the ories
+repe al
+re live
+per cy
+âĺ Ĩ
+im in
+syn chron
+sham poo
+coup ons
+o to
+la i
+thou ght
+luxembour g
+mo v
+ðŁĺ ¥
+ge mma
+se ated
+m ga
+strat ford
+un certainty
+shi fts
+est o
+fo ol
+fire arms
+cor rie
+ki ki
+appa rent
+p ills
+olym pia
+fi d
+elev ated
+de cks
+ignor ing
+av alan
+ro v
+whist le
+p tsd
+milit ants
+robo tic
+pac ers
+quil t
+bankrupt cy
+lic h
+per cussion
+celebr ity
+al s
+( ;
+su t
+pokemon go
+h g
+off s
+gibr altar
+scre ams
+billi e
+gen ome
+mar in
+be ams
+arch bishop
+em in
+bedro oms
+g ated
+ol ly
+warran ty
+at own
+cudd les
+gun na
+k ic
+vi ve
+cy mru
+nar row
+pro b
+le o
+refe rences
+manufac tured
+cho pper
+brun swick
+sem is
+don ia
+r ye
+man o
+hur ting
+? #
+hol li
+investig ations
+c els
+ðŁĵ ŀ
+le ster
+temp les
+sto rey
+mc mahon
+toi lets
+wo of
+ï¸ İ
+le verage
+at om
+night mares
+victor ious
+haun ting
+custom er
+ag i
+yo ongi
+mon ty
+ver onica
+w ur
+inti mid
+blan kets
+volu tion
+j m
+âĺ İ
+am on
+jud ith
+ðŁĺİ ðŁĺİ
+distr acted
+dri p
+hurric ane
+and es
+revel ation
+tro op
+ab leg
+col lin
+tibet an
+wor rying
+inter nationally
+eat er
+camero on
+brad or
+y uk
+ðŁĴĹ ðŁĴĹ
+tra k
+slo pes
+ci er
+ne a
+ol er
+ta ka
+albi on
+volcan ic
+am n
+a fi
+ob stac
+face time
+ger ing
+n pr
+metall ica
+organ ic
+ðŁĴ ¡
+ki dd
+d ances
+pemb ro
+wash er
+m its
+om er
+emo tionally
+tan go
+ip o
+do cks
+scan ning
+spec s
+tho m
+the ology
+emer gen
+om i
+g pa
+selec tions
+un necessary
+ima ge
+ter s
+induc ed
+gi gan
+rent als
+supp lied
+m fa
+shan kar
+lat er
+pa jam
+cla ve
+Ù ģ
+ma hin
+carl son
+avi an
+ano va
+kati e
+aj ith
+design ated
+chocol ates
+investig ators
+gla zed
+prin cess
+er ry
+ra gn
+ou rable
+hr u
+sun dance
+peuge ot
+steam punk
+gh lin
+gre ase
+hi res
+z ap
+per ce
+j ill
+tom e
+he hehe
+joy ful
+mae stro
+ni shed
+gene alo
+v ich
+p its
+fox es
+good man
+emer son
+lo bes
+con verse
+o ats
+thom son
+ra him
+mal ware
+ah i
+man kind
+re sin
+im g
+sw ood
+kin der
+sc roll
+ar a
+sak ura
+ro bbed
+xi on
+ny a
+c ism
+ce dar
+be in
+mour ning
+tor to
+heath row
+done gal
+bar b
+hydr ation
+k or
+elim ination
+su pdates
+hill s
+appe ti
+star red
+ko m
+gw en
+dd d
+cra y
+sc anner
+personal ised
+seren ity
+re design
+meta ph
+box ed
+judg ment
+no se
+ë ¹
+er ad
+ac ne
+supp liers
+ener getic
+v om
+as ap
+ðŁĶ ¸
+ir vine
+hat ch
+la ss
+ad ren
+waff les
+accur ately
+ici o
+itt le
+se un
+occup y
+web cam
+thene w
+ent es
+ga i
+j w
+accoun table
+vis or
+ir rit
+licen sing
+hudder sfield
+gen ie
+ðŁİ ¾
+atmo spheric
+ten sions
+spart an
+clif ford
+ol an
+north bound
+ame en
+cen sor
+u el
+ster y
+$ $
+far rell
+hy ster
+cl t
+se dan
+rep lied
+descri bing
+micro wave
+sla b
+pro sp
+assi sting
+ru bio
+e than
+hh hhh
+gu ay
+z man
+ra ise
+roll ing
+o e
+n ile
+ambro se
+scar borough
+hero ic
+coo ks
+mor t
+chop ra
+ðŁĮ ·
+to b
+shav ing
+stac ey
+dor m
+motor sports
+wi ki
+fol ds
+sp iced
+stress ful
+liter al
+fu dge
+pe ggy
+wa ite
+tre sses
+se sh
+pr ic
+ðŁİ ħ
+fri ght
+r va
+mumb ai
+po m
+tt v
+cel lar
+tom e
+andro id
+dor is
+tsun ami
+tin der
+o ec
+m wc
+dor tmund
+no thin
+l iti
+so u
+believe in
+at u
+kno cks
+mag ni
+ss sss
+ro hit
+ine ws
+ang i
+m andy
+ke ttle
+intermedi ate
+av ant
+cur l
+endor sed
+ori o
+ur t
+consider ation
+wi res
+shel ters
+b ino
+vik ram
+imple mented
+ly dia
+bu k
+paro dy
+c news
+under graduate
+canu cks
+sam i
+polit ically
+ro tten
+gh z
+tex tiles
+over load
+moder ni
+recre ational
+fli r
+bat on
+typo graphy
+ov ation
+intrigu ing
+pilgri mage
+al ge
+ad ays
+tcm party
+sp elled
+cur ls
+boo ze
+ste m
+ann es
+ir ls
+spon ge
+sho pper
+sig nation
+bra ss
+mi stress
+le ah
+beg inner
+lau derdale
+augu st
+pre school
+ta ping
+tai pei
+execu tives
+b d
+rhe tor
+esc or
+immun o
+deeplear ning
+stat ues
+it us
+manu script
+ly ric
+cor vette
+mol ly
+la ge
+de p
+cn bc
+le st
+je ssi
+fi fe
+griff ith
+oppo sing
+ran g
+dr ills
+respec tful
+p ity
+d ell
+har ding
+play boy
+blo ke
+shut out
+k ili
+o sp
+se attle
+bc poli
+mis es
+journ als
+team ing
+es ther
+fre ddy
+Ķ ï¸ı
+metr ics
+no tre
+gar ry
+for ty
+navi gate
+perio ds
+bened ic
+j id
+da w
+ance stors
+restor ing
+con g
+aller gy
+tit anium
+c ence
+lean ing
+ab bas
+v ast
+uc f
+roof ing
+e man
+seve rely
+vo gue
+ve au
+in bound
+d z
+tane ously
+stret ching
+man chester
+dr yer
+dav is
+kan th
+the game
+it ted
+re tain
+el les
+conge stion
+frat ernity
+ol lie
+lo ki
+fre ely
+cho o
+pon y
+sc ep
+tab ly
+bal t
+rock n
+di me
+lo gging
+ðŁį ·
+ad u
+ha voc
+water ford
+char is
+swee tie
+run ning
+ner d
+erdo gan
+z ara
+weigh ing
+fif ty
+pre cise
+low ell
+kurdi stan
+r yo
+or th
+syn th
+lin ers
+phenomen on
+art illery
+il legally
+constru ct
+nostal gic
+gar th
+al ta
+shel ton
+a sean
+w ander
+dur ban
+di versi
+bon o
+cl on
+le man
+sh un
+obstac les
+appet ite
+fe eder
+respir atory
+di xie
+formu la
+an to
+so ber
+extin ct
+au c
+ing les
+legitim ate
+; ;
+min nie
+ipsw ich
+dram atically
+ðŁijı ðŁı¼
+ingh am
+milit ary
+mon et
+us navy
+for k
+dun no
+play er
+q otd
+st oo
+ex or
+ethiop ian
+film fest
+pe red
+c ate
+sau di
+in ner
+sin cere
+tion ality
+ale e
+de eds
+cooper ative
+ir onic
+cro cod
+br ary
+post season
+cam per
+can ary
+e in
+exten sions
+nb d
+sher wood
+spo kane
+hu mp
+jit su
+ê ¹
+dar yl
+p si
+stab bed
+offer ings
+expe cts
+cav al
+body building
+fr aming
+f ca
+ye arly
+bom bed
+sk il
+resear ching
+jud iciary
+gree ted
+tu dor
+mil o
+innov ate
+ðŁĺ Ľ
+r hs
+ru by
+contribu tor
+fam er
+soci ally
+m lin
+fi ery
+ut ter
+beau t
+it os
+de voted
+rain bow
+bar ney
+pe ren
+ar jun
+r na
+gab by
+ut i
+hann ity
+pick le
+ser v
+qu akes
+pp e
+fe m
+wh itec
+j n
+victor ies
+ðŁ§ ¡
+gol fer
+congratul ates
+resul ting
+mechan ic
+ur ve
+cen tered
+kie v
+an s
+in cub
+< <
+c mo
+bestfan army
+dap h
+en ham
+on cology
+ku sh
+t xt
+ori ented
+fashion able
+c sr
+sa hara
+r ack
+pd p
+han son
+ภĩ
+ti ers
+ra r
+pan am
+in sky
+sa hi
+testam ent
+asth ma
+in her
+fisher ies
+or der
+ho we
+gall on
+ep is
+suz anne
+drow ning
+paneli sts
+ðŁĺ ²
+ë ¦
+al ach
+commemor ative
+at tribu
+ðŁij »
+mo o
+visi onal
+week sary
+gu st
+ak in
+poin te
+ee e
+di spar
+ni pp
+dent al
+st all
+pi an
+bor e
+ul ster
+tic k
+ir r
+tae hyung
+micro phone
+bermu da
+ga ard
+el er
+plumb ing
+hu gely
+âļ« ï¸ı
+race way
+cam bridge
+mar cel
+burn ley
+to ast
+holly wood
+fa sting
+me red
+hib ition
+ca pped
+benef icial
+ow ning
+cont amin
+arab ian
+to on
+cap ac
+hul u
+sm ir
+nutri ents
+se in
+graph s
+con ditional
+ðŁij ħ
+or ac
+play in
+nor the
+tor nad
+mar ian
+ju mbo
+lex i
+incredible india
+road to
+uk one
+confu sing
+sp h
+shan k
+pi ed
+mq m
+positi vely
+sher ry
+path ways
+consi ders
+tof u
+argu ments
+resil ient
+che tt
+with dra
+ter o
+ated ly
+sw ana
+he b
+fli ght
+har ley
+decre ase
+kind le
+book shop
+³ ï¸ı
+marty rs
+sm ur
+mc cl
+concer to
+sti me
+rejo ice
+app lau
+cle ment
+mer kel
+jai me
+im mortal
+isle of
+mar co
+youtu ber
+stal king
+me too
+st ack
+sp ouse
+u st
+lu v
+âļ¾ ï¸ı
+eque strian
+ev ing
+fl in
+nick name
+the big
+as ar
+st acks
+wal ker
+bor a
+kidnapp ed
+hur ling
+humb old
+rec alls
+co pper
+ann is
+se o
+mer ger
+mu ir
+ad dy
+ðŁĴª ðŁĴª
+be x
+cr acy
+con an
+congratul ation
+mid st
+âĻ ¬
+for bi
+op tic
+cr ate
+crocod ile
+mad agas
+secur ing
+ast on
+o gue
+savi or
+salis bury
+love it
+fuji film
+cast les
+as st
+ar rows
+sp acious
+tr s
+poly vore
+progre ssion
+m ri
+nel son
+bi m
+indic ator
+o da
+pe pe
+re signation
+gu t
+sne aker
+log ically
+az y
+are lla
+te aring
+jo shi
+ssion ism
+q pr
+mari ah
+p x
+ble ed
+mi an
+med ley
+we iss
+ker ry
+gat ory
+at al
+madi son
+av enger
+nab y
+pl and
+gi les
+fresh water
+d ington
+ta j
+demonstr ates
+n tv
+bul bs
+sunday morning
+pe ake
+souven ir
+wa h
+ton nes
+m kt
+complex ity
+con den
+ross i
+b ing
+y ds
+su k
+n go
+mid land
+ol y
+life is
+ri pple
+mo reno
+dd ers
+tu s
+á ĥ
+bou l
+x a
+hol dings
+wn y
+shadowhun ters
+ke i
+asp ire
+m ous
+ow en
+so ak
+skir ts
+moun taine
+stor ming
+ch rome
+ri ots
+sar ato
+amaz e
+less ness
+nav ar
+crit eria
+ra fa
+indul ge
+ay er
+por to
+nam o
+........ ........
+yi elds
+val le
+j h
+mac ron
+sa ins
+dur ant
+tra ilers
+wo t
+confeder ate
+sh rin
+id ol
+form ally
+ten e
+motor cycles
+than g
+no de
+bang er
+dal y
+p ats
+enroll ment
+au ctions
+at al
+ar bor
+lo gos
+de arest
+trans action
+dom ingo
+fle a
+ser mon
+de ck
+sin cere
+questi oning
+juli o
+was p
+pre tz
+armen ian
+k ham
+inflam mation
+picture sque
+acci dental
+film makers
+ðŁĺ ļ
+ðŁĴ į
+ca sey
+so b
+yee zy
+good will
+parag ra
+ss ly
+fe ather
+dy ed
+assassin ation
+na de
+b cs
+app lies
+femin ine
+fe u
+ext ent
+depu ties
+l ack
+psy chic
+go i
+kill ings
+pse u
+ðŁ¤ ª
+un c
+mar l
+tan e
+mck enna
+sur fer
+influ ences
+free way
+hack ney
+mal aria
+el and
+te au
+rema stered
+Ø ±
+raz or
+gg y
+cor ro
+lak sh
+fla ir
+honest y
+hoor ay
+de pp
+am c
+wedne sdays
+q a
+ed its
+- $
+se villa
+dou bled
+human ities
+c cot
+som os
+r ine
+af a
+si oux
+re construction
+wel ding
+th reads
+am ish
+encoura gement
+po der
+bo ck
+bal m
+p tions
+stand up
+accompli shments
+guar ding
+convic tion
+ac ion
+napo leon
+depic ting
+att ack
+su i
+wear able
+âĸª ï¸ı
+pot ter
+esc ort
+vis e
+to ts
+bo on
+event profs
+angu lar
+womenshi storymonth
+bar row
+sch i
+ac comp
+ti k
+l end
+kensing ton
+wol fe
+st acked
+cra shing
+exhi bit
+wing ed
+sab rina
+ma sa
+k ms
+alway s
+et t
+pla sma
+counsel ing
+pick les
+nfl draft
+mr s
+inev itable
+coura geous
+staf ford
+writers life
+ho s
+e j
+gh yun
+trade mark
+adri an
+influen cer
+coron ation
+ra ging
+explo red
+usa f
+excep tion
+eu x
+tan ker
+sw ami
+pac ket
+ðŁij¨ âĢį
+f en
+she en
+a ero
+j l
+re gal
+nw t
+au ster
+meh ta
+char ge
+a ste
+b ate
+inf eld
+racec ourse
+collap sed
+fle ece
+z il
+al lie
+alternati ves
+geor ges
+ðŁĵ į
+quir ky
+fc b
+nat geo
+philanthro py
+bra i
+every day
+ðŁIJ °
+ach ers
+ja an
+fin es
+q i
+fisher man
+distin ct
+gri mes
+nation alist
+comm ence
+ro wn
+âĢ ³
+z ing
+f ter
+hr w
+baro que
+bl ender
+kitt y
+hoo ks
+c ited
+w anda
+consen sus
+reinde er
+an and
+supp ly
+me ds
+v n
+ol ph
+rat chet
+shel don
+secur ities
+ë°© íĥ
+cro m
+mosqu ito
+j eric
+im mac
+dimen sions
+â ¤
+di ssi
+sponge bob
+dami en
+steven son
+jo anne
+del ish
+yi kes
+than x
+surve ys
+postpon ed
+alco holic
+al ised
+ðŁĻı ðŁı»
+do ch
+sen tim
+mered ith
+com pares
+b ago
+happy days
+mo ss
+ãħ ĭ
+ne c
+gn ment
+frustr ated
+comb in
+ri v
+ec lec
+col lo
+compli ment
+actor slife
+ct to
+nic ar
+op hon
+apar the
+man t
+ja de
+trol ley
+optimi zation
+eye on
+eco logical
+qui st
+ep he
+ॠĩ
+cin co
+appo ints
+old school
+c pr
+behavi oral
+min aj
+:- (
+tag ging
+ev al
+jo aqu
+ðŁĺ «
+ha k
+de me
+jama ican
+so s
+hy att
+hand book
+libr arian
+hanni bal
+pump ing
+ch om
+f man
+ga i
+hu ll
+respon ders
+green ville
+n us
+vau gh
+ðŁİī ðŁİī
+ta xi
+gold berg
+man tra
+te ase
+forbi dden
+metho dist
+ati vity
+* ***
+ec t
+mc gr
+Ħ ëĭ
+se b
+amid st
+disapp ear
+thy ro
+phili ps
+er ina
+v icious
+stream er
+million aire
+ma p
+str ick
+hack athon
+gh a
+ed ic
+mi ka
+pe ck
+ill i
+anto ine
+ar ca
+op tic
+ma ure
+ðŁĩ¦ ðŁĩº
+cla shes
+man ly
+âĺ ģ
+al var
+and res
+me i
+el m
+ww ww
+al tered
+l te
+ê¹ Ģ
+mo jo
+for rest
+thal ai
+non t
+spee ches
+acknow ledge
+ign ite
+x factor
+ðŁ¥ Ĥ
+mead ow
+disru pt
+debu ted
+scrim mage
+pharmaceu tical
+fi dd
+found ations
+philosop her
+et al
+publi shers
+bo ys
+c ke
+ru gged
+opti mism
+re be
+phil harmon
+nar cis
+ral lies
+lu is
+go blue
+fol ded
+un acceptable
+optim al
+li sa
+pol aro
++ .
+en za
+âĿ £ï¸ı
+mon opoly
+grace ful
+dair y
+du a
+diffic ulty
+judge ment
+o si
+mer sey
+flu x
+new found
+ter ns
+dimen sional
+in vic
+al ba
+am it
+abudha bi
+alger ia
+autom obile
+the ad
+lo tion
+acceler ator
+vac ant
+iti on
+lu f
+al ic
+pl l
+bla zing
+ba z
+sen e
+ðŁij ¼
+villa ins
+direc tory
+eis en
+to ck
+broch ure
+ri pp
+hb d
+zayn malik
+nic he
+lo lol
+certific ates
+mor se
+fac up
+x ham
+un wanted
+im ports
+carne gie
+fan sign
+mo u
+r alph
+destroy er
+sw ing
+trek king
+cili ation
+pit bull
+g aps
+ho well
+defin itive
+mc le
+f ps
+et z
+bol ly
+lyn n
+gan o
+at ure
+fur suit
+co il
+na v
+but ts
+tro jans
+eu re
+en ko
+sch umer
+horri fic
+install ment
+br b
+subur bs
+a bel
+vi r
+de sh
+cun ningham
+ðŁIJ »
+span n
+sch we
+ke mp
+tr u
+ste alth
+qu es
+le w
+deli ghts
+ko ch
+hu mili
+cr iti
+il t
+sp ells
+mi ley
+car ic
+ðŁį ´
+lc fc
+substitu te
+oun g
+? !!
+af fir
+predic table
+class of
+er r
+cy press
+chand ra
+age ing
+__ __
+ther land
+don caster
+el in
+yo shi
+sail ors
+har ris
+jo anna
+niger ians
+h ers
+pla gue
+pro cra
+k no
+can ton
+busine s
+un h
+pra kash
+c in
+bow en
+co ating
+m als
+be gging
+smith son
+ponti ac
+sp ies
+dam ian
+pl ine
+und ant
+al ta
+one ss
+shame less
+da q
+bb m
+wal es
+stam pede
+ser um
+Ù Ĩ
+cataly st
+x n
+ab sc
+free zer
+ch un
+ari os
+mc cre
+fore head
+he ars
+damas cus
+tac oma
+ardu ino
+encoun ters
+stan ton
+lg b
+ab as
+" ..
+ke te
+drac ula
+ele m
+g ne
+zepp elin
+la brador
+pul p
+op tional
+or n
+russi ans
+san itation
+hil ary
+etsym ntt
+pen alties
+au st
+ig ans
+olympi an
+medic aid
+vers ace
+va pe
+re stra
+pe ep
+sexi est
+st alls
+di le
+the a
+punjab i
+pupp y
+tuesday motivation
+ðŁĵ ļ
+the flash
+roc ket
+mo dest
+chihu ahu
+on na
+k sa
+hur dles
+ca ve
+fail ures
+sp lit
+bo ho
+gur l
+disappo int
+ho ward
+nug get
+fran z
+stal ert
+kaz akh
+for getting
+sch ri
+ag ate
+am at
+eve rett
+du et
+veter inary
+juli an
+ch ills
+bra ve
+ghost busters
+lan do
+gre ets
+profit able
+d é
+ti r
+ze e
+om en
+pd x
+gray son
+har i
+fix es
+stab bing
+swim mer
+symb ols
+compli ments
+po se
+func tioning
+th nx
+gi r
+corpor ations
+bar low
+lo e
+off season
+distin ctive
+marvel ous
+nik on
+enri que
+ky u
+ja ws
+amo to
+lom bar
+travel blogger
+fa h
+ouri sm
+tri stan
+so e
+ce ase
+ðŁı ħ
+z ac
+mck enzie
+taxpay ers
+swim suit
+bl o
+les ley
+kan sas
+w ks
+ki el
+provo king
+my les
+str ing
+kangar oo
+galac tic
+fif th
+s ke
+we ir
+ll is
+mat ory
+ðŁĩ ¿
+un ci
+re productive
+roo ting
+ti des
+gad get
+.... ......
+alex ander
+bow ler
+scre w
+apo log
+eri ka
+wal ters
+shet ty
+lan e
+ban ter
+as ant
+me so
+v ain
+" ""
+us i
+fer din
+accomp lish
+man sfield
+bom bar
+collabor ating
+cla p
+it ure
+s da
+smo ky
+na k
+im person
+car la
+com ra
+bur gl
+lo co
+ti es
+in hi
+trac ey
+se is
+diss er
+rr rr
+dra y
+prote ct
+cor ona
+hun ger
+ck en
+c eli
+trou bled
+predat ors
+fic tional
+shav ed
+riche st
+metab oli
+ful ham
+gro oming
+mono chrome
+wa sting
+as co
+ast e
+ti sta
+remedi es
+ung soo
+south end
+perman ently
+bu mble
+procra stin
+ident ical
+practic ally
+ma scul
+su ke
+assu red
+val erie
+devi ant
+grizz lies
+thi er
+pur a
+ne pal
+not ts
+bil ateral
+spo il
+car mel
+cine matic
+ph l
+ni fty
+ma o
+hypo cri
+la ser
+pan try
+mathemat ical
+el isa
+coordin ation
+bel mont
+a it
+radi ant
+bo iler
+man g
+f ag
+cr c
+h ams
+br in
+â¬ĩ ï¸ı
+famil ia
+âĿ £
+sab er
+ru pert
+gg an
+rit z
+mic h
+sal ford
+le vi
+gra l
+ðŁĴ ¤
+n ino
+ce d
+business man
+ul tr
+sim ply
+compre ssion
+pa ins
+hal t
+ë°©íĥ Ħ
+landsc aping
+n f
+croo ked
+er d
+itt in
+ddle ston
+sur passed
+ino a
+da g
+bl en
+exten ding
+at ing
+al gae
+ball er
+u mar
+snoo ker
+col lu
+flo wn
+thu b
+ridic ulously
+ki sh
+op le
+di re
+as ser
+ari sto
+sc iss
+h ating
+trou ble
+syl via
+suc cul
+plo ts
+sincere ly
+al er
+laure ate
+br ack
+att n
+rif les
+me to
+collec tible
+cu omo
+conte stant
+consist ency
+ant z
+rang es
+abig ail
+de b
+mini ster
+grow ers
+an oo
+hoo ver
+dream er
+nu cle
+resear ch
+mi y
+sha hid
+ma v
+d honi
+cin i
+do j
+hin dus
+part ying
+dal i
+alon so
+inform al
+clark son
+it ton
+ki an
+cit yo
+mor i
+la sted
+as pen
+libr ary
+susp ici
+qu at
+den ial
+fol der
+ch ori
+swee ping
+eni x
+ðŁį Ĥ
+Ø Ń
+nas car
+handmade hour
+mou l
+heat wave
+em er
+exam ine
+ib n
+gr ind
+po v
+tion ist
+m bo
+she ila
+integr ate
+om es
+take away
+cer v
+con nie
+tic ket
+ce led
+bi en
+visu ally
+madagas car
+sor ry
+gu i
+park run
+tra its
+la be
+pois oning
+ॠĢ
+vi able
+bohemi an
+denti stry
+bad os
+spr outs
+mask ed
+te ddy
+ðŁĺ ·
+sa f
+sa as
+ji ang
+ti ght
+spe aker
+withdra wal
+bc n
+as signed
+class rooms
+fle ming
+ðŁĴ «
+super girl
+tot als
+table top
+e books
+horizon tal
+cra z
+flu sh
+j ard
+c dc
+er son
+ãħ ł
+green wood
+ni h
+co x
+ad a
+lit re
+go ing
+v icky
+cur ved
+lou ie
+gra ins
+hy e
+lon ge
+reme dy
+tra inee
+san jay
+super stars
+ma ser
+man u
+s age
+wh l
+ðŁĺĤ ðŁĺŃ
+ðŁijį ðŁı»
+m sd
+en z
+rab hu
+j oo
+gh u
+ac er
+e po
+resurrec tion
+justice for
+bl ended
+mo da
+avalan che
+france sco
+re spective
+g s
+ye ast
+wel ch
+devo tion
+ge tin
+athe ism
+am ic
+carol yn
+lo c
+ld nont
+ave c
+us da
+le gged
+bra very
+b lower
+cow boy
+he h
+sti ble
+buff al
+chann el
+run chat
+âĺķ ï¸ı
+ide ology
+best seller
+y oo
+pe anu
+bon ne
+fel ic
+edi son
+fr actu
+naren dra
+pp ets
+seym our
+ri viera
+he ctor
+necess arily
+bi anca
+soci eties
+the best
+w g
+sent ences
+win k
+vacc ines
+pal ooza
+jam ming
+as f
+mp us
+agre ements
+ec k
+ba c
+hon ore
+com pul
+wild cat
+im posed
+yo ga
+hud son
+can celed
+l ich
+fu zzy
+es que
+ch uk
+w vu
+se k
+fli pping
+r hon
+wi shed
+wh a
+cap ability
+len ovo
+ìĨĮëħ Ħëĭ
+vi vo
+tv d
+nor a
+sil k
+pas adena
+yo semite
+valu ation
+clo cks
+u ber
+mr c
+dar kest
+au bre
+ss o
+bell y
+wrest lers
+kill in
+lou der
+buck ley
+ge el
+ad on
+un s
+appe aling
+ðŁij ¯
+semit ism
+list ens
+fit z
+ãĥ³ ãĥ
+ny lon
+ar ty
+seem ingly
+hal a
+su ited
+et y
+she ds
+mu ffins
+ap ric
+um ents
+u ta
+jam mu
+chelse afc
+star z
+yo ko
+roo t
+clean sing
+di ar
+pione ering
+ihear tradio
+dig iti
+fin dyour
+can o
+ðŁĴ İ
+z ol
+spac ecraft
+six ers
+moi sturi
+b ile
+ti sts
+hor ton
+rang ing
+colum bi
+mete oro
+senti ment
+ep l
+foo th
+text book
+drain age
+r ly
+sc ue
+imran khan
+ðŁĴ ¸
+margar ita
+ed dy
+predic ts
+gamer gate
+advis e
+growth hacking
+love you
+ug and
+v f
+beng hazi
+s later
+ne wor
+ch el
+independence day
+p np
+cul len
+hoo dies
+num bered
+brit t
+t sa
+kl tu
+s ages
+mom o
+onep lus
+col l
+gu ts
+w ta
+mesm eri
+enh ancing
+chiro prac
+j is
+teen agers
+m one
+constell ation
+sweep stakes
+e ze
+slovak ia
+la ye
+pear ce
+wa ver
+po gba
+k ron
+sur geons
+mar x
+ti d
+gg a
+desc end
+p ours
+upri sing
+wal la
+sab bath
+bachel ore
+mack in
+k am
+peter borough
+hor a
+ðŁĮŁ ðŁĮŁ
+think big
+r j
+hy drau
+sp al
+univers it
+ðŁı ī
+mail online
+league of
+ten ants
+w ally
+lan ce
+heav ens
+dd r
+bol ts
+am ir
+i phone
+ci gar
+en du
+re i
+el abor
+r inging
+john son
+characteri stics
+sal oon
+algori thms
+tal kin
+m tn
+di ve
+region als
+ff ice
+hat i
+deviant art
+so tto
+shir o
+l ama
+k we
+f aded
+por ting
+tu mmy
+est ates
+buen os
+ðŁ¦ ģ
+beli ever
+pen etr
+dar n
+sp ite
+can opy
+fashi oni
+t illa
+pet als
+eli jah
+bra wl
+marty r
+ë°©íĥĦ ìĨĮëħĦëĭ
+mid town
+eric h
+d apper
+sm town
+me gam
+ww w
+le le
+on s
+cat fish
+fir th
+fossil friday
+ball park
+th aw
+pot ent
+illi e
+cre ep
+car p
+so ap
+gun dam
+infe c
+yy yyy
+ठ¨
+z ag
+rit t
+calcu lator
+bo ca
+ok o
+to ad
+threat en
+refin ed
+olym pic
+accompli shment
+bacter ial
+a ji
+tat um
+feli z
+she ed
+j at
+th ic
+jam al
+ðĿ ĺ
+lin a
+ðŁIJ ¯
+jo king
+yot po
+pin ch
+ak ron
+her b
+motiv ation
+li a
+ho stage
+cre ek
+gam ble
+russ ell
+patt i
+fo tos
+c pc
+bro ken
+back the
+cla ys
+u mm
+stock ton
+mat ernal
+ü r
+la kel
+cent ury
+be k
+infe cted
+ภ¡
+smack down
+man ned
+ta hoe
+sm es
+bas a
+su la
+augu sta
+. *
+rohing ya
+gre ed
+counsel or
+silhou ette
+gra vit
+cla use
+' -
+bo bc
+occa sions
+now adays
+dic tat
+be ard
+n ally
+brigh test
+kab ul
+inc india
+dhan ush
+archae ological
+che ape
+mizz ou
+d hi
+ov ski
+bax ter
+asse mble
+Ã ¢
+gi gi
+ac am
+wis ely
+haz ard
+north ampton
+âľĪ ï¸ı
+me th
+bla sting
+re unite
+mu lus
+ali zes
+t read
+mil a
+ed ward
+ko va
+pe sto
+ðŁij ¶
+vit z
+hydrau lic
+refurbi shed
+mo tel
+isab ella
+hom me
+sever ance
+uph ol
+mis erable
+f ari
+lat ter
+ef er
+crack ers
+es l
+ac io
+yy j
+in an
+ec b
+z ind
+pan as
+tru cking
+re ed
+sh aker
+burge ss
+em pire
+ag nes
+n ington
+art works
+fr s
+ti le
+bi ome
+eu n
+ch ong
+americ ana
+god father
+go blin
+i shi
+! ).
+temp ted
+gen omics
+mand ate
+ck y
+ðŁĴĻ ðŁĴĽ
+som ali
+br andy
+in ven
+spoke sperson
+pc b
+yu an
+h g
+fa z
+starwar s
+ro wan
+blue grass
+don g
+d day
+trin idad
+er ton
+ban ning
+re tention
+cu red
+tober fest
+re set
+we is
+deta ched
+behindthe scenes
+immun ity
+ph a
+bra y
+ðŁij ½
+ran cho
+ram say
+est onia
+nd tv
+] .
+cab aret
+tar o
+d v
+show cases
+plu m
+ðŁij ¸
+son oma
+pre pa
+memor ab
+e stu
+drive way
+u les
+magn us
+x r
+nn n
+much as
+en ge
+stre amed
+fore stry
+audio book
+tro y
+reck less
+kil om
+ru ler
+ra k
+proce ssion
+i ons
+po ole
+noc tur
+wh s
+farm house
+per a
+par me
+hypocri sy
+s ics
+v ant
+cas k
+holi stic
+au st
+Ð ¿
+in do
+ðŁij© âĢį
+di so
+disp atch
+ol sen
+make it
+en nis
+cent re
+ar range
+ðŁĮ ¼
+sal ted
+ea siest
+f ate
+reg atta
+mo zz
+ac an
+sin i
+g ically
+ch ops
+chick en
+work in
+ha gg
+invol ve
+wee ds
+book day
+wake up
+ky r
+michel in
+fu ss
+re juven
+vac ancies
+incar cer
+m st
+sc ents
+sovere ign
+kick er
+à §
+bo d
+âĢĶ >
+sa h
+mob il
+shrop shire
+oph one
+dress er
+mis suni
+hep burn
+i mo
+foli age
+diagno stic
+as san
+cycl ing
+guil t
+c sa
+puertor ico
+win elover
+wake field
+do ggy
+k he
+pa pp
+co g
+al lot
+cu ck
+poe tic
+mi o
+re vit
+mag ician
+ç ¥
+ant enna
+west wood
+mber g
+lux e
+oat meal
+Ø ¬
+te at
+ffe e
+sear ches
+l ly
+plu to
+el on
+let tering
+inno cence
+fa i
+ann on
+telang ana
+ma it
+neu ral
+can ni
+ar oma
+a stor
+fe x
+co cac
+mon etary
+f ent
+un sure
+' @
+indi rec
+teh ran
+isol ation
+li bs
+make up
+merce des
+ff y
+he tero
+de o
+sco m
+cur sed
+veteran sday
+franken stein
+shre ws
+de co
+ge ese
+lefto ver
+ha did
+vari able
+acade mics
+carol in
+under going
+vari ation
+na h
+ssi er
+gamer sunite
+pur suing
+emer ged
+ll ers
+control ling
+ro aring
+mete or
+vol t
+daw gs
+be aver
+is life
+bathro oms
+aci onal
+pre vent
+lake district
+in als
+y ani
+gra bbing
+sac ks
+le z
+sw ay
+k ool
+time s
+klo pp
+la de
+con cord
+resul ted
+revi ve
+recon ciliation
+ol and
+az z
+gir o
+mand arin
+de en
+nutriti onal
+is coming
+van i
+aw www
+der ived
+love your
+stop the
+shou ting
+nov ak
+ðŁĻĮ ðŁı¾
+lo af
+displa ying
+sunday with
+ma guire
+ch eri
+ðŁı Ł
+re match
+qu ic
+Ú ©
+y in
+ðŁĺ ¹
+ili ve
+z ip
+our ke
+down loads
+sw at
+missi ss
+care rs
+t ment
+proper ty
+hahahaha haha
+gi bbs
+sur rey
+ar ise
+tic ism
+sti a
+ir ling
+fro g
+co se
+bas sist
+fore ig
+lea u
+pil lows
+hol la
+eli e
+disclo sure
+peanu ts
+inte ch
+ww c
+plun ge
+trium ph
+cor i
+sli ppers
+ðŁĻı ðŁĻı
+neutr ality
+ma re
+hair y
+gang ster
+hu mming
+cust ard
+mer lin
+ale a
+s by
+dam p
+mo han
+ver bal
+j st
+gu tted
+b jor
+un finished
+ðŁĩ¯ðŁĩ µ
+un happy
+âļ« ï¸ı
+by pass
+at su
+fis cher
+sa v
+afric ans
+re use
+mid way
+demo lished
+ger rard
+her cules
+Ä Ł
+medic ines
+cl icking
+sur round
+jo ong
+wav ing
+tri bes
+wet lands
+offici el
+argu ing
+l le
+do va
+su zy
+club house
+ne gro
+ob tain
+ga o
+gl ance
+assi st
+ch os
+ãĤ ¢
+âĺ ķ
+adri d
+occur s
+st ans
+par don
+livel i
+emplo yed
+re visit
+ff xiv
+bb le
+ne aring
+min er
+ðŁĺ ¹
+giov anni
+up to
+mar vell
+mar se
+to wels
+cb n
+engine ered
+y elling
+spart an
+si ans
+ðŁĻĮ ðŁı¼
+se v
+coyo te
+sta di
+t cm
+app en
+shenan igans
+open access
+so aked
+ma squ
+le vine
+stro kes
+l k
+aparthe id
+hipho p
+char don
+may may
+ha asan
+stri pped
+fr o
+scri ption
+f ton
+h f
+pri sons
+marsh al
+ķ ãĤ
+an cho
+com promise
+classi fication
+buzz feed
+bblo ggers
+deser ving
+) /
+s way
+ob o
+camp ers
+poder nfamily
+p oured
+bri e
+squir rels
+se ize
+: #
+le k
+ti mb
+st acy
+nas daq
+repe atedly
+br at
+mi ghty
+competit or
+mah one
+de si
+o ke
+bm w
+shi e
+f cb
+cheape st
+minim alist
+par amount
+n ate
+har as
+insan ity
+lat eral
+ment ality
+mo zam
+ta pped
+yad av
+u sp
+b way
+the od
+bil t
+ra ids
+em press
+adap ted
+pat ron
+nut shell
+ag ra
+be aded
+sundaywith marsha
+vi king
+proce ed
+main tained
+thinkbig sundaywithmarsha
+sn es
+mus ica
+to wer
+ch ab
+bo k
+sm t
+insul t
+harve sting
+windo w
+ru ther
+be ige
+dec al
+indic ate
+ma iling
+ri ft
+po le
+ander son
+ch oral
+sp ride
+l ili
+ev elyn
+imrankhan pti
+.... "
+ke red
+un dp
+water falls
+se ars
+le mans
+world series
+ri el
+ani e
+app ar
+score rs
+lam p
+a than
+phys icians
+qu inoa
+refu sing
+vu itton
+unle ash
+s la
+pat i
+shou ts
+inten tions
+fo amed
+europe an
+neighbor hoods
+me er
+man son
+du h
+br at
+con es
+bow l
+kazakh stan
+ठ¿
+in appropriate
+del hi
+ketch up
+ful ton
+s ys
+consul t
+gar field
+to go
+f ml
+f led
+b ds
+facilit ate
+ree bok
+selfi e
+elev ate
+activ ate
+bi ble
+ca wx
+b ys
+cam ille
+sy ou
+sk ool
+her t
+w bc
+ple dges
+recor der
+po sh
+ac re
+so aking
+mat il
+v sco
+shoot ings
+pla r
+e con
+ðŁĻĮ ðŁı»
+rashi d
+u bi
+ðŁ¤ ¤
+sw inging
+wi pe
+rap tor
+m su
+music video
+dur ham
+at tic
+apar ty
+fe tus
+activ ation
+aa z
+motiv ate
+ðŁĴķ ðŁĴķðŁĴķ
+j al
+ठ®
+ag on
+sche er
+stal ker
+fo ster
+az zo
+tele gram
+vi gor
+s laugh
+screen shots
+entrepre neu
+kri stin
+inten tion
+ch illi
+fr action
+don a
+ge a
+tc u
+s ite
+la k
+em il
+d nt
+bor o
+wil kinson
+re cu
+ato day
+t anya
+bl anco
+cd n
+brilli antly
+g cc
+ac c
+evacu ated
+ther ine
+den ny
+cait lin
+she pard
+pou ch
+hand held
+sou theastern
+ha a
+Ã ´
+re solutions
+led ger
+sr in
+r ar
+shat tered
+chim ney
+im with
+mete or
+hand led
+ra ke
+town send
+en han
+shi py
+duc t
+tw x
+inflam matory
+war hammer
+theat rical
+gro s
+sk ar
+sco tty
+ni el
+tit o
+tin i
+conne ction
+_ .
+goldeng lobes
+sha q
+ðŁı ³ï¸ı
+hall way
+fron ts
+effec tiveness
+gla ston
+d hs
+ex pi
+to h
+c pl
+sc s
+re o
+ha g
+resemb lance
+hor an
+abu sive
+qu er
+virtu e
+cho lester
+a q
+shan e
+m ce
+carri ers
+di stress
+re wind
+Â ¡
+voo doo
+int act
+ann o
+ðŁĺ ¤
+pi led
+adi a
+ãĥ ³
+en ow
+di gs
+light ly
+goo fy
+turb ine
+governor s
+con te
+re open
+pa h
+i ve
+cra fting
+swee ps
+jo di
+an de
+zu cker
+kaw aii
+o ko
+v ai
+out line
+kri sti
+ts n
+insp o
+qu int
+fil thy
+lyn ne
+listen ers
+depar ting
+or d
+t weed
+, &
+ale k
+sel fish
+nor ther
+recogni zes
+i ps
+be s
+a ed
+w ills
+pe at
+surround ings
+mon uments
+ais le
+be cker
+la v
+quant ity
+v ah
+helicop ters
+tu cked
+alv arez
+sha pe
+o bey
+ad diti
+road side
+m ite
+bl ers
+ep age
+j au
+ignor ant
+b ins
+lu lu
+x o
+c fo
+ee eee
+apprentice ship
+shef fiel
+to i
+ho k
+faken ews
+deplo y
+aid an
+husk ers
+ãĢ İ
+west brook
+mi ster
+confi gur
+car r
+fic a
+proceed ings
+ha w
+ste ak
+mur derer
+pay day
+a jo
+p vc
+don ates
+bi af
+nom nom
+be it
+k ali
+x rp
+ahmed abad
+se mic
+che y
+x tra
+an twer
+head lining
+squ ares
+roun ded
+flu ore
+bol d
+disa sters
+am oo
+gener ic
+cran es
+brief ly
+gi g
+auster ity
+anticip ation
+for ti
+treas urer
+cann y
+ce cil
+dete cted
+check list
+ภ§
+pam ela
+bar bados
+an field
+hear ty
+tx lege
+peren ni
+arro g
+ing ram
+âĹ ı
+ty ne
+spo on
+r ation
+am ba
+m be
+cam el
+h hs
+york shire
+reflec tive
+fre aks
+to k
+ju do
+partic les
+du bs
+ban jo
+accred itation
+prover bs
+over dose
+inte gral
+gu ang
+mc s
+super car
+af b
+al vin
+ail s
+x tre
+st aging
+tw ent
+rabb its
+mar o
+inste m
+dol l
+cr ay
+sant ana
+ble ach
+mini ons
+che ap
+man t
+di vers
+catal onia
+lo is
+mat ri
+cou gar
+kay ak
+e gre
+p so
+a ia
+å ®
+char lton
+tr acked
+sc ari
+pe tt
+f wd
+x in
+gra vel
+br ic
+bigg boss
+ar den
+hu gging
+pal ms
+st v
+li mb
+the movie
+handic ap
+ri me
+z ai
+stu b
+indi a
+lithu ania
+rhy th
+p ita
+maced onia
+high ered
+brid get
+schwar z
+ske let
+hi kes
+ant arctic
+c ps
+mash up
+Ð °
+n ell
+chand ra
+he ir
+an us
+sher idan
+mi mi
+muse u
+bec ca
+an ir
+bar rie
+dioce se
+compar able
+ðŁı³ï¸ı âĢį
+yuk on
+me p
+hor mon
+mer ic
+al f
+con quered
+christ church
+ðŁĴĻ ðŁĴĻ
+hazard ous
+poo h
+cont ing
+retro spective
+par ame
+na ir
+con sor
+ho tra
+astoni shing
+cater pillar
+u man
+ti sm
+t vs
+serv ic
+croy don
+mor ales
+c g
+cu m
+te ur
+scan ada
+s all
+magno lia
+el ise
+th our
+à® ¿
+ag omez
+phel ps
+ë°©íĥĦìĨĮëħĦëĭ ¨
+wh os
+weav ing
+si sd
+pro poses
+cro ws
+pre sale
+econom ies
+bernar do
+sha hid
+air show
+mc cann
+hor ticul
+nr l
+du el
+mongo lia
+tou lou
+requi rement
+struc tured
+ed i
+o lives
+he a
+cu ter
+Ð º
+enthusi ast
+harri et
+domin ion
+sub mer
+ðŁį ĥ
+sa ab
+nes burg
+mo ff
+def ended
+bur t
+rewar ded
+gold man
+op tics
+khali d
+house holds
+buc kets
+ce cil
+che ss
+substan tial
+ef l
+oper ation
+evalu ate
+st n
+rece ssion
+l ll
+tom as
+tru ths
+ak bar
+s words
+p act
+embarra ss
+ha o
+ay urve
+scrip ture
+ny cc
+op t
+di ameter
+sc ented
+organi zers
+re lat
+ha e
+dream ers
+de se
+ðŁĮ »
+restric ted
+n ale
+r hp
+dol an
+mun ster
+ha ired
+consult ants
+jo ints
+hu mil
+d ill
+relent less
+t é
+af il
+ut ilities
+japan ese
+condem n
+pet ite
+colli de
+q f
+peach es
+cou rier
+l ore
+âĺİ ï¸ı
+reli ability
+ch uk
+ðŁĻ ĥ
+stu res
+ge ther
+ho stel
+bi er
+- _-
+â ĩ
+e ze
+ta ilo
+di ent
+blu ff
+chu ffed
+pil ip
+mon arch
+e em
+bu chan
+b ick
+op au
+ku ps
+ภ¢
+pist ons
+sp ins
+m and
+ce st
+bur ne
+v ile
+cher ries
+bec kett
+need les
+pan ch
+ë Ĥ
+haha h
+trou bles
+insi sts
+do you
+g mc
+mor tar
+deleg ate
+in n
+g anda
+sin atra
+ठ¤
+spee ding
+pu pil
+pre mises
+ali gnment
+pi kach
+as us
+j alan
+Ø µ
+lime stone
+fol kl
+parme san
+ce il
+mo y
+shawn mendes
+ac up
+hu st
+ot es
+med ina
+ma di
+gta v
+censor ship
+ar g
+swe eney
+sy kes
+col o
+foot steps
+cann ed
+adv ance
+gta online
+healthy living
+ðŁį ¾
+a ig
+p ality
+oc s
+he brew
+im minent
+berk shire
+jeremi ah
+out going
+bak er
+entr ata
+ma ids
+gro ves
+bo c
+a del
+m fw
+con science
+arm ys
+nut ella
+conte stalert
+novel ist
+la h
+ban ker
+marque z
+ðŁı ¡
+to ff
+out age
+gr p
+ðŁĺŃðŁĺŃ ðŁĺŃðŁĺŃ
+musc le
+du dley
+nvi dia
+mi di
+m uni
+ess ays
+dat ac
+car ter
+ภ£
+t ans
+i ves
+public ations
+al er
+ok wx
+il u
+cu tt
+har p
+out law
+luther an
+br ill
+bo lic
+do well
+green land
+be sties
+path i
+pay ton
+gue st
+har den
+ðŁ¤ ©
+ann ed
+evacu ation
+po ised
+mc der
+b han
+o i
+envel ope
+ci d
+ca vi
+ta pas
+book review
+grey hound
+âĻ ª
+fe ud
+lun gs
+for te
+rai der
+ff er
+oni x
+dep end
+yn wa
+rel ating
+de vs
+ðŁĴ IJ
+acqui res
+d ha
+j yo
+priv ati
+can ine
+k b
+cra b
+sar din
+imag ining
+k j
+em por
+down hill
+ne z
+ta eyeon
+nick imin
+gb p
+à µ
+w ap
+sec co
+ma shed
+ðŁĴ¥ ðŁĴ¥
+augu stine
+diss ol
+dic tator
+â ĵ
+vi per
+ed fringe
+vau x
+hard work
+book let
+no x
+chi ff
+ðŁĴ ¨
+observ ations
+xbox one
+u sher
+ke er
+lu p
+dal las
+cal gary
+ma dra
+di ous
+k bs
+wood ward
+hero ine
+lu mber
+sea world
+o ws
+mc ke
+maver ick
+gu la
+cross roads
+fan g
+s ade
+nik ol
+chee tah
+me c
+pp g
+er ick
+ðŁİ µ
+tox ic
+bj j
+viol a
+sp ire
+ch ino
+tra vis
+institu tional
+ha as
+low ry
+w ac
+ea e
+hu mid
+mp ton
+ru ck
+je w
+c ine
+zim mer
+se f
+bhar at
+fre es
+aam ir
+ðŁĴ ħ
+z inc
+wan e
+multi player
+royal wedding
+e el
+preci pit
+qu ery
+kimber ly
+isa bel
+ful fill
+ig an
+vau l
+pan e
+sc y
+dig it
+gun n
+u tah
+dog day
+fi on
+xia omi
+da c
+el ast
+cha vez
+ro blo
+g ine
+ten th
+ab h
+ke to
+hur dle
+na dia
+memorab ilia
+ha bs
+qu an
+h w
+hv ac
+pix ar
+ec cle
+kram er
+accu ses
+ðŁĴļ ðŁĴļ
+per se
+mean time
+wa hl
+atle tico
+âĢ¢âĢ¢ âĢ¢âĢ¢
+ott oman
+no vo
+k us
+conne cted
+tru sts
+d mv
+spen cer
+rahu lg
+do ve
+sto kes
+bolog na
+enthusi asts
+Ã ª
+rockstar games
+ted cruz
+du ras
+s acked
+late x
+immer sive
+cer t
+lu cin
+princi pals
+fa res
+sa ils
+far n
+am ent
+saf fron
+quent in
+check point
+fer ris
+ex cur
+ðŁijī ðŁı¼
+bai ley
+se h
+ter re
+mad am
+s band
+wan derers
+cumber batch
+yy c
+digit ally
+blackandwhite photography
+roll in
+moroc can
+ðŁĮ ħ
+din ner
+d well
+to om
+m ye
+ez ra
+cp fc
+war hol
+me er
+jon ah
+no aa
+s gate
+so on
+secu lar
+g ating
+ti o
+dri ver
+si ssy
+assan ge
+ta th
+ed mund
+bobc ats
+ra ji
+po stage
+stu ds
+m gm
+kat o
+edin burgh
+meet the
+shir t
+fa a
+mens fashion
+sp reads
+wi m
+car ts
+phoe be
+j ars
+bot swana
+Ù Ĥ
+ed war
+sk ar
+ri ve
+gu sty
+c tv
+ferdin and
+su therland
+nickimin aj
+k v
+si us
+bee ch
+re z
+desi res
+on ial
+camp o
+quar ry
+lor raine
+gil more
+ig gy
+µ ï¸ı
+ho pping
+avi z
+ðŁĮ º
+uni sex
+dedic ate
+att itudes
+ste er
+jun kie
+rail way
+y b
+whi sper
+key an
+k us
+ju g
+di x
+a ins
+sum mon
+ov ich
+sy ed
+her ald
+ma ison
+me ded
+wild flower
+main land
+ri sky
+ru kh
+over looked
+ki c
+destro ys
+nam an
+ki p
+z ano
+champion sleague
+ban dit
+quin cy
+smi le
+cal vin
+open ings
+ta pp
+ol ulu
+spec tro
+accred ited
+ap k
+pra ised
+bar nett
+pol len
+premi ered
+selen agomez
+tou red
+screen ings
+uu u
+mis o
+en se
+adam lambert
+guel ph
+har yana
+hu tto
+le ar
+l tc
+po ached
+brex it
+æ Ŀ
+tt c
+pa vement
+mon gers
+ro e
+ad ers
+ling ton
+particip ant
+ca red
+ga il
+y ates
+lan tic
+dash board
+jo o
+feli pe
+ssi onist
+bu m
+s end
+a eri
+thu gs
+luci fer
+a he
+dete ctor
+fil ly
+gas oline
+ham per
+hump day
+the ta
+the band
+fore casts
+o hhh
+lo bb
+hol l
+cp u
+az u
+ad ar
+hai ley
+bu b
+car t
+quo ted
+an archy
+pan cre
+twit art
+al den
+st ash
+the less
+or ni
+belie bers
+mor mon
+partic le
+avi ation
+⬠Ĩ
+webcam toy
+sad dened
+cru is
+ham let
+n ct
+roll ins
+marque e
+saw yer
+reli ance
+a ura
+di ec
+soo thing
+sig nings
+ak is
+Ã ³
+at kins
+aer op
+ðŁĮ ¿
+y ab
+sh ari
+con nol
+du bbed
+manufac ture
+convin cing
+feelthe bern
+ra u
+pu lit
+on ec
+gem stone
+ur ging
+bag u
+ga h
+aci ds
+fi anc
+zodi ac
+sn oop
+her rera
+initi ated
+ven ge
+profess ors
+pro di
+stron ger
+e mission
+bb a
+hal le
+ta pp
+haw an
+wh im
+compe ted
+myr tle
+ir port
+cold play
+ach e
+ske p
+m son
+ss ic
+calli graphy
+swim mers
+me y
+pp c
+thri ft
+po c
+re places
+commu ter
+âģ¦ âģ¦@
+go ers
+lo gue
+para dig
+bas kets
+sensiti vity
+joh an
+atl antis
+& &
+suit case
+anxi ous
+l h
+str i
+gal loway
+stre ad
+war den
+gr ounded
+ffici ency
+li feat
+reli c
+disgu ise
+island ers
+f cofficial
+classical music
+b mc
+en field
+bi que
+oak ley
+bat man
+sla ying
+ner ves
+mul tit
+calci um
+projec tor
+scott sdale
+ant ino
+gri ps
+kim mel
+des mond
+prote stors
+hi atus
+metaboli sm
+conclu ded
+press er
+ti pping
+sli de
+e to
+hun ting
+aus open
+ri k
+pp ery
+innov ators
+pitch ers
+ag ger
+fun gi
+z ad
+proli fic
+rockn roll
+bl ames
+ct ar
+stam ford
+q ad
+mozz arella
+insan ely
+den ver
+ph ouse
+nom ad
+ï ¿
+s ris
+pro du
+hen ley
+pag an
+am trak
+ru bi
+in cl
+tu tor
+sco tia
+wo es
+sing apo
+fun nel
+turn bull
+know ledge
+gri mm
+real madrid
+we are
+missi les
+con sol
+emo jis
+sne ak
+smi ths
+ru iz
+br ou
+i el
+ha ver
+ðŁĮ ļ
+kin gof
+basil ica
+circul ation
+prin ters
+ta pping
+ri dley
+dra gged
+ha j
+writ er
+fundament als
+personal ities
+me tre
+stereo types
+bur le
+best of
+n ffc
+ha th
+mini stries
+a ali
+trac ing
+pav ed
+ł ï¸ı
+g ic
+insp ire
+tu g
+ha re
+repe ated
+ex pon
+lol li
+rho de
+pre cin
+install ations
+instag ram
+az ar
+i es
+sole ly
+du kes
+mission ary
+van guard
+fursuit friday
+on d
+pol ari
+ma st
+har an
+jos é
+jack ed
+ec oun
+al ities
+ne ph
+ra vel
+moder ated
+sco w
+s fb
+uru guay
+as o
+ni g
+au du
+p ints
+lat ina
+ben z
+m itting
+char ted
+mat ology
+cit ro
+biop ic
+ðŁij Ń
+djo kovic
+fox y
+agu il
+so to
+an ada
+sin king
+sc rap
+hair s
+bethan y
+fact friday
+ðŁIJ IJ
+unlea shed
+) (
+contra dic
+ram on
+coast line
+y ong
+sn sd
+li gan
+p ome
+mit age
+ge tt
+wat i
+ri sk
+so aring
+bru sh
+f pl
+av an
+å Ĩ
+lar son
+sh ear
+mul til
+blu r
+multi media
+chun ky
+par i
+n ani
+weir d
+cholester ol
+char les
+dream ed
+tan ning
+puzz les
+fr am
+hand ball
+ch ag
+beli ze
+al u
+bang s
+Ñ Ħ
+detec tives
+mc g
+ish q
+bo thered
+saf c
+mp ing
+ten eri
+g ays
+sail or
+an gi
+mul ticul
+gue ssed
+ros é
+high ways
+bro om
+chatt anoo
+- '
+see ker
+on ed
+at f
+lu c
+> <
+bar i
+per cep
+jewel ry
+as ph
+sor row
+sl ing
+mam moth
+jac kie
+ë §
+wilt shire
+sa o
+can cell
+im paired
+tor ial
+bre ed
+guy en
+jud ice
+tit le
+pro spective
+applic ants
+ðŁį Ĭ
+epis cop
+e id
+b yo
+stock ings
+ðŁĴĥ ðŁĴĥ
+ll p
+sna g
+keep it
+l ough
+ol son
+matur ity
+!! !"
+cop ter
+i sha
+bl i
+wil mington
+tr youts
+th ai
+ðŁ¥ ³
+pe bble
+kra ft
+f p
+Â º
+ssi vely
+li vin
+contest ants
+tex tures
+jo an
+h dr
+film festival
+prov ence
+wi do
+op end
+c si
+sto wn
+cro ati
+ad just
+host ile
+analy sts
+il an
+cu ppa
+bru m
+newfound land
+good win
+me tt
+mall orca
+plu gs
+bu k
+bb hutto
+wrest le
+sa ire
+sho pped
+for za
+le head
+vi vo
+ba st
+ro xy
+reg is
+hard working
+hon olulu
+desp air
+young sters
+ni g
+impro mp
+roll tide
+de emed
+tre ason
+ru shed
+for ged
+ff f
+pikach u
+bri ggs
+do it
+ac cent
+la us
+gla ze
+compet ent
+a ho
+photo g
+mid field
+le go
+har vard
+min orities
+re illy
+slic ed
+once upon
+initi ally
+financi ally
+landscape photography
+har dro
+qu o
+mm ers
+par kinson
+smu gg
+read iness
+bru tally
+glou cester
+mp ed
+bbhutto zardari
+mur der
+ye d
+dat aviz
+sr t
+dow ning
+bi ans
+m ü
+fle ck
+fli pped
+s ly
+brilli ance
+ri m
+k um
+bubb a
+ko i
+knit ted
+sor g
+ma is
+ðŁĮ ²
+ti ss
+su stain
+sen su
+ak han
+zi est
+exam ines
+chardon nay
+user name
+short list
+re bs
+on o
+dar ing
+hard wood
+che que
+righte ous
+light ening
+dir k
+shra dd
+du ra
+down stairs
+sh al
+ami gos
+ru ff
+s law
+ri es
+red nation
+man us
+ðŁĩ§ ðŁĩ·
+distin ction
+u bun
+dur an
+mi gra
+thi ans
+la ver
+domest ic
+k x
+jaz zy
+justi fy
+belong ing
+insul ation
+color stv
+drun ken
+chann eling
+qu and
+xi ii
+enligh ten
+kan o
+fati ma
+teen choice
+terri fied
+p ba
+as ley
+met museum
+dun e
+pack er
+ki o
+ðŁĴľ ðŁĴľ
+bo iler
+fas cism
+ar mored
+back grounds
+in mates
+embarra ssed
+defin es
+th d
+we go
+silic one
+lo on
+el ding
+bor rowed
+he mp
+ak sh
+kaw asaki
+br y
+de af
+kill er
+dispo sal
+ðŁĩ °
+glaston bury
+un covered
+o xide
+po ff
+d ant
+k j
+ku ro
+dri zzle
+peop les
+fe e
+pro pri
+dd lovato
+pi ggy
+ot is
+aller gies
+u bis
+pengu in
+ser a
+vi z
+prosp erous
+ici des
+tornad oes
+sene gal
+web cast
+sto red
+enchan ted
+bb cone
+bay area
+entrepreneu rial
+rednation rising
+experim enting
+ang an
+lot to
+they re
+por e
+er p
+seren e
+east wood
+bro kers
+bar ge
+stal lion
+timber lake
+tailo red
+dy stop
+b ate
+lat ors
+di xit
+bran son
+dynam o
+ky lie
+shame ful
+bt wn
+spring time
+mix ture
+s ounded
+lu ton
+dad es
+mal a
+op ra
+en ic
+rahulg andhi
+se wer
+~~ ~~
+ky u
+nor theastern
+ca er
+bc u
+nir vana
+kitch ens
+ous y
+al m
+river dale
+hid den
+fl int
+sp d
+pat rons
+katy perry
+au gh
+exhib itions
+sm c
+shu ts
+at ore
+da in
+some thing
+ber th
+bo g
+por ter
+gen to
+con cussion
+ang lic
+ro we
+gr illing
+scar lett
+master ing
+mor nin
+comm ented
+si me
+si zing
+christ y
+ce os
+st m
+at ry
+tari ffs
+vac ation
+pre judice
+p su
+paren tal
+far age
+can a
+cap com
+koso vo
+you re
+men stru
+stal in
+grape fruit
+br an
+che sa
+dav en
+exc el
+!! )
+๠Į
+distribu tor
+ce a
+bride sma
+millenni al
+wa in
+ob serving
+mis ery
+plan etary
+expo sing
+bra ised
+comp ton
+don gha
+q l
+spring steen
+th ul
+syl ve
+cab o
+pal ad
+niel sen
+gaz ing
+ba ja
+r oud
+orchi ds
+johan nesburg
+se man
+d ji
+oper ative
+affe ction
+eclec tic
+at c
+mut ant
+aw x
+nic e
+mel bourne
+indu lg
+tu lip
+dias pora
+wel p
+big gie
+mississ auga
+retri ever
+or an
+tam my
+c ta
+hipp o
+seas oned
+ger mans
+eng v
+marvell ous
+im f
+rela ys
+mon tan
+maur iti
+me ister
+as surance
+reig ning
+su fficient
+han e
+no thing
+pos se
+nav y
+in love
+brigh ton
+en qu
+ch ung
+sweat y
+es c
+cal ed
+man s
+nicar agua
+sl ices
+mo cha
+washington post
+bb n
+dam ned
+grow ing
+en burg
+lo an
+me s
+wh oops
+believ ers
+spi el
+vo daf
+l at
+s led
+cricke ter
+brown e
+golf ers
+bar ra
+wat chers
+lu igi
+sw amy
+mom s
+pit ched
+san tor
+cr s
+si re
+sc amp
+bo de
+ste war
+jon ny
+ent ity
+pac qui
+mind ful
+min india
+bear ded
+temp t
+scorpi on
+eat on
+authori zed
+ar to
+s vp
+op athy
+cch ini
+house music
+disney world
+âĢĶ @
+pro pose
+di y
+expen se
+ten g
+pupp ets
+sm el
+d aca
+per ry
+fin n
+boo sting
+lefto vers
+cou gs
+satell ites
+man y
+az e
+g ong
+fi e
+metho do
+fer ries
+ðŁ¤Ķ ð٤Ķ
+explore rs
+load er
+attrac ted
+il ton
+godd amn
+pi azza
+doc tr
+sav ing
+paragra ph
+visu alization
+may ors
+work flow
+ack les
+ðŁĺĤðŁĺĤðŁĺĤðŁĺĤ ðŁĺĤðŁĺĤðŁĺĤðŁĺĤ
+ठ¸
+twer k
+clu t
+lo ver
+te ases
+si an
+o te
+deter ior
+accor d
+l fw
+swar ovski
+nat al
+tra ps
+k ina
+analy ze
+laye red
+bever ages
+un it
+ran som
+pe shaw
+dest ined
+astro logy
+si pping
+miley cyrus
+cam ino
+marshmal low
+bli ss
+out back
+fa q
+int oler
+humil ity
+po ppin
+hallo ween
+mon tene
+op hy
+nu n
+tattoo ed
+a as
+ðŁĮ ³
+dale y
+qual ity
+du sa
+fisher men
+swi f
+ter rac
+st au
+le in
+trol ling
+ship ment
+garden er
+march madness
+head band
+gr t
+bur nett
+w and
+!!!! !!!!!
+gh e
+du x
+hu d
+war ner
+ðŁĩ ¦
+ex ile
+rescu e
+rat a
+d han
+duc ati
+dro wn
+bl ends
+spi e
+alli gator
+simul taneously
+broo ke
+u ke
+k har
+comm union
+ri ka
+ford fc
+chin atown
+you rown
+me y
+can al
+syste matic
+de pri
+ox ford
+an il
+w ut
+equ ation
+be z
+fle ur
+the good
+lang ley
+ad ity
+ed ith
+al fie
+о ÑĤ
+en cry
+br ill
+ex emp
+ce sar
+mb ling
+ab ri
+sc icom
+j ing
+school ing
+mi ka
+mechan isms
+impromp tu
+rhe a
+moo re
+crime a
+be sto
+wri ght
+el ders
+ro ds
+kam al
+folkl ore
+be et
+mini on
+reli eve
+thr o
+team usa
+pas cal
+made with
+boli via
+itt i
+free bies
+desi red
+best selling
+l iness
+la den
+ke ane
+mi sts
+hipp ie
+atta chment
+@ /
+se w
+flan agan
+âĿĹ ï¸ı
+supre mac
+stl cards
+si as
+q u
+rh ys
+ste ep
+val leys
+v w
+pav ing
+disp at
+al ison
+por te
+id u
+new sc
+soc ket
+mo s
+co star
+re vo
+prote ins
+stanley cup
+m cal
+ear ring
+se cs
+mc lean
+cap ric
+nick elo
+ad en
+v c
+shou se
+adap tive
+maxi mize
+entertain er
+pro se
+gri ffi
+six teen
+lam ar
+mi rage
+saudi arabia
+awe ather
+ru st
+in filtr
+fashion week
+ðŁĺĬðŁĺĬ ðŁĺĬ
+selec tive
+bubb le
+a den
+fen nel
+deci sive
+m ta
+mock ing
+mb les
+st amp
+mu le
+bernar do
+gr in
+po tt
+j ingle
+vet tel
+colom bian
+cam o
+motivation monday
+ba han
+p ly
+dh ary
+k ami
+x men
+sleep er
+gar a
+my sti
+confi dential
+conflic ts
+p neu
+ce s
+insur tech
+clean se
+me rely
+va is
+tu x
+the great
+shar on
+ma j
+hol a
+eco systems
+aj ay
+aa j
+hu sh
+har mon
+backto school
+wiki leaks
+reflec ted
+ðŁĺ ĵ
+commemor ating
+ac et
+buck ingham
+messi ah
+tu ous
+hor net
+to be
+d q
+he ine
+mi g
+pl ate
+nichol son
+sp ie
+cumber land
+nor mal
+pho bia
+happy halloween
+city fc
+mc el
+gilli an
+ke to
+lu de
+de mise
+su ga
+str ate
+mcgr ath
+visit scotland
+foo led
+cb r
+gc se
+col ori
+po td
+missuni verse
+fin ances
+ma poli
+for ks
+Ø ´
+cann on
+medic inal
+ðŁĹ ĵ
+kh o
+wre ck
+pan to
+bag el
+gu ll
+syndic ate
+ic y
+pr c
+ki en
+zi ka
+ti sh
+pe ta
+c co
+li za
+ch ut
+ex traction
+el g
+gl i
+fu eled
+pos it
+respec tively
+leice ster
+br ink
+vulner ability
+im ported
+e sha
+ðŁ¦ ħ
+r ural
+re ll
+gam ing
+atlan tic
+aband on
+no ah
+re solved
+pro state
+aller gic
+ps d
+âĺ ¹
+dun geon
+fang irl
+illumin ated
+m hs
+white sox
+d ently
+ck o
+endor se
+over ly
+dazz ling
+prior iti
+night life
+ut il
+be have
+flam en
+east bound
+ðŁĴ Ł
+ilove you
+gov uk
+mozam bique
+alle gi
+dr i
+testim onial
+ath s
+ì§ Ģ
+mm y
+shab by
+pro secco
+friend ships
+cal am
+dam ages
+off set
+jura ssic
+jun o
+arre ll
+ðŁĴ ©
+interven tions
+dare devil
+car ver
+run away
+ran e
+truste es
+ha ute
+dep ths
+ðŁİ Ń
+me in
+sacrific es
+con cier
+ne sting
+i zzy
+me tam
+ilove my
+ur ine
+du lu
+mal hotra
+ve ins
+night ly
+co at
+an di
+he witt
+lon el
+ci ble
+wr ite
+jen nie
+sant ac
+ĸ ï¸ı
+str ato
+singapo re
+sop rano
+kri sten
+cheer ful
+flee twood
+fa iri
+m eli
+wa st
+tur nt
+sfor sale
+sc rolling
+angel ina
+ren dition
+jeric ho
+nick y
+or b
+fla vo
+patri ot
+ash eville
+sick ness
+re fund
+aggre ssion
+b pl
+ãĥ ĥ
+elu sive
+thi story
+hang er
+bu ffs
+vil las
+at kinson
+sp h
+ja it
+decl ined
+wo k
+supre macy
+oo tball
+ey ang
+ðŁİ ĵ
+s ford
+ath i
+consu me
+road ster
+e so
+u pro
+reci pe
+au f
+uc i
+ar on
+oo oh
+cs go
+re ich
+mc d
+min ute
+ladi es
+pun k
+rut gers
+mee k
+ariz on
+ta j
+land lord
+de gra
+autu mn
+lyn x
+us f
+b hi
+fairy tale
+dongha e
+bet sy
+explo ded
+chen nai
+op a
+pro tag
+br ant
+ðŁĵ °:
+g f
+pal li
+ðŁı¼ âĢįâĻĢï¸ı
+su t
+ill ini
+colum nist
+shir tless
+de centr
+sear ched
+ec or
+bu ggy
+s ack
+ðŁĺĤ ðŁĺŃ
+de t
+ther i
+or naments
+bring back
+to v
+quarter finals
+ic he
+con stra
+gi er
+buchan an
+vi x
+kay aking
+mu stread
+swal low
+mel b
+sc af
+op al
+may oral
+har at
+ðŁ¦ ĭ
+schedu les
+id f
+ha gue
+ro z
+a ah
+d mc
+du plic
+ca che
+orph an
+frac ture
+rec on
+ch av
+bun nies
+al ain
+mustaf a
+ðŁİ Ļ
+vac ations
+dynam ite
+tex ted
+broad caster
+ðŁĴ £
+ste amed
+rock er
+di etary
+luxury travel
+inaugur ated
+sa wards
+vaugh n
+lincoln shire
+click ed
+kra ja
+f anc
+remo ves
+layo ffs
+mc far
+bre eds
+win nie
+jon ghyun
+incen tive
+vari ations
+pat ton
+atur day
+persist ent
+pr un
+pi ers
+dal es
+æ ĸ
+breast feeding
+r ance
+ta wa
+Ĥ âĸ
+mur doch
+cap tive
+thi stle
+nic a
+commod ity
+cou ldnt
+board walk
+graci ous
+practiti oners
+n gc
+scru m
+ner o
+camoufla ge
+col on
+he i
+phys icist
+saturday morning
+ten er
+si won
+colum ns
+bru ne
+y vr
+ba ir
+reti res
+hal am
+cab er
+shaz am
+min u
+cas cade
+milk shake
+gri d
+d ren
+vin cent
+so dium
+plat ter
+cheer leader
+chen ko
+y ak
+elimin ated
+ty po
+y man
+re think
+âĿ Ĺ
+ts ville
+bernardo kath
+ex tr
+ðŁĺģ ðŁĺģðŁĺģ
+ta o
+re per
+mo ths
+em powered
+c iting
+transpor ted
+mon ks
+san at
+cle ars
+bachelore tte
+camp bell
+racha el
+har le
+hand ler
+climb s
+inter ference
+rele ase
+sh and
+r bs
+hr h
+ãģ ª
+val le
+r é
+sli me
+w akes
+chu bby
+slo an
+el ves
+ath en
+attor neys
+micro scope
+ston er
+sc aling
+o be
+c out
+se man
+mid week
+bal sam
+ðŁĺį âĿ¤
+ti ful
+v ish
+lo tta
+ri pping
+re mn
+ti re
+le ap
+ha vent
+la by
+hi mach
+whisp ers
+we in
+ðŁİ ¸
+wild flowers
+se le
+u cc
+li ability
+az ine
+sw ings
+k ya
+ta ir
+re main
+e do
+flo ps
+poc ket
+grand ad
+exam iner
+gr is
+ffe ct
+ðŁijĬ ðŁı»
+stud ded
+heart beat
+de acon
+firm ly
+infec tious
+ste f
+out lines
+le asing
+cla ws
+sen se
+tab s
+hoo t
+mo sul
+spa wn
+co a
+hog warts
+ve in
+alban ia
+manu el
+b ino
+vaux hall
+scot land
+go bucks
+mat ty
+phy sio
+tor ino
+const able
+investig ated
+s lower
+mistak en
+bay er
+wild fires
+vo ic
+x on
+time to
+chas sis
+bar ric
+pi on
+bald head
+woo k
+regi str
+dra fts
+b hs
+li gue
+l ick
+staf fordshire
+baf ta
+dar ry
+je anne
+ven ding
+cor p
+⼠³ï¸ı
+kid dos
+fen way
+ca o
+west bound
+ðŁĺ Ļ
+dv r
+quick er
+bla h
+goo die
+ðŁĴĭ ðŁĴĭ
+vo x
+esp er
+fac ade
+cor relation
+red bull
+rou p
+decl ining
+chi ve
+mc gee
+tur o
+in der
+f eller
+fu g
+il ysm
+mar di
+peshaw ar
+ki eran
+ine ma
+meat balls
+pe ck
+depre ssing
+sen sing
+gi z
+dd ington
+spring watch
+ro aming
+yellow stone
+horse shoe
+am man
+week day
+ol or
+ðŁ¥ °
+boo sts
+spr int
+scar ves
+je e
+bee tro
+cl an
+all the
+ìĦ ¸ë
+enlighten ment
+ado be
+re generation
+? @
+cont ag
+yach ts
+to u
+mor a
+en voy
+r ani
+go li
+dhanush kraja
+wood working
+streng ths
+se di
+disc s
+ar ina
+sc on
+lit e
+ano ther
+ðŁ¥ Ĭ
+ye men
+gu ern
+sav vy
+lo yed
+biom ed
+heart break
+comra des
+milli e
+pat ch
+un f
+jar vis
+bl aming
+commemor ation
+ge y
+å ¥
+cardio vascular
+alig ned
+docu ment
+. ?
+aesthe tics
+em u
+the irs
+le h
+ps ic
+si f
+pl ateau
+ex pend
+domin ating
+rob es
+mauriti us
+excep tionally
+hom er
+discover ies
+bra un
+ten nant
+insul in
+ðŁİ ®
+car bs
+te as
+? !"
+zi e
+franco is
+brow sing
+th ol
+cla rence
+hel per
+ob tained
+cas sie
+le es
+! ,
+pome gran
+hu bs
+presti ge
+] [
+mach er
+bott led
+pun ch
+pi pe
+o ch
+gall ons
+deliver ies
+u ra
+un day
+mon de
+depic ts
+re gency
+outra geous
+khal ed
+car o
+he arti
+za g
+develop mental
+over coming
+stati stical
+flavo red
+for ds
+cre atives
+lau rence
+di as
+sun screen
+in ked
+pre acher
+n ul
+impac ting
+auti stic
+âļ Ķï¸ı
+o ss
+pel icans
+cele ste
+v b
+ru mp
+mc gra
+fair fax
+hu mor
+bbc news
+row ling
+cal der
+seam less
+ag ne
+p ti
+mix ed
+t shirts
+mer ci
+b tob
+women instem
+genealo gy
+pre ven
+l our
+cra dle
+gi use
+Ð ¾
+chron o
+fair ness
+chocol ate
+tor y
+as da
+pre scott
+stret ched
+al man
+u il
+re charge
+in tre
+ob st
+hosp ital
+hay ward
+teneri fe
+fried man
+vap ing
+confe ssions
+ye ah
+bal li
+luck now
+cor pse
+sculp tor
+amp ton
+t pp
+indic ates
+sur plus
+tru man
+ðĿ Ļ
+sin ha
+in vo
+sovere ign
+ke v
+establi shing
+engra ved
+assu ming
+ðŁı ģ
+sou za
+fab i
+ton ed
+oun ge
+del oit
+dow ney
+no ble
+om or
+car tridge
+ðŁı IJ
+u hur
+hol loway
+succe sses
+r sa
+âĦ ¢
+ma zz
+tw d
+disc ourse
+. <
+y at
+satis fy
+com pri
+ठ¹
+graph ite
+disser tation
+ar ter
+í Ķ
+b ally
+zom bi
+ly ons
+a ic
+u bc
+pra da
+e il
+da x
+cla i
+grand daughter
+extravag anza
+chall enge
+ðŁ¤ ŀ
+po ver
+primar ily
+dad dy
+man a
+bi kers
+inqui ries
+da un
+fel ine
+gener ative
+he f
+benef iting
+lind sey
+pol ka
+demonstr ated
+al le
+rand y
+o su
+low key
+weir dest
+red bull
+our y
+n ous
+wood stock
+cre denti
+nic er
+g ado
+aly ss
+ap h
+prepa redness
+station ary
+incorpor ated
+dy er
+sarato ga
+cele sti
+: "
+antibio tics
+or gs
+inde fin
+ap ron
+и Ð
+fif teen
+no f
+ðŁĶ Ŀ
+ph x
+te ga
+m z
+organiz ational
+on air
+band ung
+pleas ures
+mor i
+secre tari
+rac coon
+ca shi
+pil ates
+k on
+geof frey
+la o
+kam p
+depart ments
+back packing
+an am
+Ã «
+crack down
+aun ty
+on do
+li zzie
+ph ers
+cu n
+ðŁĩ ±
+k pop
+pu t
+inten tional
+connol ly
+bar clays
+hs fb
+swin don
+u ku
+s ally
+a int
+âľ ħ
+pen ang
+up lifting
+epile psy
+inter ro
+bun gal
+go ku
+blue berries
+ठ¦
+u ssia
+sil ky
+mou red
+i stic
+bri efs
+me ats
+go b
+ch aser
+state wide
+pra sad
+gl itch
+ar in
+ban ff
+memb er
+ðŁĺŃ âĿ¤ï¸ı
+lo ving
+hall a
+ภ¡
+smo kers
+yak u
+scicom m
+physi o
+sw ol
+lem ons
+gel ato
+ch ool
+capit als
+ki stan
+ti ghts
+spi kes
+trav ellers
+ik lan
+commissi oning
+ar ine
+emabiggest fans
+empha sis
+front line
+pad dock
+destruc tive
+ba ha
+l inger
+je wish
+shet land
+mc gin
+mon key
+ko z
+s one
+raj ini
+te h
+y en
+c vs
+masqu er
+gir ly
+we sle
+was nt
+bro dy
+termin ator
+gil le
+mag gi
+bir die
+jeopar dy
+cu bic
+vm ware
+intric ate
+an up
+to pia
+east on
+sab res
+investig ates
+bu sting
+bil ingual
+valent ino
+in format
+fer re
+advent ur
+hydr ate
+for sy
+az iz
+san to
+e de
+whist ler
+continu ously
+d ham
+un used
+ji had
+addic tive
+vi dy
+do b
+i do
+fi ed
+ni versary
+n one
+fu er
+ðŁĺį ðŁĺĺ
+coven ant
+prin table
+immac ulate
+o em
+cl t
+serv ants
+consu med
+un released
+sc um
+pack aged
+me re
+ìĦ¸ë ¸
+to by
+ta f
+spo ons
+me al
+f ball
+fair field
+jan et
+silver stone
+dart mouth
+follow me
+voy ager
+kom bat
+anni ver
+ene w
+mag dal
+ho ve
+sa th
+grizz ly
+car di
+gart ner
+sand y
+kan ye
+post ure
+po ign
+im pulse
+radio logy
+horiz ons
+si am
+aish war
+= =>
+no che
+tr is
+el yn
+com me
+du i
+ce c
+councill ors
+cudd ling
+creep ing
+loc ke
+manag es
+trans ferred
+ne cks
+di er
+dan o
+v ick
+lun ches
+d he
+en sures
+cri ss
+ul ster
+bann on
+cont enders
+sp am
+sweet ness
+med al
+hon duras
+arc tic
+ultra sound
+in fr
+disco vers
+ei ffel
+ca sters
+ru ben
+du st
+awe ed
+atri um
+lest we
+se ared
+ðŁĵº :
+ty ne
+ex changes
+little mix
+l le
+astron auts
+hersh ey
+work day
+kno b
+so v
+re signs
+today show
+der man
+an th
+af c
+ta ster
+sw oo
+sa eed
+per ing
+narrow ly
+rn li
+best buy
+panas onic
+obst acle
+farmer s
+ðŁİ Ļ
+pa wan
+ki est
+ang ers
+absur d
+oh my
+sin o
+pist achi
+sp ice
+giu li
+prime time
+ko w
+k ens
+ex agger
+! ?!
+u ba
+midd les
+ju dd
+e jec
+slam med
+pen sions
+of a
+re create
+b hp
+xx l
+liver pool
+thre sh
+pur ity
+ni eu
+hol ics
+wr ath
+ra do
+gli o
+am ma
+dile mma
+cr u
+lets go
+.... @
+âĿ ĵ
+sugge sting
+tru mps
+hor us
+f v
+ic om
+refer ring
+predic tive
+tar ts
+ge tte
+so ck
+glo ssy
+pin ky
+al ec
+thy me
+ou ra
+thero ad
+pe tr
+cr am
+p fi
+dv n
+me ier
+incen tives
+tun nels
+mobi l
+rec ap
+extra s
+upri ght
+rev amp
+per severance
+, -
+ot p
+mir ror
+ar wx
+ger ry
+ma her
+g or
+hom epage
+am is
+ag ra
+made le
+best friend
+sirius xm
+bun dles
+admir ing
+t dsb
+ðŁį ģ
+ch as
+slow ing
+ro h
+wall papers
+â̦ /
+tek ken
+gang s
+tal a
+lind say
+shou l
+line backer
+tool kit
+ur anium
+caly p
+ab rams
+mat thi
+ðŁı ¿
+hon ourable
+da yo
+ver sail
+tan k
+st c
+fr itz
+spl end
+pat ag
+anno yed
+on day
+devast ated
+chattanoo ga
+national ism
+mas sey
+jen n
+tail or
+dev gn
+org ans
+zu cchini
+on fox
+sat ire
+wex ford
+dis grace
+no to
+vol ta
+âĿ¤ï¸ıâĿ¤ï¸ı âĿ¤ï¸ıâĿ¤ï¸ı
+à ¶
+home owners
+poin ter
+m cr
+au sten
+day sto
+mo ons
+pal ma
+gra zing
+e so
+influen cers
+shahid kapoor
+compli ant
+measure ments
+develop s
+y d
+par l
+p vt
+rand olph
+tor tured
+ger ald
+eli as
+deepi kap
+war mup
+hick ory
+g ap
+co ffin
+am our
+re neg
+moun ting
+seven s
+ig le
+hi er
+dec ad
+tri ght
+esc apes
+wer ner
+t fl
+ful filled
+ni ger
+sour dough
+re aper
+choo ses
+spin ner
+week nd
+fil tered
+sh uk
+kat i
+old ham
+open source
+kh anna
+at elier
+conne c
+opho bic
+gla s
+complic ations
+ar son
+counc ils
+sm ol
+as sy
+lur king
+ling ui
+han ks
+e in
+Ù ħ
+ru gs
+n guyen
+nou veau
+men ace
+le v
+alad din
+ru ining
+round about
+k m
+con or
+shoo ps
+may day
+traum atic
+prab has
+ka iser
+k ita
+rou ter
+pe dro
+re tar
+stun ner
+spani sh
+distur bed
+acade my
+e learning
+wit ty
+sen g
+fer al
+av y
+sta b
+ke aton
+ur du
+ko to
+hu i
+coo ke
+ari an
+the personal
+u ma
+se ap
+a sting
+rhetor ic
+hand writing
+munici pality
+consor tium
+ðŁIJ Ł
+glasgo w
+ra ya
+eli za
+polym er
+bro th
+prac ti
+correspon dent
+addic ts
+gay le
+ail ing
+o fe
+p li
+hear tw
+st itch
+sight ings
+prie sts
+sam o
+slo th
+good wood
+roc co
+sab c
+summ it
+l ace
+pres ley
+itt en
+cin cy
+thepersonal network
+s week
+pe gas
+af con
+regi stry
+ci m
+le th
+dic ap
+cand ice
+flu ent
+sm ack
+pede stri
+al oud
+car ac
+priyan kach
+p gh
+ir ons
+dol ce
+lat via
+dece ased
+thero ck
+cla p
+cen e
+fo am
+morris sey
+gre t
+essenti ally
+com cast
+be agle
+argu es
+ing ed
+- â̦
+sa g
+ha san
+ðŁĻ Ĩ
+ðŁį °
+nh ra
+kann ada
+indic ators
+on er
+bri xton
+at as
+screen play
+sor ority
+sha heed
+he em
+class mates
+tain ment
+es i
+breast cancer
+zucker berg
+aur or
+en cia
+ref ers
+kae per
+vor tex
+com part
+lym ph
+photograph ing
+ste ff
+rest ling
+par sley
+mom ento
+th man
+lac king
+du tt
+ocu lus
+fin o
+fren zy
+ra sc
+der n
+dis missed
+noo k
+met gala
+sh ill
+rapha el
+maver icks
+exhib its
+eag erly
+c pa
+amen ities
+. âłĢ
+exo dus
+ern st
+lit a
+deal t
+womens march
+i ain
+score board
+campe ones
+c en
+ti ki
+garri son
+fidel ity
+bra g
+road map
+psy chop
+lo e
+ble u
+ðŁijĬ ðŁı¼
+sau vi
+spr inger
+temp tation
+ru dolph
+ac ura
+wic z
+parach ute
+stro l
+len ny
+zi k
+dom s
+nb af
+al pac
+vivi an
+ro ve
+pre et
+perpe tu
+sna ke
+air soft
+infl atable
+prin ces
+ati e
+ffe y
+pati ent
+m ire
+chel le
+sl ack
+groo vy
+# :
+up loading
+!!!!!!!! !!!!!!!!
+siem ens
+provi sion
+v fx
+need y
+f ats
+to poli
+bhu tto
+sa thletics
+alu ms
+t winning
+south western
+adop ting
+last night
+man ne
+la ga
+tw ell
+ac ia
+-- --
+eye wear
+hur ley
+fle e
+sa ch
+pe cker
+cost ly
+is k
+cr ates
+polic y
+ero sion
+in go
+wer k
+ðŁIJ į
+torto ise
+therap ies
+inter net
+chihuahu a
+ri ps
+fre i
+ed or
+tai ji
+t fc
+do d
+demp sey
+christ in
+chen g
+hi ps
+gra eme
+com passionate
+cavali ers
+histor ic
+soul ful
+crimin al
+ja c
+vin ci
+expi red
+sur at
+turi smo
+k ona
+se aweed
+ber ts
+le ica
+expre ssing
+a al
+wor t
+break fast
+her ring
+am used
+rhu barb
+mar tian
+cospla yer
+y ash
+stri al
+ra ul
+refer ral
+dw ts
+j w
+ad ler
+cur tains
+gu r
+val ence
+tyr one
+sw fc
+coach ed
+re born
+diabe tic
+cho ke
+nor folk
+investig ative
+ðŁĴ¯ ðŁĴ¯
+z id
+v mas
+phi e
+objec tives
+âľ ĭ
+over due
+di vers
+mat su
+ðŁİŁ ï¸ı
+casu alties
+ภ§
+al k
+stand ardi
+re alist
+arti facts
+pand or
+ke x
+in vin
+( !)
+ine y
+par aly
+mr t
+fay e
+the voice
+on ga
+de ed
+skin ner
+az wx
+speci men
+priyankach opra
+nu evo
+bar kley
+toulou se
+resu mes
+football ers
+cit i
+fe tch
+è re
+lestwe forget
+ðŁĻ ĭ
+ch unk
+dri fting
+manipul ation
+equ als
+pu tt
+ky ungsoo
+âĿ¤ï¸ı #
+ela stic
+par ano
+fo y
+do ping
+cin cy
+ss ler
+interrup ted
+al ay
+ado res
+ame thy
+con voy
+ãĢ ı
+Ĭ ãģ
+black list
+gener als
+sa chin
+bru shed
+oun ces
+non stop
+illi ams
+bt sarmy
+u av
+ru ff
+bur ma
+bi k
+defen ce
+schul tz
+bo asts
+lonel iness
+go re
+trans forms
+alum na
+@ @
+ra ppers
+ne hru
+car o
+himalay an
+wearab les
+ge h
+pepper mint
+re development
+flam ingo
+cos by
+big baldhead
+ag ri
+bare foot
+sco pes
+re gram
+gh ana
+ðŁİ «
+i heart
+sa die
+carri e
+microbi al
+ku ala
+sk ater
+quer que
+âĻ ©
+gen res
+reas oning
+ch ased
+as o
+sli pped
+en can
+vam os
+ker s
+ad verse
+mo il
+commod ities
+with you
+sil ent
+hy pe
+an de
+am ination
+whi spe
+lit z
+âļ½ï¸ı âļ½ï¸ı
+ri ff
+pp y
+lam bs
+gan esh
+ab sent
+regu lator
+marse ille
+en roll
+par cel
+wa p
+by rd
+ðŁĩ Ń
+tu ber
+country music
+par l
+contro llers
+responsi bilities
+we y
+ch ate
+montene gro
+chic o
+mil an
+l ms
+tra inees
+appropri ately
+un certain
+popp ies
+ed sheeran
+nutr itious
+gar o
+deut sch
+awe some
+ãĥ ¼
+comfor tably
+land marks
+et i
+re usable
+daniel le
+ro sal
+co les
+just ic
+c cs
+f anny
+ni m
+mc u
+clin ch
+at ene
+mer ge
+im db
+ang lo
+uc cino
+pan ini
+an not
+bur berry
+feat ure
+predic ting
+fashioni sta
+s ask
+imag inary
+mm o
+south sudan
+spe ar
+hu bble
+jo inthe
+coyo tes
+sli go
+ko dak
+sit com
+polaro id
+roo ted
+corru p
+ðŁĻĮ ðŁĻĮ
+bris ban
+at z
+ah l
+re my
+tal ent
+aval on
+ra da
+pau line
+locom otive
+go ons
+ne mo
+maser ati
+ic u
+stu tt
+histor ically
+sm b
+pres by
+avo id
+so oners
+rhine stone
+w ad
+ri sing
+tro t
+mo des
+reg ent
+optimi ze
+re ece
+sm u
+ver ti
+newyork city
+cor tez
+ra c
+in case
+sin c
+fiel ding
+e tta
+tiff any
+al monds
+sad dle
+k rat
+mat ter
+g low
+star ving
+gl o
+cra ppy
+sl ur
+st d
+monit ors
+recei pt
+maymay entrata
+mc il
+un is
+rain bows
+cal dwell
+pacqui ao
+j op
+a fe
+hoo k
+es sen
+wiz ard
+medi an
+fla ws
+com s
+âĿ Ħ
+ing h
+ha ynes
+anton io
+tem plates
+ou ter
+na w
+cardi gan
+bel grade
+ðŁĴ ī
+hom o
+a ise
+ro pes
+no ve
+what you
+tri gge
+concep tion
+ad ukone
+na di
+fri ars
+sw er
+adju sted
+hot line
+san ity
+kau r
+down loading
+c gi
+ten or
+eth nic
+app alach
+ภ¸
+pa g
+gol ds
+on set
+investig ator
+car tel
+peace fully
+jarre tt
+cat alan
+poli o
+n um
+fru stration
+dhar ma
+my life
+âľĮ ðŁı»
+aber deen
+mu sa
+bin der
+spark ly
+fle eing
+instin ct
+co ping
+domin ance
+ill ers
+er a
+u conn
+lo oms
+living ston
+gal i
+he s
+c ma
+bel a
+se ley
+mon k
+la ch
+mar x
+Â ´
+m erica
+woman in
+es sex
+ra ina
+jim i
+nep tune
+z ack
+chine se
+mart ins
+chand elier
+her n
+with us
+ear l
+asph alt
+modu les
+st p
+ul la
+psychi atric
+mile age
+captiv ating
+si der
+men to
+mor t
+tran ce
+tal bot
+ab by
+ì ĥ
+âľĮ ðŁı¼
+j ak
+daw n
+turn up
+scre wed
+fe ds
+blue print
+ðŁĴĸ ðŁĴĸ
+har sh
+er os
+insom nia
+ban kers
+ta emin
+mis conduct
+hu mber
+gi di
+edu ardo
+con a
+musc ular
+consu ming
+ra sh
+don nie
+di pped
+col lie
+samu el
+melt down
+ðŁĺįðŁĺį ðŁĺį
+me z
+exam ining
+schwar tz
+pri stine
+ðŁIJ Ŀ
+ve it
+ful filling
+an esthe
+gue sses
+dra ft
+som me
+soli d
+pati onal
+ho ped
+evolu tionary
+all er
+enter tained
+sli ps
+lud wig
+conclu des
+sen sible
+bon net
+cra ze
+tra s
+haz ards
+const antine
+ed ics
+star trek
+to c
+occu pational
+in cheon
+deepikap adukone
+pizz as
+new comer
+de part
+oppre ssion
+ebon y
+foss ils
+tro jan
+el en
+ste aks
+k hou
+positi oning
+ug by
+red cross
+ak h
+dol ce
+us mnt
+pp en
+dil ig
+ma vs
+call er
+cost ello
+⼠Ħ
+dy n
+thing s
+rhin os
+a xi
+sar kar
+con vocation
+att ers
+ss ss
+fun gus
+eu gen
+russ o
+squ at
+w sb
+eli on
+william sburg
+s off
+defici ency
+be arer
+o kin
+key stone
+t wain
+cal ming
+break able
+wa res
+horser acing
+com bs
+bun ting
+u it
+t land
+ðŁĴĻðŁĴĻ ðŁĴĻ
+ga stron
+sab ot
+ick ers
+commissi oners
+sen ate
+ii ot
+ath ena
+nit rogen
+an tony
+ero tic
+di alo
+mis sou
+hypo cr
+âľ Ī
+kaeper nick
+can v
+d roo
+clevel and
+o sh
+mon sta
+stefan o
+^ )
+sh ul
+po ison
+ha e
+commerci als
+ma ul
+nit ro
+co worker
+alo e
+vap or
+t ents
+russi an
+qu id
+question able
+mid get
+po ker
+girl friends
+sin the
+erit rea
+ten ure
+depos its
+buc keyes
+spot ter
+theod ore
+trin ity
+joaqu in
+u cci
+follow the
+caf c
+mp a
+ðŁIJ »
+plo tting
+dom ino
+ta ek
+sion ally
+dicap rio
+pa p
+car mel
+ig er
+bt cc
+beth le
+www bigbaldhead
+foo die
+bagh dad
+mason ry
+off ended
+à ·
+ภģ
+sc ro
+vers es
+ori ent
+ar ches
+pi yu
+know your
+gre e
+ta kers
+gu ard
+dish on
+bucket list
+bha fc
+war dly
+ðŁİīðŁİ Ĭ
+leigh ton
+pe w
+stra y
+assaul ted
+in hal
+ly fe
+amar keting
+l x
+kat z
+ubun tu
+me o
+carto onist
+turno ver
+mi z
+dis like
+mul len
+mo f
+bl and
+hi des
+emer ges
+chori zo
+truste e
+ma hog
+lan sing
+paralym pic
+fa int
+fa una
+ch al
+sn ar
+cat h
+bent on
+cast illo
+sli ppery
+apric ot
+oec d
+bar o
+l z
+he ming
+clow ns
+co workers
+peru vian
+commu ters
+y ell
+ðŁļ ´
+under ing
+v j
+tt p
+fli pk
+w ana
+soc ent
+Ĥâĸ Ĥâĸ
+ठĤ
+oo sa
+jag ger
+di sm
+e less
+d ham
+cali f
+a official
+ec lip
+harro gate
+gra pp
+com rade
+n tr
+concentr ate
+thi ghs
+bit coin
+bel arus
+ë ĵ
+end uring
+now watching
+industri al
+pi p
+ar on
+ar at
+Â ®
+whit by
+oooo ooo
+sa ree
+tic als
+mis leading
+yo on
+year s
+sle igh
+roman ian
+sciss ors
+vam pires
+ac up
+ab ba
+th weeksary
+cent ri
+fl ye
+u o
+c bi
+bu ena
+sin d
+mar ino
+bur r
+re building
+ठ²
+anniver saire
+ac ca
+ðŁĴĢ ðŁĴĢ
+gett ing
+tu lips
+wolf pack
+âľį ï¸ı
+more than
+ta kin
+ð٤ĺ ðŁı»
+u be
+mon ic
+dou bts
+mo wer
+co balt
+don ne
+specul ation
+argu ably
+kak u
+htt ps
+prosecu tion
+din ah
+stam atic
+disclo sed
+bever ly
+fl wx
+cra bs
+extraordin aire
+war mest
+imper i
+o logists
+trac es
+par c
+lake side
+am r
+ter i
+hour ly
+domin ation
+ar row
+shrews bury
+ance stry
+wr angler
+trigge red
+pen sac
+roo ster
+survi ves
+a on
+bo ko
+val or
+love is
+la g
+pe y
+fo cal
+out laws
+bl anc
+artic ho
+wit s
+marsh all
+die go
+support small
+u ca
+sa h
+je et
+syn ago
+gover ning
+ðŁĴ ¬
+sal ads
+cre ate
+miri am
+cen sored
+ami de
+no u
+z eta
+allegi ance
+* )
+bl m
+ric an
+pa stors
+oly mpus
+blo c
+whir l
+star ry
+pr one
+y k
+p ne
+congratul ating
+be v
+so ber
+love island
+sa ir
+an ing
+tutor ials
+q e
+lun d
+in ist
+cle ver
+taxpay er
+ali z
+wren ch
+dd ling
+cap ri
+h pa
+ðŁı» âĢįâĻĤï¸ı
+na j
+o j
+futuri stic
+jelly fish
+ðŁĶ¥ðŁĶ¥ ðŁĶ¥ðŁĶ¥
+cel ery
+plan k
+fil a
+ne me
+un healthy
+lec tions
+ðŁ§ ¡
+rit chie
+n ws
+mi kha
+wonder woman
+âĢ İ
+hip stamatic
+ka g
+ðŁĴľðŁĴľ ðŁĴľ
+poul try
+mo w
+wor ds
+lo ff
+ðŁ¤£ ðŁ¤£
+relat able
+re mixes
+keny atta
+ke m
+re signed
+fo d
+stra igh
+j lo
+hu tch
+box ers
+colle en
+mag s
+instruc tional
+ko l
+attrac ts
+pra g
+account ant
+go ggles
+br u
+th ole
+mar row
+leu ke
+oc to
+pon ds
+bubb ly
+he ist
+ìĹ ij
+im p
+a har
+ha unt
+hall mark
+psy ch
+kkkk kkkk
+col umb
+jump suit
+cost co
+si delines
+ag gies
+over turned
+ni b
+key chain
+fu k
+f af
+mi am
+assist ants
+cy cled
+ri der
+dam mit
+red wings
+mag es
+kin s
+ì Ĥ
+ho d
+son t
+carol ine
+" '
+cu le
+bra id
+fel ony
+ar ities
+ruther ford
+depic tion
+isab elle
+ro ach
+k day
+fifth harmony
+em y
+li gam
+bari sta
+albu querque
+gro ss
+ðŁį º
+oo ks
+ðŁij ¼
+dun can
+try in
+jag s
+g ould
+li tho
+âģ £
+а Ð
+sam my
+tun g
+cas ser
+apo lo
+aaaa a
+man g
+as ics
+sh en
+p ye
+tur bul
+ss p
+saint sfc
+on lin
+n anny
+he ster
+do z
+ภĶ
+th read
+ren ts
+kh and
+ðŁĴª ðŁı½
+un conditional
+rob son
+car re
+ph on
+sacrific ed
+Â £
+auto s
+par ker
+oc a
+log in
+kee gan
+hard cover
+dough nuts
+ðŁĮ İ
+spit fire
+refresh ments
+saskat oon
+commod ore
+j f
+rub ber
+halam adrid
+child care
+stra da
+io m
+ri k
+dak ar
+ther mom
+cro pped
+gar u
+ali k
+ven i
+i ft
+si ka
+ritu als
+z ul
+e ch
+Â ©
+su dan
+l land
+i me
+do cker
+ì ¤
+fe ared
+fa o
+wal ter
+no g
+mutu als
+l h
+ali gn
+mon ia
+concep tart
+ðŁĻı ðŁı¼
+sco e
+compet ence
+sw ine
+ly me
+laun ch
+green er
+abstract art
+inqu is
+gran ada
+ga elic
+flu ff
+d backs
+grave yard
+ba be
+acade mic
+adventur ous
+joh ann
+~ !
+bi bi
+| #
+pl ings
+gett y
+as b
+âĿ¤ï¸ı @
+staf f
+religi ons
+bang or
+world bookday
+me gh
+de vin
+ash ore
+meri dian
+gi thub
+qui z
+all stars
+be stest
+ir resi
+ack er
+do te
+war rington
+pol ly
+newor leans
+cr ou
+wi gs
+che y
+smithson ian
+la sag
+de tour
+bor is
+stra ps
+mari ah
+inten tionally
+ko h
+ðŁį ¸
+ssi an
+mar issa
+cor al
+episcop al
+casu alty
+tom o
+supply chain
+sam p
+on go
+ro o
+cavi ar
+p fw
+clau dio
+buff alo
+s ations
+mat ty
+snap back
+l ds
+al arms
+mat te
+âĺ Ķï¸ı
+conditi oner
+d ors
+he x
+fi zz
+a stri
+sus sex
+secur ity
+qa eda
+all star
+cocac ola
+as one
+cl icks
+sc ans
+mu te
+he avier
+ðŁİ §
+âĺ ŀ
+lv l
+book boost
+youtu be
+fla shes
+f jor
+c su
+explo de
+do dge
+cair n
+gonz ales
+th ill
+pel le
+hart ley
+renew able
+re tin
+e stre
+costar ica
+shipy ard
+nc fc
+pri ya
+a ghan
+an ath
+plu gin
+co rey
+re bound
+or u
+kat rin
+hor mone
+gi m
+mahin dra
+s sus
+park land
+har per
+fanta stic
+infer no
+ep ilo
+wrest ling
+fe ct
+c it
+ac oun
+to ssed
+monu mental
+char tered
+bu st
+pe tra
+âĮ ļ
+wildflower hour
+sweat ers
+* .
+bl er
+ate ch
+go wan
+demo graphic
+bra l
+suici de
+renov ations
+vu el
+sin ister
+ar mani
+miso gy
+ph arrell
+nap s
+un iting
+crusad ers
+cor gi
+insu red
+than i
+no or
+g q
+d ada
+bicy cles
+snu ggle
+sch an
+ten berg
+ss al
+fe mme
+bo il
+½ ï¸ı
+re ap
+occur ring
+hus sein
+divi d
+sto ke
+sh alom
+na ia
+o lic
+frustr ating
+Ù ĩ
+ig s
+gro ver
+scen arios
+n ds
+bru tality
+med alli
+bu on
+sas s
+skate boarding
+ony x
+lor ry
+ny u
+gau tam
+mm ings
+gu g
+end i
+lo thian
+comm ando
+chal k
+ph ora
+asse ssing
+ti gh
+crun chy
+ad ay
+is l
+ci ara
+pilgri ms
+kam al
+p to
+brit anni
+t ani
+sm c
+l ure
+app store
+ab y
+golf ing
+cl c
+fa u
+an as
+shu tting
+regul ated
+carn age
+scow boys
+all enge
+c ma
+humbold t
+rel le
+ku mb
+her i
+refin ery
+sound check
+d wayne
+bos nia
+i sp
+the alth
+anni v
+relev ance
+my a
+bag gage
+dre ad
+s bc
+th ed
+bu h
+hi jab
+lo id
+ke w
+c te
+respec t
+lovel ies
+cu bes
+celebr ate
+dir t
+sav ers
+_ ,
+gar ment
+pulit zer
+mas jid
+beat port
+al arts
+encry ption
+s ner
+ple ads
+found ry
+sym metry
+ru mi
+birth place
+scallo ps
+supp le
+pivo tal
+t ati
+no de
+so d
+pro xim
+tr ics
+col dest
+bren t
+mand u
+cla ir
+e ach
+and alu
+hi ddleston
+ðŁIJ º
+mel ts
+v ance
+pin n
+se ments
+scre ened
+sa chs
+o bl
+ic ha
+âĺĺ ï¸ı
+school ers
+heal ed
+lo gged
+ð٤ĺ ðŁı¼
+ic us
+bore dom
+b ish
+b ffs
+tal king
+sure sh
+hoo kem
+de on
+de fl
+ei leen
+ðŁį ķ
+women intech
+ri sotto
+rang er
+adverti se
+ภģà¸
+tel ly
+la go
+dart moor
+d ong
+sk ates
+lo go
+un ner
+mail box
+ma sala
+lo oooo
+amethy st
+che wing
+c bb
+australi ans
+rc mp
+game art
+# ...
+kor n
+extre mism
+fruit ful
+anci ent
+pu bg
+pol ite
+wh it
+mur als
+m gr
+line man
+dav ao
+ste ms
+ten nis
+av age
+tu pac
+gigan tic
+hs bc
+auto biography
+up the
+ี à¹Ī
+re gal
+fig uring
+ku l
+mis sy
+hoo p
+gra s
+for ums
+back lash
+abduc ted
+p nw
+min ic
+bu tt
+bott oms
+at on
+ven g
+ðŁĮ ı
+del aney
+prab hu
+fan club
+over haul
+health ye
+sy no
+aa f
+ren amed
+kim i
+un cle
+man city
+se u
+qu anti
+este em
+um in
+en zo
+mel vin
+under go
+j har
+far ah
+coast ers
+humph rey
+mh z
+children s
+^ .
+d hi
+disrup tive
+integr ating
+r nb
+over sized
+a ide
+ne au
+docu mentation
+ðŁijĢ ðŁijĢ
+pal o
+hear th
+ri yad
+pun ctu
+abc news
+secu res
+boy band
+bir ch
+ju co
+tra ff
+legislat ors
+bay a
+ãĤ ¯
+no ises
+collec ts
+s warm
+k ner
+bi shops
+stur geon
+snapp ing
+mo l
+fre aky
+chair person
+tro p
+lyn ch
+car cin
+art sy
+e sto
+cha i
+fl ur
+inv ali
+sau sages
+im el
+j or
+fun fact
+wit ter
+puni shed
+ac ons
+h ya
+re versi
+em c
+dif fu
+z x
+sp aw
+cla d
+d mit
+hol land
+fre sco
+pay roll
+ab undant
+stu ffing
+mor o
+c ny
+boy cott
+wend y
+ele ven
+pro voc
+pil ot
+tr x
+be ad
+climate action
+ri on
+assi e
+ì ĸ
+o sm
+islam ic
+ho ar
+good reads
+al ici
+afterno ons
+spoke sman
+jo lie
+it as
+masc ara
+âĻ© âĻ«
+pre vail
+beetro ot
+lu jah
+k li
+dod ger
+Â »
+ru le
+l n
+scre am
+ho bart
+col bert
+r tc
+er m
+pat ro
+quo ting
+s live
+que st
+non fiction
+semin ary
+prosecu tors
+ve st
+express way
+g ge
+nau tical
+et f
+ðŁİīðŁİ Ĭ
+dur ation
+cha ired
+the film
+fab io
+she h
+can o
+ðŁĴª ðŁı»
+with draw
+! :)
+cor pus
+phen om
+yel p
+la wn
+ent om
+snapp er
+but te
+pin ball
+pro xy
+libr e
+alle vi
+n ada
+gabri el
+fo wl
+eure ka
+daph ne
+tu nes
+pun ched
+wh ore
+jo g
+ren tial
+man ners
+o pe
+wh ufc
+gu th
+revol t
+sne aker
+philharmon ic
+ho ste
+sovereign ty
+ðŁĻıðŁĻı ðŁĻı
+fish ing
+sci art
+fe ta
+i pp
+dump ing
+kel own
+gir i
+dig its
+sal u
+san jay
+twee ters
+sp as
+col chester
+sc ab
+ma dd
+๠Ħà¸
+Ä ĩ
+ged don
+march for
+do p
+maure en
+un plugged
+di do
+fashion blogger
+up a
+mex ic
+tar y
+pol ye
+jame son
+v t
+grin der
+mad dy
+consult ancy
+¬ ë
+leagueof legends
+ac cents
+um ni
+jane iro
+tu ss
+h ens
+ampli fier
+to shi
+pret tier
+pre vents
+new town
+red wood
+vant age
+ball ard
+ar tof
+a she
+a sion
+lac ey
+ap at
+gro ve
+ภĦ
+rw and
+real tors
+tra itor
+bed ding
+ö r
+zi on
+fla shing
+cam pan
+boom er
+secretari at
+ab ol
+liti gation
+cont amination
+se dly
+shred ded
+in for
+do herty
+bench mark
+ro che
+skate board
+sho vel
+i zz
+to pper
+o ster
+laby rin
+autu m
+k ong
+hum mus
+vi z
+tech news
+kla us
+am using
+socialmedi amarketing
+i des
+cast ell
+ste e
+underestim ate
+cal ab
+pa ign
+b illing
+unanim ously
+g mb
+fly fishing
+hath away
+commerci al
+colour ing
+skul ls
+pivo t
+te p
+tb c
+motor way
+x press
+construc tive
+pu k
+under lying
+kir sten
+mani ac
+cha o
+se ma
+chiff on
+ðŁijĮ ðŁı»
+ver ona
+kom o
+stan doff
+wi ped
+c ated
+bla ir
+wor kin
+m sc
+bethle hem
+swi pe
+unexpe c
+pe es
+pe tri
+orig ami
+ðŁij ħ
+mex ico
+flav or
+ru dd
+cannab is
+mar u
+ri ddle
+wor shi
+sil on
+sch at
+ap se
+tang er
+bi ous
+e er
+questi oned
+o zar
+dan k
+angle sey
+char an
+bak u
+compe ten
+re pri
+bat ter
+sa xon
+cal ves
+leng ths
+$ $$
+âŀ ¡ï¸ı
+immer sion
+ga unt
+car ry
+cy to
+b anda
+shu tt
+experi ence
+el gin
+mous se
+ta z
+ê µ
+in correct
+en z
+b ham
+mor on
+so ver
+ar un
+ti pped
+la ble
+de arly
+bau tista
+í Ļ
+mor tal
+woo p
+dt la
+sho cks
+dav os
+ðŁĵ Ŀ
+swim wear
+her man
+ðŁijĩ ðŁijĩ
+z ir
+neglec ted
+grac ed
+campu ses
+av s
+ar ora
+swach hb
+live pd
+ac cra
+enqui ries
+shoo ters
+kur t
+vancou ver
+brad ley
+gar da
+g ü
+ol la
+attrac ting
+up ton
+ne win
+lu mia
+furn ace
+ev ers
+e on
+sw a
+roo kies
+a oc
+v ss
+bris ket
+tor ch
+yo da
+heart land
+tac o
+ph ony
+food bank
+ab bey
+bab ylon
+u y
+gre ate
+expre sses
+d andy
+sc apes
+survi vor
+ron d
+e ci
+ha vin
+ab el
+chil dish
+tor que
+wav y
+ur self
+kanye west
+year of
+ale stine
+o brien
+al fon
+sk ag
+kore an
+anchor age
+val eri
+de w
+ðŁİ ¨
+land slide
+car ole
+christ en
+go phers
+af i
+priyan ka
+q q
+power of
+it te
+pc so
+tw ol
+pr y
+intellec tu
+guer rero
+pi les
+wish list
+w ren
+time table
+ë ı
+prodi gy
+gibb ons
+. /
+ne ur
+anz ac
+mur ray
+vie st
+pla ster
+la ir
+art gallery
+inter continental
+g br
+bell ator
+nam joon
+mam mals
+am el
+y aw
+saras ota
+cam ar
+bud ding
+sum mari
+aco sta
+la sh
+ey ou
+post graduate
+instruc tors
+ti g
+const ant
+were wolf
+ic os
+cla s
+glen n
+bud ge
+ðŁĻ Ĥ
+er ta
+sta ins
+persecu tion
+cumb ri
+o ch
+syner gy
+hu ang
+scand in
+mid terms
+comment ator
+regar ded
+perpe tual
+bo iling
+al p
+lan ge
+sch le
+fac eli
+twee ta
+ri dden
+ok toberfest
+charlotte sville
+ik lan
+jo u
+ch atham
+b sc
+ðŁį ¦
+stra uss
+mel low
+xx xx
+happy hour
+re actor
+ww er
+distr action
+at orial
+ðŁĴª ðŁı¼
+twin peaks
+fay ette
+a or
+ko k
+bro om
+sy fy
+ou se
+am ag
+Ø ·
+ubis oft
+lu lu
+hall mark
+stu art
+it ya
+si deline
+venge ance
+re lu
+sex ism
+boun cing
+un ites
+gu stav
+te ssa
+stu mp
+pro clamation
+ima x
+divid end
+col by
+ðŁį İ
+play wright
+un safe
+co smo
+ðŁĩ²ðŁĩ ½
+cup board
+constitu ents
+ang lia
+ram page
+ðŁĺįðŁĺį ðŁĺįðŁĺįðŁĺį
+than ked
+take aways
+shro ff
+de bat
+kh ur
+conduc ts
+format s
+à ©
+port age
+graph ers
+u ten
+pre m
+mo ines
+condem ns
+s ous
+l ps
+f cs
+deal ership
+leuke mia
+bure au
+ski d
+guardi ola
+ca ster
+thir d
+avoi ded
+en cyclo
+c sr
+vi xx
+analy zing
+she ar
+dulu th
+shap iro
+chan ting
+stre sses
+as be
+mil itia
+ãĥ ª
+col lin
+arsen e
+sure sh
+teach ings
+yi xing
+sh ill
+nu des
+sv u
+clear water
+war ped
+pro life
+artist son
+it u
+versail les
+galax y
+ax el
+spring st
+cal a
+hu hu
+sc u
+commit ments
+exe ter
+poign ant
+mo tion
+conserv atory
+row dy
+rec alled
+mu sk
+emb elli
+so the
+âĺ Ģ
+sto pper
+sch ild
+to pe
+el mo
+zi el
+j om
+barn sley
+snow den
+on tour
+jour ney
+hills borough
+par ole
+w ts
+mo ving
+ag ility
+tiv o
+ff ers
+kindle unlimited
+g wen
+ann an
+ah mad
+tex tured
+hepat itis
+dra m
+insi ders
+tis sues
+ãĥ Ħ
+fc barcelona
+cr atic
+na acp
+pe can
+f gm
+custom ize
+concer t
+g sm
+pe g
+p one
+justin trudeau
+super cars
+happy holidays
+bu lar
+ado x
+lap tops
+digital health
+destin ation
+gradu ally
+áĥ ¦
+popp y
+ss l
+inhi bit
+star light
+of fro
+glo omy
+x per
+hal der
+im plants
+le to
+hass el
+a as
+un told
+en ci
+liber ia
+or an
+con tests
+il ah
+sma g
+sc out
+mari anne
+cr yo
+schedu ling
+lo s
+kan e
+stutt gart
+ne se
+law rence
+da in
+pho tom
+car ou
+ภ£
+g wy
+national dogday
+roa sting
+band camp
+kentu cky
+stret ches
+ke rel
+ca she
+ãĤ ¸
+sta x
+tran si
+dog gie
+at ric
+hal le
+ci vic
+brow ning
+lein ster
+cat day
+high land
+joy ous
+in cumb
+or lando
+ro mo
+col ton
+del ta
+car ab
+ro tc
+aster oid
+goose bumps
+mo logy
+yo ko
+an ds
+tomor rows
+red carpet
+sm p
+ca sio
+ðŁ¤£ðŁ¤£ ðŁ¤£
+se au
+rejec tion
+rot ating
+bi partisan
+th un
+mat i
+bon i
+ol l
+ener gye
+do it
+l j
+mother hood
+lou ise
+neck laces
+el ite
+ni x
+l cs
+en v
+gl u
+le sh
+cran k
+su sie
+m clau
+so tu
+crow ley
+rat ri
+use d
+bre ton
+alfre do
+ye o
+travel pics
+ti pp
+elli son
+sax ophone
+me red
+heu ghan
+ta ine
+f es
+vi ro
+suppo sedly
+i as
+dige stive
+y le
+li zzy
+wildlife photography
+bri anna
+west field
+ra ined
+am her
+ðŁĺĦ ðŁĺĦ
+distribu te
+bott om
+pre serving
+oil and
+craf ty
+de scen
+col ling
+shakespeare sunday
+r wc
+ang led
+ci an
+t ations
+mon tage
+me yers
+france sca
+ðŁĮ ·
+wi ggins
+san ford
+volunte er
+car ra
+bar k
+vari ed
+pl in
+am u
+kap il
+rock ers
+qu ind
+br ane
+in mate
+ent al
+impro vis
+michi gan
+re tweeting
+progre ssing
+mercedes benz
+smo ker
+physi ology
+dor ado
+watt pad
+h wa
+sr bachchan
+w ga
+vol atility
+hi re
+ac ap
+wn ba
+hein z
+stit ches
+kidnapp ing
+bur ys
+lim b
+f itters
+thumb nail
+ton e
+mir and
+desi rable
+ad dison
+tar an
+tamil nadu
+spec tator
+soci ology
+amit shah
+remo tely
+âĻ ¦
+ham id
+r ds
+g lee
+smooth ly
+sch ro
+er c
+lali ga
+he als
+us f
+ni shi
+d hu
+un il
+h le
+tro mb
+bhu tan
+pilip inas
+se ung
+whit man
+te y
+min ce
+snow boarding
+re au
+k ker
+av o
+zach ary
+ran veer
+ti k
+gover n
+qu al
+beck y
+anthropo logy
+att en
+grocer ies
+de bit
+war p
+sil icon
+hawa ii
+ðŁĴ ħ
+pomegran ate
+pe er
+orang es
+people schoice
+end ure
+ðŁĴĽ ðŁĴĽ
+ãĤ¹ ãĥ
+ac ial
+a haha
+stu k
+imper ial
+bl ond
+pow der
+kno ts
+vin ce
+wood lands
+den a
+watch in
+mat cha
+ma hat
+galax ies
+middles brough
+k ö
+stre e
+resc ues
+wal do
+lero y
+desp ic
+real ities
+tm nt
+ha q
+un o
+pe c
+bolly wood
+blin ds
+design thinking
+he ms
+and hra
+ab sen
+fan s
+ste ch
+shire hour
+bla ine
+shak ti
+pu rely
+ðŁı ı
+tra fal
+ke ynes
+gr ate
+to bias
+spon taneous
+satur ated
+caval ry
+pri sc
+ðŁĺ ij
+wh t
+pas si
+~~ ~
+vir at
+patt inson
+la o
+weir do
+sym pathy
+ju da
+occa sionally
+cred ited
+stat u
+es co
+hil ly
+esc ape
+dischar ge
+se er
+may nard
+sud bury
+z lat
+or al
+we er
+encoun tered
+sm elling
+over sight
+ê ¸
+that cher
+mack ay
+you can
+fre ep
+freed oms
+prophe cy
+ho e
+ishq ba
+dra ke
+qu its
+pel led
+tur k
+o vi
+wesle yan
+new music
+leg g
+ch eng
+h illi
+ay y
+pan ties
+ad versity
+ad jac
+vaccin ation
+ju ke
+ga c
+exce ed
+time sof
+sta ining
+ep cot
+v ital
+up ward
+bethe sda
+apar k
+ma hi
+camp fire
+enchan ting
+rha pso
+h z
+na ver
+fa x
+vali dation
+ac ad
+ny r
+as ym
+coordin ated
+depar ted
+all ery
+var ies
+spr ite
+chap lin
+ss occer
+s wat
+bre t
+relu ct
+tunes app
+super star
+reminis cing
+o co
+home grown
+dough nut
+un canny
+la pd
+thyro id
+! âĿ¤ï¸ı
+botan ic
+bre s
+sp ade
+i ste
+echo es
+du lil
+bur sting
+qui ero
+ðŁij İ
+loy ola
+amuse ment
+ha ils
+sleep y
+burgl ary
+âľ ı
+ro gue
+cot land
+mo ors
+low er
+wic ked
+ðŁĶ Ĭ
+compet iti
+argent ine
+yvon ne
+karti keyan
+ili ary
+gat sby
+precin ct
+six ty
+na ji
+cam s
+practiti oner
+ðŁĺ³ ðŁĺ³
+pu ne
+neg li
+juli en
+inv aded
+cali br
+cla m
+duba i
+mu k
+lan tic
+produc t
+fe dex
+ï¸ı :
+eu ra
+dari us
+s ling
+virtual reality
+home stead
+ðŁı³ï¸ıâĢį ðŁĮĪ
+pac ed
+in ha
+pul mon
+la zy
+premi ering
+ma stered
+in he
+con gregation
+ba jo
+sport ing
+new jersey
+hor ny
+lma oo
+leng thy
+du t
+yo gh
+swe aring
+philosoph ical
+pap ua
+in ski
+know les
+dy ke
+âĢ ²
+to ken
+mc guire
+ri ot
+probab ility
+mc con
+gro s
+su mat
+c ite
+da a
+on da
+mad dow
+che w
+board games
+spar ked
+re claimed
+ad hd
+ny se
+imwith her
+equ inox
+boo ths
+balsam ic
+ha zy
+dor chester
+ag os
+se aw
+moder ator
+seri ea
+ander sen
+pilgri m
+âŃIJ âŃIJ
+itch en
+hal li
+x ton
+nathan iel
+mun ition
+celesti al
+ga f
+zo om
+mark le
+pen thouse
+cal e
+s fa
+bar king
+tu cket
+em ery
+cal orie
+li que
+ad ar
+mc nam
+tor tilla
+wood pecker
+mo town
+bad ger
+ayr shire
+scram ble
+dd ay
+cra ziest
+per rie
+cho co
+cast e
+i ot
+wre cked
+selec ting
+uss r
+gra ft
+pun t
+lab ou
+ir st
+ba ek
+Û Į
+su ki
+que u
+ach at
+te ster
+aug mented
+wc vb
+sin ks
+ðŁĵ »
+ra ke
+inter ne
+be cause
+belle vue
+une arth
+light en
+ðŁĺ £
+turn around
+labe led
+unemp loyed
+twitter kurds
+le ia
+h ye
+great er
+ðŁIJ İ
+tim ed
+i red
+e tt
+limit ations
+cab e
+s out
+bee ch
+anni hil
+re trac
+yo ona
+ang er
+den nis
+supp lying
+di z
+" (
+sc ur
+gun man
+su ho
+sauvi gnon
+ภ¥
+wi ley
+land on
+choreo graphy
+pre historic
+ðŁı ĥ
+var gas
+assess ments
+pinn acle
+di i
+chamber lain
+ì Ī
+v p
+present ers
+deut sche
+sun shine
+sal utes
+r one
+bu siest
+- .-
+motor ists
+hemi sphere
+al wx
+ps p
+ow a
+den ying
+cho c
+gu tier
+han uk
+mus kete
+jait ley
+se wage
+t ame
+thin kers
+shi m
+se quo
+pap ar
+middle east
+k wa
+ke g
+patag onia
+no y
+bar ça
+take off
+he a
+à ¬
+n sc
+g dc
+ðŁij Ī
+mou stache
+mel ania
+thr a
+â¬Ĩ ï¸ı
+pier ced
+ze us
+fon ts
+ber a
+it iner
+q atar
+contr ary
+ire land
+i fy
+ou los
+commun al
+fin s
+un paid
+pa a
+ðŁijĩ ðŁı»
+ri os
+ou p
+f iller
+cafe teria
+ภŃ
+kas i
+cali ber
+z ulu
+v sco
+ts ford
+dragon fly
+smo kin
+pi st
+psycho logist
+diplom at
+we bs
+buc cane
+à® ¾
+motiv ational
+du ne
+ba e
+c fs
+with out
+er on
+i ac
+ate e
+pen sion
+fra zier
+en sis
+sk is
+par ting
+ger y
+territ ories
+nach os
+eni ght
+ever lasting
+msd honi
+tel e
+sp un
+po di
+sab ah
+environ mentally
+ce ase
+beau mont
+mar ta
+kel vin
+ho ff
+sun il
+n da
+co b
+sh ale
+ree dus
+un boxing
+u bio
+re opened
+n all
+capsu les
+mar r
+himalay as
+swee ter
+ja z
+f mr
+twee ter
+dha ka
+na u
+de mi
+d fs
+ta urus
+fad ing
+it utes
+ci p
+over flow
+jef frey
+don ny
+car tunesapp
+ðŁį ij
+prefe cture
+danc ed
+c pt
+ple asing
+ital k
+earth quakes
+ul ation
+hi o
+ãĢ ĭ
+ant an
+nutri ent
+de ere
+selec ts
+enrich ment
+r iti
+tram pol
+bl amed
+j ia
+contribu tors
+chesa peake
+pi geons
+tribun al
+mad uro
+w su
+ilo ve
+effici ently
+dar cy
+war ms
+ar ra
+ec u
+ho wer
+strugg led
+rajini kanth
+ðŁĺ¢ ðŁĺ¢
+hou sing
+str at
+eli x
+disp ro
+raf fic
+thi erry
+na sty
+c fb
+staf fing
+al ma
+back ers
+hen son
+sky walker
+reale state
+roo s
+ness y
+chan ce
+cair ns
+c ci
+pe dal
+ly ft
+cross word
+wait er
+only in
+kru ger
+k ir
+alej andro
+car tier
+car rera
+re paired
+ou at
+un clear
+un breakable
+today in
+qu eries
+jo dy
+gen ital
+win ner
+to l
+kelown a
+fascin ated
+ãĥ ¬
+sris ri
+squ ared
+spr ung
+negoti ate
+priv ately
+av en
+>> >>>
+g ical
+gav in
+chester field
+zu mba
+or r
+nat alia
+impeach ment
+mn l
+car at
+criti que
+credi ble
+trac y
+tan i
+musi k
+jig saw
+gam bia
+tol kien
+fe u
+as per
+sav ory
+fo xx
+f itt
+mar lon
+l rt
+v ell
+p br
+imprison ed
+i om
+chu l
+wind shield
+kay e
+ba a
+chor d
+s art
+al gon
+minister ial
+nat geo
+la zio
+nor ms
+ðŁijį ðŁijį
+lic king
+fut bol
+un sung
+dalla scowboys
+sh red
+distur b
+dev ine
+be ards
+ch f
+b day
+ro sso
+ig or
+ay i
+si ren
+k air
+sti les
+ro f
+mag nets
+un cover
+mou se
+bang ing
+si ghted
+spe ople
+impac t
+row land
+kir a
+environ ment
+love the
+p sis
+mish ra
+gl endale
+ca jun
+o che
+de ception
+sex ist
+stra ws
+s ga
+buff er
+apost le
+sp l
+pop up
+ðŁļ Ĺ
+r g
+up er
+ball in
+i dy
+occa sional
+national park
+ðŁı Ĭ
+u an
+innov ation
+ภ«
+te aparty
+re tte
+counter fe
+b ha
+rec s
+ig en
+ðŁĮ IJ
+humming bird
+cu r
+ha ven
+la zar
+pue blo
+: :
+zi onist
+op ath
+inver ness
+promo ter
+carto on
+cabine ts
+mahog any
+surve ying
+r ational
+feel ing
+testi fy
+so w
+oc on
+ภ¢
+ne el
+mar is
+sol itary
+che mo
+rad cliffe
+sim ons
+ros ary
+new er
+jo die
+re tali
+pra wn
+pad dy
+hen ge
+k ala
+im plant
+at y
+bren twood
+par adox
+ene z
+re designed
+p our
+wy d
+al de
+௠ģ
+sol d
+biomed ical
+๠Ĥ
+tt tt
+mat teo
+ys er
+new ton
+de bun
+ner dy
+loo l
+wo on
+elisa beth
+ec c
+wh i
+ach o
+salv age
+sal aries
+qu ity
+navig ating
+oph thal
+con soles
+re built
+o pec
+ast ers
+sho red
+set list
+kathr yn
+rhy mes
+re visiting
+ash ish
+li ft
+re post
+sole il
+âı ±
+weal th
+sa at
+we c
+king james
+flipk art
+field work
+se gu
+mo dal
+bu b
+are rs
+ðŁį Ĵ
+clo oney
+pad dington
+necess ity
+guth rie
+pen te
+li mo
+jo sie
+ar tin
+en c
+l hs
+betra yal
+info graphics
+i er
+mo a
+hear ings
+bon jour
+sym bolic
+ag ro
+wed ges
+krist ina
+wild flower
+athle tic
+photograph y
+pe sh
+ca hill
+chi lean
+gou l
+fi oren
+ðŁij ¶
+z il
+sk im
+bad oo
+deli a
+tre ble
+n cc
+ðŁĩ¦ ðŁĩ
+a house
+bul lock
+sol itude
+ا٠Ĩ
+can cers
+futureof work
+hu tch
+water shed
+war mongers
+sp illed
+colom bo
+mo th
+associ ations
+weigh ed
+global goals
+not just
+christ i
+tor g
+swe ating
+man eu
+clu sters
+â̼ï¸ı â̼ï¸ı
+ta ped
+ul y
+tru sting
+yu suf
+te in
+ra b
+, ,,,
+sin ai
+audi ble
+explic it
+cro wns
+sch iz
+at least
+ðŁĹ £
+de bra
+je suit
+ene gger
+z hen
+one sie
+i it
+ss f
+gur gaon
+chak ra
+bear cats
+k ran
+k awa
+reque sting
+han over
+g end
+sor os
+mer cy
+lovel y
+do omed
+tim my
+ku z
+ul l
+ab ram
+sa ison
+ãĥ «
+clean ers
+re mo
+circu its
+bar red
+o th
+mo ist
+madele ine
+gall o
+u j
+per mits
+hea viest
+car ols
+az te
+gior gio
+flo ats
+decl aring
+us rc
+min at
+craf ts
+pri ma
+conven i
+nickelo deon
+danc ing
+ceremon ial
+blo gg
+tw p
+anglic an
+she k
+k nick
+( ((
+hubb ard
+harve y
+hit man
+fen g
+we some
+for za
+s word
+op us
+bro m
+gi bility
+z al
+m unch
+dance hall
+gre edy
+hd mi
+re birth
+ðŁĺĭ ðŁĺĭ
+s world
+figur ine
+com post
+k f
+engra ving
+gior no
+st ana
+k man
+ham ster
+compos ers
+aj e
+func tionality
+pol k
+is ons
+air planes
+te se
+hor rors
+musc at
+gi ven
+sp ence
+ðŁĩ¸ ðŁĩ
+eli ot
+ach illes
+fre ck
+crypto currencies
+sou ther
+hal o
+bor neo
+polit ic
+hahahaha h
+up state
+si ena
+obsc ure
+hau sen
+lloy d
+happy friday
+motor bike
+bon a
+americ as
+hol s
+- (
+spor ty
+un aware
+reven ues
+christop her
+bank sy
+av an
+ev apor
+com press
+eyel iner
+to dos
+buff y
+renewable energy
+ly rical
+ar chan
+rapi st
+fair trade
+lma ooo
+beat z
+pro active
+la pse
+ir ical
+revers al
+po de
+mcin tyre
+mac au
+ãĥ ķãĤ
+nash grier
+f sa
+g all
+çĶ Ł
+perpe tr
+il ya
+configur ation
+% ;
+str ange
+rac i
+ภĩ
+pic kups
+kov sky
+mam mal
+w ps
+g able
+compar ative
+z h
+save our
+da vey
+on etsy
+mu ssels
+mis er
+cri stina
+electr on
+cra ve
+lo ren
+precipit ation
+m z
+ðŁį «
+vin cen
+snow board
+no ida
+ah n
+marin ated
+g tr
+town hall
+min is
+bethe l
+adv an
+su ra
+shi el
+fur ry
+ðŁĺĤðŁĺĤðŁĺĤðŁĺĤ ðŁĺĤðŁĺĤ
+lyn d
+so il
+sc ence
+sen eca
+shar jah
+dick ens
+credenti als
+av ar
+per k
+requ iring
+pre fer
+j ian
+de ca
+r ach
+ing for
+del e
+be ep
+ðŁĴ »
+cis ely
+hu ddle
+green sboro
+haw king
+ho ax
+hang ar
+ç ľ
+mis o
+lo vin
+gre ta
+ab ad
+logi e
+at an
+snow flake
+mahe sh
+fear the
+al kal
+bobb lehead
+ba hn
+ju dged
+fu tu
+feli x
+ðŁį ĵ
+pi ke
+der iv
+notic es
+au er
+dis super
+or da
+wi pes
+am ino
+stri kers
+foo tb
+dram as
+pun ching
+score less
+heming way
+bi h
+bal lad
+chat ter
+am mo
+kle in
+fabric ation
+kari m
+z end
+hi sto
+vol ta
+rock y
+marke ter
+xtre me
+sequ encing
+paradig m
+cle ats
+boom ing
+âģł âģł
+block ade
+promp ts
+yogh urt
+pur pose
+nu r
+regu late
+nois y
+ing rid
+bird watching
+bar tender
+Ù ĥ
+wor dof
+cha otic
+shor ty
+el dest
+z app
+onceupon atime
+fl yo
+rit os
+mike quind
+ðŁIJ ´
+regi stering
+. ]
+ad ol
+gg gg
+pur ge
+kid lit
+ar bor
+val ves
+synago gue
+o th
+unanim ous
+veri fication
+dar rell
+ãģ Ħ
+vander bilt
+tape stry
+pro sper
+did dy
+dra fting
+de cep
+marqu is
+st int
+michael jackson
+pee led
+men us
+bb b
+sc are
+ema il
+wri gley
+it is
+f ell
+some thin
+bar ra
+ed gar
+di pping
+pu ddle
+sla de
+lear ner
+jal en
+ðŁ§ IJ
+the daily
+mikequind azzi
+ju x
+iq bal
+mckin ney
+ra iser
+ef an
+dr one
+cat o
+pic ket
+cro we
+l att
+uk o
+giuse ppe
+hin i
+synthe si
+ponti fex
+song writing
+to d
+swit ches
+din ners
+h q
+gabri elle
+pensac ola
+cir cle
+expo ses
+ev s
+riyad h
+pro men
+o ck
+sa j
+cit ation
+brew co
+jo si
+ep aper
+dri f
+point less
+tang led
+cri pp
+line ups
+fairi es
+daz e
+mour n
+bla dder
+sal z
+bur undi
+book mark
+the people
+sub sequ
+princi pal
+sk er
+court ney
+a oki
+rac ers
+ad m
+mom a
+critical role
+hou n
+shed ding
+sa ka
+ace ous
+mck ay
+hus bands
+Â ½
+me da
+accu sations
+ro sel
+nc is
+witne ssing
+or ama
+go ds
+hil ton
+el man
+ÃŃ n
+meg ap
+cra ven
+announ cer
+crit eri
+sheffiel dissuper
+milit ant
+consu l
+hoo ded
+aby ss
+b x
+ma dam
+lo cu
+mary am
+manic ure
+grat is
+ac tresses
+ros ario
+this dayin
+king ly
+gn ome
+cel ine
+r ous
+he el
+lil ac
+vish al
+ab h
+thor ns
+s ls
+ne al
+construc ting
+be ren
+s lang
+ma ins
+far ra
+sar ko
+pai ge
+gu iller
+l ala
+ice berg
+nou n
+plann ers
+u mmm
+ou ses
+ill ary
+ma an
+box ing
+zi pper
+srin agar
+migu el
+o str
+mp o
+responsi bly
+lan terns
+appli ance
+x b
+gren ade
+neglec t
+dy sle
+ham mock
+ne ctar
+wit cher
+r gv
+di ence
+ser bian
+seed ed
+cru z
+bi sh
+sp he
+e q
+sky rim
+alge bra
+phil ately
+bungal ow
+ge off
+y ves
+demand ed
+consider ations
+the vamp
+pawan kalyan
+co ded
+grit ty
+erup tion
+se infeld
+uni denti
+ëĭ Ī
+wor m
+ac us
+se ung
+dun g
+ro land
+su d
+di visions
+ab lanc
+shor test
+j f
+p oun
+plant based
+be to
+tough er
+mc o
+don et
+mark us
+v fl
+ðŁı ł
+open ing
+co ward
+caber net
+o xi
+burle sque
+sand ra
+su mo
+consi st
+tho t
+cay man
+motor ola
+gutier rez
+d slr
+y w
+no bel
+nov ice
+moms demand
+grun ge
+sp or
+d cc
+pre sses
+sli st
+allot ment
+voc ational
+ft c
+pu ja
+lo ven
+utt arak
+tan dem
+sh ep
+come dians
+anat om
+cant wait
+healthye ating
+west side
+mar gins
+chi ang
+asbe stos
+stupi dity
+proble matic
+fit bit
+: $
+ceil ings
+shu a
+protec tions
+bio tic
+beng ali
+re sts
+bien nale
+tim o
+cul min
+e minent
+affe ction
+unbeliev ably
+individu ally
+canvas sing
+wh itt
+nov asco
+chin son
+h pe
+go w
+gloucester shire
+pa o
+thresh old
+chev ron
+s ine
+we ther
+pp ie
+aqu ino
+antwer p
+âĸ ¬
+po on
+inst af
+equ ine
+cinemato graphy
+nbaf inals
+vali ant
+kil kenny
+te rence
+syste mic
+sr l
+p ound
+made ira
+pl ough
+tre cht
+mat ed
+mp d
+ransom ware
+ph in
+li qui
+bb ce
+boom er
+i standwith
+con ju
+r te
+nar a
+foo lish
+da shing
+vier nes
+br ite
+da u
+juni per
+ai da
+you now
+ra zer
+de i
+repe ating
+comfor ting
+adjac ent
+e to
+ca sted
+chat ur
+mu er
+syn th
+san itary
+mac le
+independ ent
+law ful
+e erie
+h or
+ðŁĴ Ń
+am rit
+vel o
+station ery
+mu f
+may may
+contempl ating
+elabor ate
+gre gor
+dri es
+ac col
+ภļ
+schwarz enegger
+ill nesses
+day break
+follow back
+collu sion
+electr onic
+jo vi
+hiro shima
+ta w
+hom ec
+mic ah
+qu itting
+fro sting
+ben fica
+hel i
+s ical
+pic cad
+corpor ate
+ment orship
+you are
+sing er
+shi va
+ru ne
+ing er
+ri um
+play able
+doo p
+wil low
+ter re
+ni p
+at d
+war bler
+profession ally
+er ase
+proce ed
+pedestri ans
+mis chief
+ben ding
+alas kan
+c kett
+mo p
+dd les
+shut ter
+ge ared
+atene o
+ma deline
+g ations
+o sha
+der ick
+sw ild
+an gry
+pat ents
+hun k
+decre ased
+fr y
+ðŁĴĸðŁĴĸ ðŁĴĸ
+sal on
+quant ities
+d ario
+ni gel
+ku ma
+jen n
+happ ye
+xx x
+rex perience
+pro s
+au sch
+rele ssly
+ham burger
+fuku shima
+er ne
+stat ec
+ren d
+may field
+j one
+lef ty
+bern stein
+sm il
+gener ates
+fore station
+band its
+ta yo
+r ca
+ac ci
+rodri go
+kn app
+elo vers
+vege tation
+u ral
+le ft
+ħ ï¸ı
+worl dre
+sur i
+embar k
+w son
+ba you
+mu ller
+mo vers
+ðŁķ º
+presby ter
+l f
+cre e
+bat b
+sal am
+demonstr ations
+an ec
+n pc
+it ics
+to graphy
+re inst
+thur st
+tal e
+off ences
+smart city
+bro tha
+ofthe year
+in valuable
+ear n
+ðŁijı ðŁı½
+kre mlin
+gra dy
+town fc
+guern sey
+ma ha
+contag ious
+dre x
+be en
+( £
+nati vity
+k tm
+somer halder
+comp ounds
+íķ ĺ
+" â̦
+af g
+ott news
+h ound
+fire fly
+cil an
+donet sk
+volunte ered
+ak ira
+è ª
+sing ul
+st h
+dro wned
+mand o
+he ir
+ðŁİīðŁİ Ī
+tax is
+y uki
+vel d
+k ans
+el k
+ran ts
+hash tag
+t eng
+ro g
+a at
+gru b
+e ber
+in india
+colo ssus
+sig ni
+so ever
+mile stones
+der o
+differen tial
+phu ket
+master mind
+an gh
+mel ani
+bro ker
+actor vijay
+stun ned
+continu ity
+af fl
+vo cal
+perenni al
+fianc é
+in complete
+hun ts
+re issue
+domin ates
+tur meric
+ro am
+ri on
+bag ged
+nas sau
+fu t
+x ox
+national trust
+jo ye
+san o
+hearth stone
+dis respect
+le es
+h se
+siber ian
+offe e
+re stock
+wolf gang
+re gan
+plan o
+un wind
+re par
+mil le
+] ,
+skul l
+fat ally
+concep tual
+ðŁĮ ²
+f é
+ber to
+b ms
+u a
+mag na
+notre dame
+le te
+la undering
+heartw arming
+buffe tt
+go at
+pe abo
+wind mill
+v ac
+continu ally
+az alea
+mem brane
+can cels
+make yourown
+athe red
+p to
+tor pe
+ðŁĺ ł
+ðŁĴ §
+sc ares
+le aking
+z et
+pix els
+ac i
+kh il
+marath i
+ðŁĻı ðŁı½
+u la
+tam u
+chandi garh
+z agre
+aa b
+pronoun ced
+aubre y
+sand er
+pun ta
+har low
+ic elan
+celebr atory
+so t
+unci ation
+stru ly
+mc dowell
+deepi ka
+remin ders
+my stical
+ct c
+chat ted
+s ica
+bar gains
+ch hat
+ru bin
+m net
+oiland gas
+pel ican
+o at
+mor ality
+k our
+i h
+nu clear
+gc u
+ric her
+vene zia
+m ma
+le ith
+ac company
+rich mond
+sports net
+ba ahu
+smu ggling
+mm i
+ðŁĩ®ðŁĩ ª
+twi sts
+sahi b
+.... .
+amb itions
+il lo
+histor ical
+fo rec
+show biz
+pon ies
+chas ers
+remo del
+will ing
+prince sses
+am ple
+cushi ons
+ac les
+lot r
+da ch
+an the
+in corporate
+new bury
+ki ri
+fried rich
+ab v
+ball ers
+alber t
+ðŁij Ń
+let i
+nan op
+ci de
+anal o
+n sf
+)) ))
+griffi ths
+valen ci
+ro ano
+fun run
+babys itting
+ca day
+ent re
+u ck
+slu g
+tic al
+the sims
+ro ar
+car ney
+g am
+sto we
+fi d
+bun ny
+sham rock
+pe cu
+mol ina
+go cougs
+con tributes
+transform ation
+mo y
+v aj
+sever y
+antioxid ants
+thir teen
+sight seeing
+l j
+reversi ble
+odd ly
+hoo kah
+nou vel
+hal al
+fe i
+stab les
+mul t
+ho pped
+bra ids
+inter change
+ghana ian
+ww ww
+eth no
+con junction
+ago v
+ye ti
+earth and
+ts p
+con serve
+heir loom
+metaph or
+woo f
+tor io
+self less
+n wa
+em ilia
+yl ene
+y xe
+gi ar
+moder ating
+pro bz
+b fi
+ne er
+du mmy
+hanuk kah
+we bber
+k v
+eye brow
+dag ger
+su mp
+ra ges
+ork ney
+tb o
+hal sey
+assign ments
+tr onic
+scri b
+co on
+an war
+# âĢİ
+jal ape
+flori da
+qu aid
+haw keyes
+âĻ¡ âĻ¡
+street car
+ro g
+dat lantic
+gran ola
+un changed
+expect ation
+Ù ĩ
+mar lin
+gu mmy
+ðŁĻı ðŁı¾
+awareness month
+oil painting
+mu th
+per ch
+jun to
+villa gers
+mor g
+che ated
+web comic
+the future
+d ps
+la kings
+men tioning
+vo or
+ident ities
+accor d
+mc gu
+l pga
+rum our
+massi vely
+m pls
+heal y
+d ate
+sp oli
+re visited
+on t
+al and
+scru tiny
+lakel and
+bl ending
+< /
+an kara
+jami edor
+metab olic
+f ences
+ann y
+å ħ
+semic on
+oo tt
+space ship
+wack y
+le ta
+ap ac
+she e
+in herit
+do res
+ðŁĩ¨ðŁĩ ¦
+gent e
+tw ick
+ri ms
+gal ve
+de ville
+king fisher
+scorpi o
+ow l
+al ar
+vari an
+ðŁĹ ĵ
+vene tian
+star dust
+then orth
+q ing
+har rington
+consul ate
+spectac le
+ho bbs
+tur ks
+gre er
+mat ing
+ðŁİ Ģ
+ðŁĮ Ģ
+direc ts
+í ĭ
+pompe o
+vo iced
+la os
+tz u
+pro me
+pri sm
+mer c
+fortun ately
+bc fc
+mcdon nell
+not sorry
+smi led
+t ba
+for war
+mid term
+dar by
+we instein
+up grading
+wol ff
+bron co
+cab ello
+ðŁ¥ ĩ
+fi able
+shar pe
+bat tered
+sat o
+myth ical
+instap ic
+pre pped
+eni um
+e spo
+di aper
+explan ations
+who pping
+ragn ar
+pe el
+antibio tic
+l acks
+harri son
+li sm
+au l
+qu ail
+martin a
+sent encing
+sc ams
+di di
+tr onics
+ãħł ãħł
+go ff
+za in
+param ore
+cha ined
+clin ton
+li ff
+cott ages
+em on
+reve rend
+consu mer
+ce an
+t any
+lum pur
+e bay
+sto ol
+ðŁĺ» ðŁĺ»
+ta pro
+h ath
+modern art
+just ine
+prover b
+app y
+tra x
+mani fest
+am bu
+nai k
+pe pp
+r sd
+mer chants
+kitch ener
+shi fted
+li zz
+âĺħâĺħ âĺħâĺħ
+âĢĶâĢĶâĢĶâĢĶ âĢĶâĢĶâĢĶâĢĶ
+uto pia
+tom o
+ou ted
+com ers
+chiroprac tic
+book club
+cin dy
+pro hibition
+se uss
+ë¯ ¼
+thin kin
+rr rr
+go fund
+t ack
+om b
+catastro phic
+ling u
+guild ford
+bo td
+ॠĭ
+plan ter
+^ ^
+win k
+kath mandu
+sto ppers
+smooth ies
+re efs
+hin d
+bell amy
+Ħ ë
+waste water
+vo or
+nat l
+! ]
+re el
+y ap
+scoo by
+work space
+corin thians
+bl un
+obli gation
+g bbo
+dy son
+cra vings
+ell ington
+dap l
+wre xham
+earthand clouds
+uk runchat
+positi oned
+kal b
+four square
+jo ck
+im pending
+even ing
+ath y
+pro claimed
+c ites
+ann apolis
+san i
+mar th
+ir l
+accom mo
+ka a
+fin a
+y aa
+di sper
+ec ar
+bha k
+will y
+ðŁĺĢ ðŁĺĢ
+mcder mott
+mo j
+gener ational
+u said
+train ing
+lon ely
+lo res
+impe cc
+âĢ IJ
+beav ers
+ma ki
+he b
+aap l
+å ı
+wolver hampton
+leader board
+me u
+c fa
+easter n
+hu r
+civil war
+ou rage
+hor ned
+le high
+awar ds
+evi dent
+gi gab
+r ous
+ma del
+ro byn
+ur gently
+k ors
+en as
+heis man
+bam bam
+fab ian
+f om
+evalu ating
+assemb ly
+out sourcing
+hun tsville
+ðŁĶ ª
+justi fied
+cashi er
+sp aper
+buc keye
+analy tical
+illumin ati
+au tho
+o j
+sha de
+geel ong
+wh ey
+he aton
+terri bly
+ele k
+un charted
+sd live
+moto cross
+her mes
+dar shan
+dar lington
+cash mere
+gri pping
+cilan tro
+pun ish
+... :
+ðŁĴ Ħ
+inst ance
+der i
+lo bal
+muk her
+sp ar
+thin ker
+fre mont
+com piled
+color ado
+vig ne
+sm d
+whe ad
+villa ge
+le ek
+formula e
+ta res
+persist ence
+?? ????
+ped ago
+he z
+alzheim ers
+vul ture
+off ence
+is great
+suff ra
+kick in
+h mmmm
+broad way
+ï¸ı @
+art i
+alli son
+endor ses
+ry u
+lolli pop
+soy bean
+kend all
+cer a
+inv ade
+( ðŁĵ·:
+conver ter
+car pets
+ho bo
+fr it
+pe ac
+es qu
+ern an
+ou f
+an il
+di ffer
+ch ing
+bre cht
+sp g
+daven port
+stra va
+sever n
+n gos
+stor ians
+fe te
+parame dic
+j hb
+al amo
+sne aking
+gold coast
+roof s
+isi l
+depic ted
+projec tions
+nu mb
+o ss
+ep i
+glu cose
+zid ane
+infin iti
+íĺ Ħ
+ran som
+ton ics
+fal k
+g ler
+ou tw
+re ss
+week ly
+the on
+n ole
+ðŁĩªðŁĩ º
+vol ley
+sum mar
+neg ativity
+sam son
+ye w
+aus votes
+ju l
+ju dy
+f art
+pra yed
+pal ate
+multicul tural
+double header
+cycl ones
+pier re
+ãģ ¨
+âĺ łï¸ı
+rt w
+conver ting
+wir ral
+l ari
+ir relevant
+austin mahone
+an che
+ya an
+sd f
+$ .
+explo ding
+ulti mate
+prof ici
+gofund me
+cell ence
+ep stein
+bul lied
+sep tic
+à® ¤
+lu mber
+cu ff
+vsco cam
+pl or
+ภ¥
+se ok
+ro to
+venezu elan
+sor ta
+spir ited
+daniel padilla
+team sisd
+radio active
+icelan dic
+ðŁĴ ¤
+ver e
+accommo date
+shi pp
+ot ter
+ol ina
+e go
+su la
+san antonio
+de as
+simil arities
+âļ ¾
+y om
+bro ward
+å °
+can cun
+veri fy
+on te
+candle light
+ìł ķ
+inf ants
+az am
+ðŁĺ °
+le ven
+un stable
+bloom ington
+x ford
+con tour
+y p
+innov ator
+histor ies
+po y
+lolo lol
+ex pires
+cat alo
+bill boards
+an ab
+el ic
+novasco tia
+fa ire
+ìĿ ´
+rock well
+gr ille
+az tec
+joh or
+ur struly
+fi ren
+dun lop
+id le
+port man
+jo es
+tx hsfb
+hol m
+cham ele
+under world
+lo ss
+ti em
+therap ists
+past ure
+pa ste
+ing now
+vul can
+ra gon
+lar kin
+o shi
+ho co
+child hood
+umb rel
+success or
+kath y
+iz en
+° ï¸ı
+share holders
+ol ga
+ai b
+he ap
+fl aming
+ro u
+air tel
+rat t
+z ane
+vo w
+thor ough
+sn ag
+par th
+un conscious
+ve y
+new release
+gh ee
+croati an
+facilit ating
+swan son
+astor ia
+to logy
+master y
+ðŁ¤ ij
+bil bao
+trou pe
+the ori
+chey enne
+ro tt
+shore line
+gra sso
+master chef
++ )
+vi x
+ellen show
+as g
+an ak
+ku ya
+safar ilive
+debu ting
+blu m
+list ener
+v ins
+book shelf
+smart cities
+makeyourown lane
+; ;
+ðŁIJ ¯
+ri zz
+on ward
+bull dog
+bear ish
+vir uses
+fri gh
+lin den
+we iser
+sn t
+gon a
+dre sden
+fl anders
+cu k
+wheel ing
+ba u
+atu esday
+surf ers
+swi ft
+mc call
+arbitr ation
+aw d
+mon c
+b ine
+at x
+re fr
+mi ro
+po sey
+n are
+rit ter
+âģ ¦
+play book
+blow out
+sports manship
+s oooooo
+malay alam
+gri ms
+bur bank
+infin ity
+sar gent
+oit nb
+joseph ine
+ski pping
+par kin
+excur sion
+semin ars
+jo har
+par tridge
+post game
+ll ll
+blan che
+temp ting
+m na
+lu ka
+is ers
+to ffee
+bar ron
+he mmings
+sa e
+go hawks
+cu pid
+li mbs
+con se
+un common
+z ada
+head shot
+so ils
+pione er
+mam ma
+sem itic
+pan dey
+jamiedor nan
+spl its
+vel a
+son i
+ra ff
+t mobile
+âŀ ĸ
+pra wns
+lit er
+enjo yment
+egg plant
+tu b
+cultur al
+us ic
+suspici on
+sy cam
+summ ed
+ma du
+ho ck
+up wards
+eye ing
+ri ve
+assas sins
+âĤ ¬
+out fy
+chi ves
+t ner
+la is
+por ridge
+sad dest
+w cc
+vick i
+sna ils
+biz italk
+mill an
+ðŁĮ į
+sam oa
+j ing
+mi key
+gu j
+chel ms
+eli gibility
+arma da
+thro p
+surger ies
+ãĤ ¿
+mo hawk
+ex its
+me m
+is lington
+c me
+land fill
+kait lyn
+ðŁİ ¼
+combin ations
+tomorrow land
+ver b
+cor a
+pre cisely
+na om
+ðŁĨ ķ
+shr ink
+sof tly
+merce de
+mand el
+poo dle
+ball erina
+sop h
+jux ta
+y at
+ary an
+hesit ate
+lo wered
+gu lar
+dungeon sand
+ron an
+my ri
+sp f
+men opau
+gra sp
+pa thi
+fe asi
+fla w
+shi story
+ste ward
+gg le
+fay re
+cli que
+credi bility
+yo g
+sec tion
+mu sko
+se ville
+no tt
+cal m
+mate o
+indic ted
+fi ba
+by l
+lin o
+u kin
+!! #
+enig ma
+siri us
+bu sc
+ðŁį Ĭ
+mac kerel
+psal ms
+a at
+tomorrow spaper
+ðŁĺ ĸ
+p fc
+........ ...
+shre k
+mul let
+o sh
+danger ously
+immen sely
+am ur
+ðŁį Ĥ
+pro por
+sy a
+london marathon
+abo ve
+obli gatory
+pro v
+ra cha
+alex is
+pri mary
+sh h
+ether net
+d stv
+cou gar
+un lucky
+ni l
+steak house
+mel a
+fc bayern
+cause way
+ca therine
+fluore scent
+nx t
+to kyo
+au sp
+releg ation
+qui zz
+shored itch
+proud tobe
+promo s
+inter acting
+home brew
+da esh
+w pg
+stead ily
+provin ces
+bal lots
+i ah
+al to
+< <<
+you u
+ri ley
+prefe rence
+tra verse
+incen se
+am munition
+ho dges
+# @
+hail state
+tart an
+witch craft
+vent ilation
+liber tarian
+! â̦
+ow es
+% !
+ong chang
+bru shing
+le ic
+fi ber
+under attack
+down load
+ex pir
+hy o
+pompe y
+mc bride
+y ag
+stre e
+com bat
+ten ding
+ai ra
+gug gen
+ab ra
+in na
+fli ps
+aw al
+m ach
+dol lar
+inspir ations
+z um
+o du
+it ty
+video game
+aqu aman
+har u
+bel fast
+je b
+but ch
+us gs
+calcu lus
+go yal
+mor gen
+x finity
+stand up
+contrac ep
+sab re
+na be
+in secure
+gener ously
+epit ome
+l w
+t ca
+narr atives
+don nell
+pand as
+ber gh
+tu t
+ker al
+fel icity
+br ampton
+quinte t
+nom ore
+ðŁĶ ij
+lo i
+alham dulil
+ðŁĶ¥ ðŁĶĹ
+ston er
+shaw l
+clin ical
+bren dan
+gon e
+fla wed
+tri ppy
+j g
+al location
+po aching
+ve vo
+mo cks
+lef tist
+bon uses
+condem ned
+abil ity
+st ating
+microbi ome
+bio logist
+for you
+wahl berg
+ss or
+ift ar
+w ul
+ÑĦ оÑĤ
+pom er
+me me
+ver te
+tre ll
+tra it
+in let
+hormon es
+deliber ately
+vill ar
+battle ship
+p bl
+tw enti
+ho kies
+dal ail
+say a
+may fair
+han s
+die ts
+⾨ ⾨
+od in
+hot spur
+pap i
+k ana
+k amp
+fin na
+flo tus
+ti ans
+unic orns
+tribe ca
+chang ers
+fore ground
+out a
+inv aders
+gett ys
+tomorrowspaper stoday
+mac millan
+hand written
+w fp
+u de
+state of
+base d
+âĺģ ï¸ı
+cas m
+psy ched
+histor ians
+fol d
+d da
+ag grav
+p ans
+green way
+au sv
+ðŁĺ ¶
+shradd ha
+inde x
+be sti
+zim mer
+t ness
+eye shadow
+ot te
+go ts
+distribu ting
+pro min
+yo l
+ace a
+tram rahim
+hoo per
+supre me
+jam min
+intu itive
+quali fications
+sli m
+sid di
+jay ne
+tri pping
+g tx
+pun s
+e manuel
+om g
+mid summer
+in to
+succul ent
+ri en
+new mexico
+o or
+hoo king
+in f
+ðŁ¤ Ŀ
+flir ting
+na hi
+g friend
+t ps
+hel ix
+z s
+on ie
+ct f
+kri s
+irresi stible
+fla p
+ðŁijıðŁı» ðŁijıðŁı»
+us wnt
+ru d
+ram ps
+pin oy
+ot w
+lol z
+low ering
+favor ite
+t mc
+phra ses
+her mi
+aver aging
+em br
+ben o
+estu ary
+sle eve
+ribb ons
+ta sh
+ภ¹
+x f
+aw gs
+sun ited
+brew eries
+anir ud
+pun ches
+ol die
+ip ads
+wi fey
+land lords
+d ji
+gun ner
+íķ ´
+tex an
+ex op
+cas sandra
+s off
+ðŁļ «
+igh ton
+bak ers
+awareness week
+v all
+ear p
+bts bbmas
+apologi zes
+âļĵ ï¸ı
+was ps
+states man
+snat ch
+watch dog
+ra fi
+after party
+spi ke
+j er
+peri ph
+r nc
+mu ll
+le en
+shi es
+li eu
+urstruly mahesh
+mer ton
+de sai
+shi f
+ðŁĮ ±
+pe dic
+gos ling
+arrang ing
+ww g
+gen y
+you uu
+netfli x
+e ttes
+k wi
+bernar dino
+am iga
+Ø ¨
+kashmir i
+t ings
+emer itus
+de cat
+ab domin
+dc i
+pha ses
+d jan
+be am
+op ry
+i shed
+the ellenshow
+the st
+habit ats
+to ons
+mclau ghlin
+ri pper
+micro biology
+tal aga
+clu eless
+ss u
+cro che
+bro mance
+longe vity
+zagre b
+prev ented
+tra ve
+spo ilt
+darry l
+migra ine
+al cat
+dd dd
+vi v
+ser pent
+mat tel
+jam a
+con quest
+î Ħ
+sam sung
+presbyter ian
+ket ch
+fire fox
+mo tif
+le c
+cho pping
+cher no
+j ann
+ðŁIJ °
+pro lon
+wake up
+conver gence
+mersey side
+heart broken
+lo oming
+hal lucin
+mai ze
+commun ism
+mo h
+twitter storians
+serge y
+res eller
+favor able
+ed gy
+re iter
+mal aga
+live me
+ka hn
+pul sion
+big g
+kim kardashian
+ati o
+tyr anny
+ru ption
+q ant
+pro ven
+by z
+pu shaw
+kri stin
+e er
+tar dis
+ri z
+awak en
+mi ko
+un documented
+path finder
+indirec t
+resemb les
+h ler
+conce aled
+scand al
+re im
+d nb
+cr itters
+attend ant
+apprentice ships
+aa u
+scre amed
+l su
+fa h
+har bour
+ed d
+bat sman
+li ss
+mi sha
+spani el
+it f
+advan cement
+fa c
+close up
+cecil ia
+medi c
+narcis si
+lav ish
+gi ac
+ma ys
+le it
+wine wednesday
+pushaw ard
+let to
+curren ts
+bug atti
+out ine
+w j
+un do
+ler osis
+devo tional
+ðŁij «
+on na
+fais al
+sa una
+himach al
+am ii
+à® ®
+di zzy
+screen writing
+ph x
+sp n
+ick i
+ag irl
+fi shes
+wb z
+pi m
+bo ar
+ac id
+! ..
+rocke feller
+n ga
+dra stically
+simpli fy
+dru mming
+autum nal
+gur mee
+lor de
+jo ann
+give up
+b our
+am ura
+der land
+sim pler
+wat son
+tri dent
+concor dia
+bel lum
+bre k
+dum plings
+vi on
+dungeonsand dragons
+sp ri
+ascen sion
+wil datlantic
+u st
+rob ins
+legi on
+insi st
+jar o
+gue ss
+so b
+bigh it
+pool side
+negoti ating
+mc gill
+bil d
+techn icians
+miti gation
+ajay devgn
+b to
+ant en
+cosmo politan
+ðŁĺĬðŁĺĬ ðŁĺĬðŁĺĬ
+patri oti
+temp er
+promen ade
+nav ajo
+nam m
+wrink les
+dc fc
+le ach
+bru nette
+r f
+cout inho
+al ti
+tradition ally
+op tome
+na z
+accord ingly
+rec ard
+de ets
+sw ell
+po sure
+whit ening
+strang er
+illi on
+here ford
+u wu
+ro bber
+cotsw olds
+cl en
+gor ge
+nam aste
+re lish
+gri ff
+adren aline
+bla sio
+val e
+ê ²
+toler ate
+rail minindia
+jen sen
+ho ven
+el lu
+ob sole
+eisen hower
+unidenti fied
+than niversary
+body guard
+Ø ¯
+i dge
+sch al
+stock port
+sn i
+re taining
+po po
+pix ie
+oli thic
+ki er
+ha jj
+sa z
+cor bin
+!!!! !!!!!!
+v it
+me gat
+de h
+circu it
+af fleck
+theore tical
+hope less
+u ab
+slu mp
+b ice
+jam med
+let stalk
+can i
+side ways
+labyrin th
+re fs
+ha hn
+jare d
+ðŁį ¹
+jam bo
+ph yl
+enhan cement
+c tr
+ful lest
+se ye
+do ba
+cho ic
+yo s
+cb j
+andr é
+re watch
+pri ma
+doctr ine
+for gets
+u hm
+ar ound
+u le
+art lovers
+shi raz
+har th
+ex tor
+Å ¡
+unexpec tedly
+eli us
+y x
+em my
+se ac
+ðŁijĩðŁijĩ ðŁijĩ
+correc ted
+com bu
+wom anc
+cou gh
+what son
+publi shes
+divers ity
+back bone
+lock down
+mesmeri zing
+nor te
+ma b
+desig ner
+í ģ
+ra gh
+mole cules
+get outside
+the beatles
+semicon duc
+nach o
+lun es
+ham mers
+sul tan
+o on
+fe ren
+att ach
+ar qu
+uttarak hand
+s ash
+; -
+tre ad
+i ko
+ar thur
+scandin avian
+r ation
+ga el
+charge able
+fish y
+v ma
+hand bags
+char a
+ay ne
+de fam
+sett lers
+qad ri
+pal ais
+in wx
+apocaly ptic
+poo ja
+a es
+at ories
+proof ing
+n lp
+ts la
+v ina
+li do
+dee phouse
+informat ics
+v v
+pp ings
+di ss
+Ã ¯
+uhur u
+st ony
+betra yed
+b aff
+my ra
+as pen
+allow ance
+tam ara
+ci f
+cor bett
+ser ge
+di go
+ambi gu
+pain ters
+p cr
+p ca
+nom s
+lo ft
+ve e
+opend ata
+ðŁIJ ±
+alex andre
+identi fies
+fantasy football
+re production
+brom ley
+ware agle
+mm er
+p ss
+cu es
+ay at
+hut chinson
+sar ac
+jack man
+ira h
+ap ink
+col s
+aussi es
+ex ecs
+day ton
+ðŁĻ Ĩ
+im v
+har am
+chuck le
+authent icity
+ar do
+incub ator
+ภª
+photo shopped
+embrac ed
+fight for
+gor man
+zz zz
+schol astic
+cri sps
+te apo
+mid night
+ga ine
+col lier
+s ate
+de tte
+å Ń
+imag ine
+i ff
+tw ili
+i fication
+teat ro
+nor ma
+es ur
+emergen cies
+rise up
+r inger
+hass le
+cait lyn
+tranqu il
+vers a
+se b
+over look
+gin i
+bo go
+se re
+may ne
+henri k
+contamin ated
+rhapso dy
+pro portion
+wildatlantic way
+âģ© .
+organis ers
+tran e
+stand ard
+sper m
+laun cher
+ric ci
+her ts
+paper work
+showcas ed
+mer yl
+pen a
+p imp
+disa strous
+^. ^
+phar a
+x is
+fron tal
+sw irl
+sp ills
+swag ger
+smart watch
+sizz ling
+savi our
+cat ar
+bb cr
+refurbi shment
+dr is
+citro en
+absor b
+patrioti sm
+il leg
+chro mo
+fresh ers
+ru s
+lim iting
+ef ish
+down ed
+man dir
+hazel nut
+p all
+mac on
+disappear ing
+quali fies
+bo on
+bar racks
+am ine
+gen dere
+ðŁļ ĺ
+j es
+ãĥ Ń
+qu ito
+middle weight
+sch au
+quad ru
+aci ones
+limit less
+ðŁijĮ ðŁı½
+ch man
+ar av
+regulat ors
+it up
+batter sea
+mil ford
+g z
+tic king
+gh ou
+cru shes
+tu tu
+dread ful
+fam ine
+for change
+dalail ama
+ðŁĴ į
+whit aker
+hash mi
+h us
+vo d
+bet te
+aa ah
+iso o
+ðŁ¥ Ī
+ha ar
+la ine
+b v
+all day
+spr out
+indie games
+free bie
+gree ks
+but ler
+ill in
+ha al
+ware ness
+si ma
+public health
+gam a
+wa a
+oun g
+goo oo
+okin awa
+off enders
+im pose
+ho c
+young ster
+story teller
+sc ap
+figh ter
++ ,
+whit es
+music monday
+re za
+go ducks
+bri a
+mi um
+cas per
+cru mbs
+a ad
+marti alarts
+ch p
+ri gged
+tn g
+harve sted
+sa k
+do jo
+mill wall
+b nw
+oc d
+histor yof
+t mr
+si rens
+fan ci
+caregi vers
+vir a
+son i
+recur ring
+acknowle dged
+ðŁı Ł
+oph ile
+bu cky
+stre ssing
+roo k
+di gger
+vi val
+san do
+fle et
+si ers
+sel caday
+refre shed
+anti fa
+a que
+po lo
+disappear ance
+de mb
+âĮļ ï¸ı
+ren ted
+ber ger
+g mb
+cu la
+ss al
+goo dy
+u hh
+marcel o
+w anna
+soft ware
+shop small
+turt le
+tom as
+fri sco
+ðŁĺį ðŁĴķ
+jim enez
+c su
+day z
+an do
+wyn ne
+choreo grapher
+cerv ical
+trail blazers
+ed g
+zend aya
+travel blog
+el s
+whole some
+co g
+lab out
+ar ney
+del le
+su isse
+ma si
+ine se
+om be
+fi ddle
+re claim
+pa u
+wat cher
+sla in
+ber ty
+opti mum
+el ites
+min is
+tur key
+patro ls
+ger ard
+au reli
+wild ly
+wal tz
+br gy
+w ob
+cre st
++ ++
+ve z
+fro sted
+davi do
+the x
+param edics
+p into
+han k
+du pont
+ur g
+fo stering
+micro poetry
+spec tre
+---- >
+ne uro
+fri da
+music al
+galve ston
+e ffic
+sc ape
+pal azzo
+th all
+pro visional
+p js
+au re
+ðŁĶ ľ
+mam amoo
+kit ties
+cre e
+wa k
+lo ool
+lu pus
+cn blue
+Ã º
+ðŁİ ¬
+rac ed
+tro se
+om as
+stri de
+co ors
+⤠µï¸ı
+in comparable
+cy ril
+broad er
+arec lipse
+ðŁį Ķ
+inter val
+ti ru
+co working
+w aco
+a ham
+a bee
+flouri sh
+the times
+ol ini
+kick boxing
+lu cer
+at la
+as un
+casser ole
+mi aw
+lobb ying
+jan ice
+cir que
+re flex
+le ary
+sanat omy
+tem pest
+se mb
+mur dering
+us av
+ro bo
+on et
+p cc
+nati ves
+life of
+sa ha
+ruth less
+rel ates
+appeti zer
+pye ongchang
+nor d
+er u
+a thing
+ug ly
+pl ying
+bran ce
+organ ise
+kend ra
+dat o
+chees es
+par ma
+burn out
+a stra
+pre toria
+adjust ment
+uk u
+sl o
+li ken
+fav ors
+cli ve
+be ets
+snow donia
+go tv
+sy n
+open house
+pan i
+portra yed
+sl ated
+me cca
+ren al
+supportsmall streamers
+staf fs
+da o
+bi ker
+vik tor
+tit us
+admi red
+ðŁĵ ±
+hurric an
+he ats
+gl ory
+photo genic
+mer i
+de por
+burn ham
+or angu
+dj ing
+impre ssionism
+ign ition
+ca i
+w ynn
+de pe
+cove ted
+colla gen
+sau s
+or nam
+administr ators
+ss on
+nh politics
+hahahaha hahahaha
+aspir ations
+r gb
+swol len
+so we
+sc r
+diver gent
+hou ghton
+han oi
+d ory
+ni ki
+land ry
+b cci
+ðŁijĮ ðŁijĮ
+is mail
+tri pod
+her d
+bhat t
+dress age
+tab by
+ingu ish
+hur on
+à³ į
+Ã ł
+to das
+evangel ical
+chor ds
+st john
+slo ppy
+marty r
+face book
+ali ght
+sen sei
+kath niel
+r ites
+zi one
+u o
+revel ations
+weight lifting
+pan o
+nc wx
+ac ton
+à® ķ
+Ø ²
+som a
+ภĹ
+respec ting
+mar che
+fore man
+be tty
+ki k
+shi bu
+po on
+argy le
+k swx
+et z
+mar bella
+brac kets
+stand by
+fire side
+defi ance
+v ex
+britanni a
+in habit
+appo int
+piyu sh
+le ash
+sci ento
+fla sk
+sen na
+> :
+at roc
+sand erson
+id lib
+dhan ush
+ðŁĺ Ļ
+en thr
+hit ch
+de dly
+al ley
+dor k
+mon do
+cudd ly
+mis sin
+ye sss
+night ing
+j pn
+w ary
+ump ire
+ma z
+ê ³
+bab s
+ĭ ãģ
+stan ford
+posse ssed
+exce eded
+ðŁĶ ¶
+wall art
+tra p
+j il
+hi bis
+sp ying
+scri be
+khali l
+trans lator
+lu mb
+di zed
+ch c
+super vision
+shut ter
+ja g
+_ *
+yester days
+ms f
+hi hi
+gonz aga
+gille spie
+vive k
+ec static
+this morning
+ch us
+ed es
+ston ed
+be es
+ðŁĩ¹ ðŁĩ
+tur in
+ho ver
+at rics
+ster n
+sam heughan
+auti sm
+mi ya
+eye witness
+writ ings
+travel tips
+chut ney
+px rtg
+keny ans
+my stic
+k rit
+/ $
+red head
+world ly
+am us
+op la
+le ve
+gab bana
+se en
+o clock
+gang a
+keen an
+sc ent
+ol dies
+go green
+corner stone
+comp ly
+con cours
+ðŁİ¶ ðŁİ¶
+ha an
+con fis
+aw son
+cle op
+î Ģ
+su zu
+sau té
+al gar
+subscri ber
+este emed
+ãĤ¤ ãĥ
+worth while
+mel rose
+flo ck
+bri ghtly
+viol inist
+p ere
+sli pping
+and co
+si gh
+ha van
+cu lo
+m sa
+fibro sis
+matil da
+ra fting
+aw ard
+ë ª
+mm mm
+ge aux
+ste iner
+sin n
+help ers
+beet les
+ai mee
+tai wan
+pistachi o
+mac beth
+m zan
+descend ants
+on sale
+in r
+il m
+grou se
+sa ig
+mo w
+bi gre
+adjust ments
+tu la
+mathe w
+transl ates
+mu h
+bol lah
+ðŁĴĽ ðŁĴĻ
+amo res
+ab outs
+bomb shell
+bla ster
+x avi
+s ns
+k roger
+ga ther
+erad ic
+daf t
+chem o
+ben ches
+ðŁĩ© ðŁĩ
+ut v
+our a
+n ko
+gator ade
+biaf ra
+ok state
+im danielpadilla
+dom ains
+open ingday
+kid do
+do i
+ric e
+day care
+mac millan
+ba thurst
+cheer leading
+ðŁ¦ ģ
+cash back
+k won
+hob bies
+exem pl
+ries ling
+âļ ª
+ag les
+ny s
+every thing
+nav is
+ad di
+magne sium
+faceli ft
+ark ham
+grand es
+extre mist
+don at
+vit ality
+pump kin
+be tta
+sl td
+arti san
+li by
+pe aked
+ah hhhh
+mary am
+assi m
+un sc
+ment e
+al aya
+low ers
+ar as
+gri ev
+le ip
+gr ati
+cri ses
+spr ints
+exe cute
+w to
+ms d
+mag ical
+re viewer
+spark les
+juke box
+ðŁĺĤ âĿ¤ï¸ı
+pay back
+licen ses
+dun kin
+bel t
+lake wood
+h ateful
+bud gets
+rev amped
+ph erson
+ky iv
+went worth
+ro sen
+cru ise
+gi ggle
+def star
+assassin scre
+ym outh
+win kle
+w fc
+band wagon
+b kk
+w iring
+kear ney
+south side
+pe tit
+! ðŁĺį
+nor dic
+mir za
+mu gabe
+v l
+scon es
+k tv
+sand al
+du c
+m alls
+ðŁĴŀ ðŁĴŀ
+it c
+al ay
+im pair
+un rest
+flo ss
+c é
+ab ou
+var ying
+muse o
+ser ver
+di ya
+hibis cus
+ero y
+mer ritt
+fin dom
+f pp
+un usually
+go tt
+conting ent
+ali aa
+ball on
+jo l
+hi ked
+zy me
+ay r
+ag n
+ga z
+perio dic
+spar ty
+practi sing
+lin ton
+tal is
+cy pri
+womanin biz
+radio disney
+ðŁĮ ¼
+jump ers
+endo cr
+ðŁļ¨ ðŁļ¨
+and on
+shar apo
+mi er
+ma sonic
+fac tories
+vi en
+bb ers
+ìĽ IJ
+hol d
+ke bab
+be ak
+approach ed
+ac milan
+mun ro
+ko sher
+excell ency
+negoti ation
+walt disneyworld
+cr ouch
+te asing
+suppre ssion
+en ya
+b ce
+transformation tuesday
+cal lie
+vis was
+p gat
+ic ted
+end ings
+esc u
+recru ited
+it fc
+collabor ations
+g ino
+snu ck
+ausch witz
+i fc
+x ii
+ke sha
+ger vais
+clo ak
+x l
+sa ad
+prob ation
+pre cau
+mac in
+anasta si
+le k
+e azy
+daysof code
+mariah carey
+yo g
+stit ched
+boy friends
+sh ar
+ph ile
+ag u
+twin kle
+phi shing
+week ender
+ic ton
+gurmee tramrahim
+al ton
+l eness
+all an
+pen ultimate
+kry stal
+go u
+lan de
+dis mant
+ab using
+nor se
+pat erson
+ed mun
+ap an
+xi umin
+sk el
+cat walk
+re act
+wal led
+t angle
+br yn
+ve to
+super moon
+cas ablanc
+appreci ates
+ski d
+bo th
+catal ina
+ele ague
+cyber monday
+cau tious
+ðŁ¤ ĵ
+nov o
+hamp ton
+ha ye
+jose f
+var an
+lo bos
+roano ke
+orph ans
+tt in
+squ ads
+ishqba aaz
+black panther
+e tu
+k sh
+cru mble
+cess na
+reli eved
+scul ly
+pollin ators
+explore canada
+ki es
+kam loops
+kir an
+pri mal
+sett lements
+hot spot
+brain storming
+ce dric
+bi ennial
+sh ant
+âĻ¡âĻ¡ âĻ¡
+do on
+hear n
+walk way
+fe m
+ve al
+deport ation
+tox ins
+elimin ating
+descen ding
+by the
+bla sphe
+ha sta
+comple ment
+as cent
+ri ga
+provo st
+âĸ ª
+wee ping
+anti semitism
+employe e
+unearth ed
+pin o
+natali e
+bla d
+ang ola
+lock heed
+in ian
+ag r
+ni ster
+im pala
+m ke
+fan atic
+âĺħ âĺħ
+ðŁij ¸
+lu ch
+simpli fied
+gall ery
+econom ic
+cy borg
+con i
+sel ma
+in ception
+ko ala
+dv ds
+cre sted
+m mor
+visi ble
+n sd
+ðŁĻĮ ðŁı½
+w under
+refriger ator
+re opening
+e era
+carou sel
+as p
+balli stic
+victor y
+mo tive
+tre y
+sharapo va
+si i
+mon ter
+int end
+west chester
+sp e
+cy mb
+vi dal
+ll ama
+uni v
+fin er
+crafts manship
+jazz fest
+b ch
+ag gio
+n cc
+lamb da
+tranqu ility
+cis co
+ba den
+so bbing
+of i
+go ta
+ru mored
+war med
+ore an
+ac ton
+mar ci
+gh ani
+âľ ĵ
+as sorted
+pembro ke
+pen elope
+da f
+at ty
+aim o
+pretz el
+carni val
+than os
+ko chi
+mer sal
+ham radio
+ar twit
+cas c
+guer rilla
+kush ner
+k app
+al ise
+todd lers
+steward ship
+o tti
+ter ri
+tem pe
+rest less
+vit o
+zay ed
+rsp b
+pi on
+hi ppo
+haw thorne
+in as
+am ily
+nut cracker
+lo p
+d ali
+tro pic
+ðŁ¤ ł
+ul o
+jare dle
+py rene
+pale o
+usa ir
+m ould
+it ated
+gene tically
+biom ass
+ðŁĩ³ðŁĩ ±
+do dd
+practic ed
+monarch s
+un manned
+m buhari
+am al
+photo gra
+ko ol
+bren don
+ju ices
+cu re
+world bank
+poin ters
+ðŁĴ Ŀ
+tur f
+le ds
+bor ussia
+bapti sm
+warwick shire
+moun ts
+gay o
+be gg
+co pied
+asi ans
+k g
+moder nist
+gi d
+front man
+concentr ated
+y t
+sc avenger
+iron ically
+adi c
+ps n
+ðŁ¥ ī
+cultur ally
+yu v
+mac arthur
+fertili zer
+be withyou
+ri gor
+min ors
+z oning
+âĸ ł
+ri r
+adole scent
+vin ny
+ren g
+sand stone
+gu et
+we sth
+ple dged
+lac ed
+sp ide
+v ai
+ty coon
+seiz ure
+du p
+appalach ian
+ro k
+cathol ics
+sey chel
+posse ss
+la ger
+jo di
+cham p
+stra s
+d ina
+cent uri
+cal der
+blur ay
+ðŁĩ¨ðŁĩ ³
+mo do
+an nette
+youtu bers
+chap s
+ang ling
+label ing
+a qui
+pk wy
+ly le
+bi sexual
+lit ur
+dug out
+li bby
+grey sanatomy
+sub stances
+august us
+rall ying
+fi del
+ing ue
+äº º
+hallmark channel
+tooth brush
+m á
+adi rond
+ag gi
+ðŁĵį :
+cru sade
+tax ation
+k z
+i ver
+dou bling
+room ie
+wa b
+en rolled
+az on
+a ju
+grand children
+as df
+ðŁ¥ º
+mat ic
+ough ton
+utili ze
+ðŁĴ £
+pon der
+rais in
+dys function
+co bain
+butter nut
+e man
+su red
+dri an
+and friends
+with the
+on omy
+heine ken
+bri dal
+leader ship
+pyram ids
+deutsch land
+jo cel
+bo wel
+y qr
+horse power
+be acon
+ing eni
+gra dient
+fer mented
+mo om
+thing y
+pot assi
+wrist band
+bor d
+bo died
+ðŁĺŃ ðŁĺį
+ma pp
+ka u
+cyber punk
+ph ish
+loo king
+co ates
+ap ur
+am ie
+uk labour
+at in
+g la
+adop table
+shel by
+v illi
+ri ya
+m ingly
+cli mber
+bumble bee
+ðŁĺ ¸
+c sd
+âĿ ¥
+hospit alized
+c ki
+hat er
+ch r
+re tina
+it a
+fan base
+beat rice
+gwy ne
+go ss
+fo s
+favor ited
+swachhb harat
+mal ade
+mon mouth
+" [
+si van
+sh hh
+command ing
+sains burys
+wee d
+g man
+ss w
+rep tile
+iv y
+tro pics
+roll ers
+over cast
+ex position
+masquer ade
+man crush
+wa ist
+spr inter
+sle et
+le vin
+j pg
+_ (
+o pel
+explo it
+ap a
+po we
+wrec king
+jong in
+or b
+er ick
+bo sco
+pra ising
+ber tr
+to wing
+in security
+ku t
+resto cked
+rr p
+prescri bed
+trafal gar
+per t
+g ases
+app rais
+g har
+music als
+âĸ¬ âĸ¬
+mc fad
+ag ony
+conditi on
+equi p
+shi k
+atra vel
+ðŁĩ¿ ðŁĩ¦
+ke h
+abduc tion
+pe oria
+wil kins
+g ms
+as d
+ev i
+ðŁĴĹ ðŁĴĹðŁĴĹ
+u z
+mo c
+halle lujah
+guad alu
+lou vre
+dra wing
+go ve
+ph ant
+fri e
+web dev
+program mer
+z able
+games com
+clari fy
+li th
+kin ky
+âĿ £
+labour doorstep
+son ata
+ju ris
+mai den
+vi adu
+buch arest
+conditi oned
+capit alist
+u de
+ps b
+sp ca
+lul la
+footh ills
+kay o
+bon d
+wom b
+roun der
+ce sar
+bur sts
+ap ra
+sw oon
+sab rin
+fra grant
+cle arer
+ku brick
+cli max
+jour no
+ag le
+ðŁı½ âĢįâĻĢï¸ı
+poo ch
+hal e
+sol it
+sal mon
+organis ms
+bron son
+art en
+hodg son
+alo ve
+vent ure
+bb i
+ae a
+ðŁIJ ¢
+ld n
+d nr
+o zone
+el las
+man ny
+azz ur
+un beat
+tru ffles
+th ong
+ma ñ
+las ers
+ley e
+gettys burg
+back packs
+or is
+ma ison
+craw ling
+la bra
+cl ing
+dra gging
+ste al
+dou bt
+de van
+ck ers
+agent sof
+photo bomb
+elon musk
+abo y
+dist ances
+story line
+sp i
+nor than
+europe ans
+wh ale
+ser pent
+ðŁļ ²
+fi or
+tr it
+ox o
+awar ding
+class mate
+su fc
+smar test
+rich es
+pr k
+big foot
+ar mb
+bi polar
+dw elling
+om ars
+k wan
+gri me
+m eng
+freder ick
+navar ro
+sorry notsorry
+jaredle to
+pa ve
+sl ack
+barn sley
+att ar
+evic tion
+accumul ation
+o ir
+cat chy
+wel ter
+vik as
+has see
+nik ita
+mo yes
+mathe ws
+shi v
+gat wick
+pro filing
+compan ions
+mar rake
+an tics
+ðŁĻĮðŁĻĮ ðŁĻĮ
+se se
+bo i
+bart lett
+poison ous
+ab uses
+ym m
+kam pala
+guggen heim
+imv kohli
+dol om
+bre e
+thro ttle
+gare th
+fitz patrick
+un ya
+par ad
+mar got
+j nr
+we a
+potassi um
+p nc
+disgu ised
+cra sh
+ren ergy
+ill ic
+coup led
+ni els
+ci ones
+æĹ ¥
+im ent
+despic able
+d ye
+what cha
+conne ctions
+paralym pics
+gaunt let
+wait rose
+suici dal
+star ship
+vap or
+st ou
+law maker
+coo led
+si mo
+then o
+offro ad
+ja den
+bas que
+vick y
+lu kaku
+centr o
+tri sh
+strate gist
+medic ations
+hor st
+b fc
+gra il
+sharp ly
+ad itya
+tom b
+kau fman
+tri pad
+sam ba
+pastor al
+brit ney
+sag an
+hill side
+mas ons
+sar a
+z one
+x u
+to tes
+rob bie
+app en
+mon tag
+der o
+short film
+charis matic
+tat ors
+ki ba
+and ri
+al arming
+split ting
+ic ar
+th ug
+scari est
+sylve ster
+an an
+u trecht
+a difference
+me ade
+bu ster
+air strikes
+cu ffs
+account ants
+ðŁĺ¡ ðŁĺ¡
+new t
+bo tt
+issu ing
+cl ancy
+wwen etwork
+kyu hyun
+rese mble
+pajam as
+sin k
+kin ney
+sul ph
+or k
+li es
+la gh
+or ton
+ra hul
+d sc
+we will
+re am
+collo qui
+shar ia
+hec tic
+sar casm
+land er
+tm z
+endor f
+ro z
+ham mered
+fri s
+w adi
+pope francis
+he it
+flash light
+un born
+op es
+hol iness
+ðŁIJ ¦
+nach t
+im sa
+gr acing
+bj p
+ver ts
+c sc
+home owner
+a que
+bigo try
+anni e
+bag h
+âĿ¤ï¸ı ðŁĺį
+car i
+thom p
+dispo sable
+cardio logy
+pat ented
+hh hhhh
+ld r
+stephen son
+cro res
+fan ning
+cli mat
+ðŁijį ðŁijįðŁijį
+ðŁijį ðŁı¼
+aer on
+piccad illy
+bank rupt
+sil via
+emplo y
+don ny
+commen ting
+screen writer
+io ta
+ce an
+anc ers
+tu an
+street wear
+ठ¯
+sk ine
+esp a
+asi f
+os ce
+she ppard
+more cam
+bott le
+der s
+orac le
+google play
+aver aged
+edmon ton
+steph an
+sister hood
+cru sted
+stag gering
+methodo logy
+congress woman
+c abo
+tri ggers
+mil ky
+gli de
+tooth paste
+room mates
+nu ff
+gu am
+sprink les
+alternati ve
+wat fordfc
+uof t
+hal ey
+cont acted
+bun dy
+pro stitu
+gh ar
+pre ston
+on site
+hil ar
+g ts
+c att
+hamp stead
+? ?!
+ðŁĩ§ ðŁĩ
+bbc qt
+aless andro
+resi st
+ma idan
+t ko
+shad ing
+pin up
+gal lo
+sin u
+at ec
+fun k
+ac lu
+stri des
+rhy me
+wet land
+bbc springwatch
+t ins
+wild card
+st our
+flamen co
+pau la
+onto logy
+gang sta
+am ade
+ãĤ «
+t bs
+skelet al
+run ner
+jard in
+harri er
+hun ted
+z hen
+believein film
+de mean
+au diti
+re start
+chon dri
+âĿ¤ï¸ı ðŁĴĻ
+mcla ren
+ga b
+sh um
+au sa
+lewi sham
+y pg
+k jv
+fur nished
+dor o
+bon ded
+mor ty
+lat itude
+_ )
+lo va
+water ways
+vin ai
+shor th
+drun k
+c ay
+ay ana
+kap lan
+capp uccino
+spr o
+life boat
+has bro
+spol ice
+tor on
+do ing
+dam n
+sh ree
+foun tains
+ent ation
+mar u
+boar der
+to pless
+j ada
+chan ning
+ul ls
+en closure
+gib son
+fractu red
+brit ton
+Ã ¶
+t ous
+por th
+dra f
+tra iling
+mar gate
+eli fe
+down ward
+lin n
+gla des
+girl power
+ak rish
+u ki
+ron da
+ts c
+appreci ationday
+vis ing
+lo om
+ðŁį ³
+mex ican
+ar gos
+y ya
+jad ine
+south port
+d end
+si sta
+rede em
+men g
+bra xton
+antioxid ant
+s key
+mp g
+fin ding
+vibr ation
+ce u
+kh art
+di mini
+cl ine
+shel ly
+hin es
+ī ï¸ı
+to pical
+no ver
+ma xx
+prim itive
+illustr ate
+b ounds
+tren ton
+join tly
+breed ers
+u chi
+wakeup america
+b ada
+ðŁĹ £ï¸ı
+gu acam
+sp heres
+pere gr
+youth ful
+lo lo
+bir min
+t ly
+jeremy corbyn
+defe cts
+co sm
+a rent
+v aa
+bag els
+medi ac
+cori ander
+ic ago
+g haz
+ab bas
+re model
+struc turing
+pu m
+out law
+ad ani
+r bc
+gul ls
+n li
+confu se
+ðŁijĩ ðŁı¼
+vil a
+mcnam ara
+correc tions
+mug hal
+ser i
+re gain
+ss b
+lea ve
+haha hah
+gran de
+di stressed
+re chargeable
+ho a
+hou sed
+sti l
+attribu ted
+opath ic
+di ps
+pri t
+head phone
+conclu de
+pil o
+he t
+ut sa
+nit in
+je m
+sni ppet
+tutor ing
+op er
+sun k
+en sla
+cha u
+ac orn
+quinte ss
+ran kin
+affili ated
+our lives
+cl int
+se ater
+isa ac
+ba shing
+sme ar
+nur se
+doo dling
+" ;
+sa ku
+atroc ities
+im am
+g fs
+viol ating
+comm end
+brad shaw
+er ville
+b illed
+b be
+thul hu
+i phones
+moo se
+di os
+re w
+me thane
+strang ely
+whis ky
+ti ghtly
+spiel berg
+radi us
+notic ing
+wi f
+ig nati
+i fa
+ap is
+w ali
+ha itian
+bu shes
+y z
+v l
+ex ited
+asse l
+tru ec
+dom en
+ash er
+in king
+newyear seve
+hend ricks
+bat i
+ìĿ´ ì
+rich ter
+mon santo
+con line
+agre at
+ðŁ¤ ¯
+master pieces
+ar n
+rough s
+cle ve
+se v
+fashi ons
+to ya
+sh ail
+cop eland
+aqu ari
+dec als
+are you
+y aya
+a str
+fon t
+ml m
+ar ca
+pp or
+pol lock
+xper ia
+conserv ation
+chain saw
+ag gie
+?! ?!?
+si le
+sh on
+ìĹ IJ
+note books
+marque tte
+de us
+bb led
+spic er
+mc cabe
+nor wich
+modi fication
+boo sted
+stru m
+sales man
+bang le
+nis san
+hez bollah
+brea sts
+a af
+anth us
+sk er
+ow ed
+her os
+gi fs
+fo sters
+eat ers
+du es
+_ /
+lymph oma
+sf am
+me gal
+afri di
+ag ic
+p amp
+jeal ousy
+ðŁijĮ ðŁı¼
+calcul ate
+napp ing
+g ale
+ðŁ¦ Ħ
+lub bock
+assu med
+ren ting
+íĥ ľ
+subur b
+ãĤ ·
+tech nic
+u cla
+in front
+gar net
+ster oids
+stri ving
+ho war
+mo ver
+le ton
+bull do
+is in
+ci ao
+sn z
+fore front
+d ams
+mid wife
+ma wards
+cla pton
+we in
+subsi dies
+spr oud
+rother ham
+phan tom
+ar ach
+spi el
+rac ket
+sel amat
+no on
+l bc
+enti ally
+ðŁĴ ¸
+sil ve
+m oud
+kine tic
+y asi
+ðŁİ ©
+o ol
+mi ku
+i za
+fer a
+flo ren
+barber shop
+groo t
+z est
+ne ars
+stan is
+z and
+police man
+juris dic
+form ations
+appar atus
+sp d
+arti fact
+to sc
+motiv ating
+womanc rush
+re dro
+diagno stics
+ra za
+out fitters
+el xn
+dod gy
+ry n
+sh d
+ortho don
+ol de
+jay anti
+bal ances
+quic kest
+can ton
+friday reads
+! *
+na a
+a ak
+ðŁĶ ·
+behavi ors
+rasp berries
+ä »
+polit ical
+cam il
+å ľ
+di k
+ast ounding
+lie be
+novel ty
+tur moil
+sul ly
+spring break
+hon ouring
+cc g
+ðŁı Ĵ
+my little
+ky c
+pro ms
+ðŁķ Ĭ
+Ã ¨
+bi ge
+av ril
+ðŁĩµðŁĩ °
+mari on
+as ants
+sur ya
+oc tag
+luf than
+ac ron
+fayette ville
+ti que
+love s
+en ca
+de kalb
+ta ver
+de vote
+aux iliary
+joh annes
+tread mill
+ay an
+qu r
+donald son
+cher yl
+" ....
+s ven
+kir sty
+gun ners
+ra dish
+o ahu
+v sky
+i ble
+con course
+b ps
+elo qu
+ash ford
+te bow
+roblo x
+ma da
+dri ving
+th day
+spro ject
+m ms
+band ed
+. !!
+libr arians
+flan nel
+intoler ance
+her al
+ç µ
+neme sis
+list a
+tar ak
+cry pt
+star plus
+vish nu
+sc ale
+cr is
+% ),
+j illian
+regg ae
+pegas us
+ol in
+ip ment
+man ic
+l fc
+godd ard
+ite am
+parl our
+anch ors
+lee minho
+talla hassee
+ant it
+d ho
+kid ney
+y ash
+batt led
+az ad
+gar is
+faul kner
+sni ff
+papar azzi
+ed m
+phy llis
+con tested
+aa ay
+se ca
+k ton
+vel ve
+rain ier
+for um
+tam pab
+ho sp
+trac tors
+ox fordshire
+no tion
+guang zhou
+ðŁĺ ¯
+ref ill
+wednesday motivation
+sli der
+mukher jee
+pr att
+fon taine
+alph on
+af ar
+ts i
+pest icides
+fi ends
+mo cking
+bra w
+tran sat
+do ses
+co res
+hom ophobia
+docu menting
+zlat an
+con doms
+s é
+sun set
+kun st
+ton ga
+ภª
+v ation
+sp ray
+chow der
+ra ps
+palla dium
+nor wood
+music history
+hoo ker
+si si
+osp rey
+ph ys
+conce ded
+bob cat
+ar mad
+ze it
+Ù Ħ
+ðŁĺģ ðŁĺģ
+mer idi
+ðŁĩ· ðŁĩº
+corn wall
+! ),
+touch downs
+ze it
+chal et
+mm m
+al che
+gor illa
+fo ss
+ati ku
+lumin ous
+ivan ka
+be ek
+sta res
+sw iss
+âĿ¤âĿ¤ âĿ¤âĿ¤
+scru bs
+me ath
+gusta v
+jo gging
+confe tti
+as os
+ers fc
+breit bart
+applic able
+autho red
+ya ho
+h in
+displac ement
+j v
+ðŁĮ¹ ðŁĮ¹
+ot c
+non profits
+diec ast
+gu sto
+inte stin
+c ages
+me en
+lu kas
+moon ey
+ðŁĺ ·
+very day
+tor ah
+is sion
+wa c
+lever aging
+ish able
+cu se
+le wood
+may an
+turn table
+ju ice
+tru sty
+tu p
+eti quette
+supervis ors
+stu n
+gu zman
+confe ren
+ric o
+fe ast
+back ward
+pol aris
+mic he
+jo g
+h ing
+field house
+vel ing
+sho cker
+esc ence
+ठ¾
+vi be
+anasta sia
+mar ched
+kill ing
+Ķ ë
+fe tt
+exop lan
+... (
+snow day
+lo h
+ir ani
+la khs
+del a
+po caly
+boom ers
+dictat orship
+ac er
+tur keys
+quarter final
+muskete ers
+ðŁĴĽ ðŁĴļ
+sf x
+museum week
+sc ala
+ri sis
+( ðŁĵ·
+ãĢ Ĥ
+z ies
+bo eh
+hu es
+lu sci
+dol a
+impeach trump
+roo d
+don caster
+tor re
+hero es
+fo yer
+tar i
+blur red
+ke w
+frank ly
+dro id
+ap al
+Ð ¼
+y af
+bre t
+par agu
+cac ao
+ðŁĻĮ ðŁı¾
+ru e
+head aches
+shaw ty
+char ley
+pal er
+go wns
+correc tional
+ðŁĺ© ðŁĺ©
+breaking bad
+ol ing
+da p
+endeav our
+cit adel
+tra d
+incumb ent
+medit ate
+foo ted
+ðŁĴ µ
+shab bat
+dayof the
+wil lem
+gal way
+to red
+marri age
+f illion
+sleeve less
+aud itor
+jin young
+invin cible
+kad una
+a and
+volcan oes
+mon eti
+indie gogo
+buccane ers
+ðŁijī ðŁı½
+ãĢ Ĥ
+lay ton
+cuck oo
+hu mber
+buzz er
+Ï ī
+to re
+stra ins
+sto m
+pa ine
+s we
+du ff
+z ou
+si mi
+li pp
+ur n
+se agu
+ðŁĶ ®
+sun dae
+hi c
+ðŁĺ ¨
+bull pen
+u per
+flyo ver
+al dridge
+glo bes
+ali es
+ken zie
+ge es
+y cle
+sp lin
+mag enta
+j ha
+bal u
+gh orn
+ti pper
+wick er
+taste of
+con clave
+ch ale
+inv asi
+cat er
+dio xide
+me gab
+win n
+at p
+transform ative
+nest led
+hi g
+bri dging
+lil ies
+chee red
+bad dest
+sc rolls
+real is
+dipl o
+ðŁĶ «
+conce ssion
+prefe rences
+explo des
+er gon
+introduc tory
+ine au
+ch af
+som es
+land rover
+spir ation
+sex y
+sco recard
+illustr ates
+soul mate
+wi en
+inter disciplinary
+fore casting
+ent ities
+glu ed
+en lar
+cur t
+percep tions
+boot leg
+mi re
+asho k
+v az
+hor ne
+cal le
+ac ulture
+ther oy
+night time
+oc al
+character design
+ar mist
+ðŁĺı ðŁĺı
+yah oo
+ac eae
+to se
+even to
+sou t
+nay anth
+wh om
+v are
+ri gging
+gen us
+hi ve
+com mands
+sti e
+day a
+ethan ol
+en f
+hi fi
+flu ence
+cle mson
+re invent
+thermom eter
+humor ous
+emer ging
+aci ón
+ðŁĺĺ ðŁĺį
+s ity
+haw ke
+accompan ying
+t ility
+ðŁĺ ª
+re cess
+protag onist
+l ery
+dun dal
+int l
+britt any
+q bs
+off the
+marri ages
+how to
+viol ated
+adel aide
+wit t
+lanc er
+pak v
+hu me
+st ade
+bra gging
+ou tright
+ad c
+super st
+real time
+cu res
+garden ers
+ero ck
+dale jr
+ver o
+bar tol
+mo ti
+mc fly
+v pn
+st ink
+over rated
+guer ra
+e tis
+ath ome
+twd family
+th ab
+tn x
+rafa el
+family travel
+x ley
+sat anic
+equ ations
+ru dy
+wal dorf
+stan i
+tu be
+meas les
+zimmer man
+obli gations
+i ously
+bow ser
+trans former
+sho ppe
+shak en
+gh ouse
+to d
+ke tball
+share holder
+mar ca
+kp mg
+ak an
+given chy
+coast al
+au th
+roller coaster
+mar ches
+coordin ate
+cine ma
+apprentic es
+par lor
+mit o
+men on
+consider able
+bar re
+glo ss
+enh ances
+jaz eera
+fal mouth
+thra sh
+stat en
+k zn
+eng el
+samanth ap
+flo ppy
+sal om
+ðŁıĨ ðŁıĨ
+w ack
+deliber ate
+osc ill
+herit ag
+du sted
+orni thology
+pad dle
+fer ns
+bar un
+cl ans
+anticip ate
+a ay
+mat ically
+é ĩ
+tu mble
+post man
+unic ef
+tro tter
+op d
+leaf let
+ge ist
+cease fire
+scre ws
+cre ation
+wal nuts
+longh orns
+under statement
+ab b
+proxim ity
+na x
+un ity
+turn pike
+orda ined
+dub step
+chak ra
+me ch
+love her
+look alike
+donne in
+vir on
+Ù Ī
+bang ers
+vari ants
+out dated
+in ta
+cri sto
+sp elt
+food and
+f on
+stefan i
+margin al
+hu tton
+ti ara
+tel ford
+qu en
+fair grounds
+que tta
+mikha il
+heal er
+v ball
+ty re
+under grad
+gl end
+hom ers
+scri bed
+main tains
+po che
+mis sal
+mar ko
+u as
+á n
+sh p
+con vey
+pad re
+sab a
+pu glia
+madhu ri
+pa xton
+chap lain
+n ago
+ca si
+... !!!
+fli rt
+sal eh
+k are
+di re
+stam ped
+extre me
+ðŁĺĥ ðŁĺĥ
+ho ppy
+guadalu pe
+advant aged
+eu char
+p low
+un n
+mac qu
+port land
+cla sh
+pe s
+lou bout
+y p
+keep ing
+arca dia
+fran kie
+fi u
+de th
+encyclo pedia
+si ze
+inve sts
+ðŁį ©
+geo logical
+fran ç
+con front
+ðŁĺ ¥
+d ys
+af m
+tex an
+graph ene
+repost app
+ac f
+ur sula
+gaz a
+dd led
+fu m
+wsb tv
+m be
+fron tiers
+chrono graph
+ke s
+inter faith
+tab oo
+spar ta
+won do
+flori st
+em braces
+ca w
+no el
+arch ers
+ðŁIJ ·
+roman o
+ban an
+sh akers
+melo dies
+geo thermal
+se phora
+ìļ °
+оР´
+pro c
+hand shake
+pan de
+popul ated
+slow down
+hor tons
+registr ations
+un deni
+lan ts
+pas sover
+thak ur
+li ef
+adhe sive
+pe tal
+micro scopy
+memph is
+confir ming
+air drop
+mesm er
+perce ived
+ming le
+lifel ine
+gh j
+worcester shire
+pas sions
+ach er
+el lar
+ah o
+firen ze
+bar ang
+letter man
+hat field
+lu cha
+je ter
+e shop
+william s
+horo scope
+pre de
+east bourne
+dur ga
+di version
+al trin
+seis mic
+premi osm
+nar co
+ti r
+ori g
+or m
+land fall
+ci ous
+lin do
+max ine
+x ico
+tra y
+os wald
+c ba
+ric otta
+n cr
+mar au
+ภ²
+gladi ator
+ch ery
+lun g
+u me
+po psic
+lon ging
+can als
+ta ya
+decentr alized
+sho pp
+pres sures
+mahar aj
+eti had
+wal greens
+succe ssion
+sign aling
+li g
+staf fer
+north korea
+def ying
+as ma
+de g
+peri meter
+oak ville
+m sk
+balti more
+rece ip
+de ple
+ðŁĺŃ ðŁĺĤ
+jambo ree
+> .<
+rsp b
+puni sher
+consider ably
+in tothe
+pari sian
+acceler ated
+polye ster
+low es
+fr ying
+sauté ed
+mou ths
+seychel les
+ra x
+go dis
+dak ota
+house wives
+the me
+mat inee
+black bird
+ye sung
+pre fers
+pelle gr
+in ated
+trun ks
+stronger together
+re pet
+re pairing
+ped als
+toler ant
+her r
+dun ne
+indic ation
+decat ur
+b tv
+exhibit ors
+ik on
+friday motivation
+bra gg
+live tweet
+al ves
+womens art
+foreig ners
+wal lets
+min dy
+lan ey
+bb in
+tv miaw
+lif ter
+tar get
+tam e
+dr ou
+astro photography
+mp c
+g pu
+nord strom
+fric tion
+run off
+lov able
+sp nfamily
+ext ingui
+bloo dy
+sch el
+arti stry
+sw ish
+scar ce
+ph ils
+max im
+pos sum
+com promised
+sty li
+sc fc
+is sa
+birmin gham
+sket ched
+angel ica
+ordin ance
+je ts
+conqu er
+ðŁĺ IJ
+online shopping
+s ori
+reason ably
+nue stro
+ar turo
+ch l
+benef ici
+spho to
+wel t
+ni kk
+ðŁ¤ ŀ
+dan ao
+for mid
+as se
+af irst
+âľ Ĥ
+gil lette
+as sor
+an onym
+sel ca
+fe mi
+bear able
+y and
+ar mory
+cre pe
+celtic fc
+bra vo
+in expensive
+de lec
+ge cko
+new market
+snow flakes
+kab ir
+con tra
+can ning
+mor pho
+gar wal
+ðŁĴĥ ðŁı»
+fight ing
+mu tation
+woo dy
+ju gg
+gr aces
+premiosm tvmiaw
+kenne dy
+gu p
+sa e
+op ha
+off spring
+fini sher
+bet ts
+span ning
+mar j
+h one
+sh ing
+contin ents
+samanthap rabhu
+un related
+l acy
+explo sions
+benjam in
+sophi e
+no ting
+micro soft
+as sen
+a hoy
+i ker
+ho fer
+mo e
+ah madi
+yan n
+an ak
+ma hi
+be u
+aha h
+creep er
+baahu bali
+am at
+pri ory
+haw keye
+deloit te
+sko da
+print making
+assemb ling
+mirac ulous
+no ch
+sw o
+leg a
+oper ates
+border lands
+eli e
+stron gh
+rep tiles
+pir ate
+un fold
+Â ¯
+qual comm
+un predictable
+ot r
+rose wood
+direc tional
+counsel ors
+corn ell
+liber ated
+j ad
+ir regular
+bulgar ian
+high ness
+vodaf one
+sw ild
+mini mize
+gra zie
+๠ĩ
+r stats
+stre ep
+ome tric
+humb le
+lu mp
+l ille
+b ü
+home depot
+tripad visor
+ki wan
+a via
+er z
+ex ico
+du f
+blu men
+mi zing
+ar ma
+in im
+con stan
+sor a
+ju al
+au n
+tw ell
+tren ches
+her a
+r k
+po plar
+recipe oftheday
+ll an
+bhu ban
+short ages
+ing don
+bridge water
+ðŁIJ ĺ
+fortn ite
+cam den
+un cture
+pro w
+colon ies
+t ks
+n go
+b hm
+live pd
+spl ace
+sli ke
+happye aster
+ter rence
+revol ver
+j ed
+yy yy
+office of
+m ts
+exist ential
+r ourke
+explore bc
+sse d
+pri est
+vix en
+si ding
+k pa
+a har
+ju ic
+ob struc
+foren sics
+uk mfg
+cancell ation
+we ary
+ab q
+ele c
+pri zed
+deb ts
+me zz
+salv atore
+m dc
+gre tte
+c gc
+th on
+snow storm
+ts ch
+cook ery
+å ¹
+wa xing
+n acional
+mur s
+ra ve
+cap es
+ger main
+dri pping
+sub mitting
+ome lette
+iter ation
+aj es
+shim mer
+fu eling
+ðŁĩ§ ðŁĩª
+li po
+bo bble
+un follow
+islam ist
+hi ber
+cat s
+agentsof shield
+sen si
+____ _
+ster ia
+inst al
+ausp icious
+har row
+over land
+femini sts
+inst ant
+char iot
+blind ness
+sp ed
+sc arec
+nu it
+mini atures
+ho seok
+glo ck
+fifa worldcup
+e te
+dis m
+we iner
+ex foli
+ear ts
+ภĶ
+my art
+man il
+iss ant
+form a
+in cu
+buffal ob
+in tim
+mc cul
+anj ali
+po po
+un doub
+hil a
+fun gal
+thank ful
+fu tur
+en dish
+ren ds
+th ar
+she ff
+ring o
+nichol ls
+io wa
+po tom
+cl ams
+ãģ Ħ
+acon f
+stadi ums
+di mp
+di k
+residen ces
+do v
+caric ature
+seagu ll
+kl m
+confe ss
+sla pped
+cele b
+turb ines
+pp v
+nur ture
+el ab
+.... .#
+tu ff
+de press
+al far
+amii bo
+di spon
+e wing
+que er
+friend s
+for re
+âĺ ¼
+sw t
+aqu arius
+head liner
+cur d
+fi gs
+o tters
+love fl
+kare em
+go vegan
+fri yay
+consol ation
+at ri
+ì§ Ħ
+âĺĿ ï¸ı
+poly ne
+gu ed
+o ya
+la us
+intestin al
+cam illa
+scal p
+pi r
+leed s
+horri fying
+bore tum
+dand elion
+fer rer
+ell ic
+as x
+so ren
+re loaded
+ale ague
+navig ator
+ine tte
+add ams
+al chemist
+ak shay
+dystop ian
+awe c
+n aya
+al isa
+ai led
+ag or
+avi ator
+ali zer
+smo bile
+findyour park
+cop ying
+to ddy
+sh ti
+mon ger
+cal houn
+nap kin
+break up
+y atra
+se thu
+ric hi
+eras mus
+fer ry
+am ore
+prac tise
+bo bo
+power point
+oo se
+li ffe
+chin a
+sh ka
+fad navis
+du ane
+war on
+fal se
+ðŁļ Ĥ
+wa shes
+disc ip
+==== ====
+g k
+ab b
+stub born
+medi eval
+p ci
+ðŁį ª
+maril yn
+h yo
+man di
+cr i
+prede cess
+continu ation
+om usic
+s lat
+wh al
+mall ory
+bon n
+shen zhen
+ca i
+âĺ ĥ
+sa fest
+for wards
+dra wers
+bla sted
+sle e
+mor phe
+mb ta
+dumb ass
+ÑĦоÑĤ о
+alhamdulil lah
+ec lub
+al beit
+heal ey
+ayurve da
+adverti sed
+cro cs
+itt les
+bry son
+be i
+nj pw
+honore e
+fu sed
+ðŁĶ ĺ
+mul tin
+n aga
+de parts
+ko p
+kin o
+jhar khand
+ed na
+ax le
+mil ton
+supremac ist
+marrake ch
+domin ic
+tran script
+] [#
+: ).
+wo c
+sur rounds
+o gil
+leaf lets
+co well
+whe w
+tru de
+proli fer
+succe s
+sports man
+con dom
+po che
+k up
+imprison ment
+{ }
+scram bled
+å Ľ
+ka ine
+cell phone
+metam or
+con i
+remn ants
+ee z
+down pour
+afterno on
+exerc ising
+ber ser
+architec ture
+wick low
+m ns
+is p
+bo c
+n iss
+mn wild
+stu mble
+r si
+lu ffy
+sil en
+dd ad
+bul lies
+haw ker
+bb cc
+scu ba
+e pp
+que ts
+for aging
+pal let
+ha di
+cinemato grapher
+cat chers
+to aster
+k hi
+lite coin
+kid lit
+amher st
+maur icio
+ip ad
+mar malade
+fe y
+don nelly
+g to
+est as
+cere bral
+ant grasso
+zz led
+vir gil
+swa pped
+ðŁĺħ ðŁĺħ
+no dapl
+greate st
+nhl bruins
+fra ser
+b mo
+ane w
+. âĿ¤ï¸ı
+se gregation
+remark ably
+mccor mick
+lo gger
+er as
+contrac ting
+âłĢ âłĢ
+yor ks
+uku lele
+touch screen
+de cked
+ben n
+south wark
+ra vin
+nu mis
+ðŁ¤ Ļ
+ru t
+gre co
+eth ic
+red neck
+ar r
+t cs
+ih ri
+ðŁĩ« ðŁĩ·
+l k
+inher ited
+zy k
+viadu ct
+marty red
+hi gu
+ss n
+be in
+street style
+fer gie
+bank of
+æĹ ¥
+stake holder
+exempl ary
+cre ss
+ess a
+ero tica
+intre pid
+gom es
+bra un
+bethan y
+bang tan
+pulmon ary
+m illing
+doctor ate
+trump russia
+ठ°
+s ani
+bl att
+pla u
+depri ved
+t le
+ful ly
+bour n
+st ak
+lufthan sa
+kio sk
+far oo
+def y
+bad an
+ðŁĺĺ âĿ¤ï¸ı
+rit z
+tri sha
+ran ds
+middle sex
+arab s
+pro j
+sport scenter
+repe ats
+iv f
+bleed blue
+as sure
+o bs
+territ orial
+ele n
+bever ley
+ann ah
+âĿ¤ï¸ıâĿ¤ï¸ı âĿ¤ï¸ıâĿ¤ï¸ı
+z l
+for good
+science fiction
+gla u
+son ya
+pri th
+st weets
+mix ers
+mari o
+ant elope
+writing community
+went z
+den ham
+be di
+sf o
+harley davidson
+look book
+immuno therapy
+or phe
+es ville
+ed ged
+tas k
+sb ball
+corro sion
+kilom eters
+co sting
+play back
+ke ke
+di visi
+u ter
+re location
+yel led
+pen g
+up beat
+ser ve
+âļ ł
+hal en
+stir ring
+reh man
+en v
+schu macher
+frag ment
+alkal ine
+sb k
+resil i
+share point
+rol lover
+tra sh
+counter part
+âĻ «
+ob itu
+à ½
+ãĤ ¹
+mul berry
+ðŁİ Ĩ
+auton omy
+spra ying
+nat l
+love you
+fran ki
+nu k
+esc ar
+can teen
+ali baba
+de plor
+mole cule
+pu d
+fort night
+blon die
+sp hin
+portra yal
+ta che
+bu te
+consi sting
+freep alestine
+c sp
+im mort
+d ns
+ðŁĴ¥ ðŁĴ¥
+tour de
+coo king
+archi val
+ga thers
+bit t
+b anc
+pre mature
+snow ball
+poetry day
+lou dly
+fug itive
+ed ay
+em ra
+ðŁĩ¸ ðŁĩª
+sci en
+node js
+jur gen
+je ong
+band ana
+un is
+fox sports
+v andy
+pro visions
+wee p
+tu k
+i ko
+h oun
+zig gy
+z r
+fil let
+bat a
+tin k
+con e
+we want
+k ilo
+hor ace
+sl t
+sc t
+stay tuned
+victor ia
+umb ria
+att acker
+ingham shire
+fright ening
+no ir
+fr at
+con tempt
+lia ison
+ho i
+br ink
+tr ill
+ni agar
+kick ass
+dun das
+not my
+rho de
+bu mble
+no xi
+fa g
+spec tators
+mancrush monday
+jin ping
+distr act
+dais y
+wal den
+portra it
+ar thistory
+vol tron
+ev el
+is c
+ac m
+r ite
+na o
+de ported
+swe ats
+ru fus
+lo bo
+labor day
+gam o
+ihri thik
+bl it
+abdomin al
+ãħ¤ãħ¤ ãħ¤ãħ¤
+i it
+e q
+bu sy
+allu arjun
+un disclosed
+de ton
+pro create
+ki l
+ðŁİĤ ðŁİĤ
+mitch ell
+ki i
+inherit ance
+al p
+jo burg
+pat rolling
+compul sory
+un signed
+ni am
+l ga
+eshop suk
+tr illi
+ma w
+appreci ating
+rock ab
+mañ ana
+an tal
+mal vern
+roy o
+grand prix
+sut ton
+go ftheday
+dig i
+ãħĭãħĭ ãħĭãħĭ
+t les
+varan asi
+erec ted
+discip les
+cont act
+ðŁĺ µ
+li d
+⬠ĩ
+scen tre
+radi ator
+ing tips
+trans itions
+thursday motivation
+chem ical
+separ ati
+sal is
+mi m
+geo graphical
+book fest
+/ .
+âľ ĭ
+v ae
+cur rie
+ag garwal
+acceler ation
+the ses
+lg m
+u mass
+pro portions
+nat a
+ani ans
+ku ch
+be acons
+ap r
+@ #
+ðŁĴª ðŁı¾
+nu ke
+sher aton
+ki o
+ma kati
+polit ico
+mor ale
+ì Ļ
+econom ically
+gg ly
+ss en
+pa stries
+intern ships
+vic ente
+fanta ken
+aveng ers
+accu se
+slee pover
+indic ated
+the dream
+ster one
+ren ders
+fro st
+ou i
+gre gg
+d ore
+⾨ ⾨⾨
+pu gs
+sat y
+nu mb
+hems worth
+tam i
+la ssic
+schi ff
+igle sias
+ag awa
+] "
+re shi
+game stop
+divor ced
+theat er
+clau di
+un conventional
+prophe ts
+ac in
+twel f
+tow ering
+t ml
+sc lerosis
+k wan
+ge ts
+distur b
+na ira
+ener g
+pir acy
+pru itt
+noti fied
+hen na
+bra m
+ground water
+bl s
+opti mis
+$ )
+luci e
+biz hour
+fang irling
+gr ills
+or l
+ver se
+c ina
+law less
+artistson twitter
+tele vised
+marshmal lows
+radio head
+bar r
+m fc
+bre vi
+mmor pg
+g aya
+âĸ «
+sub titles
+j t
+disney land
+to bago
+nh m
+groo ve
+fi awec
+" /
+ba o
+scra bble
+om ni
+ff l
+um c
+si mba
+ali er
+ter rell
+plu me
+mi di
+dig nit
+co c
+bru t
+ad ata
+alche my
+d sm
+ðŁĺĨ ðŁĺĨ
+win try
+spa res
+cu er
+conclu sions
+to ys
+od or
+fl ann
+gar vey
+scrip tions
+inspec tions
+cat ap
+ang lo
+st louis
+heim er
+at ay
+tr ich
+en yc
+chil ds
+vent il
+mont p
+guiller mo
+circu lare
+z ell
+mode led
+craf tsman
+al ina
+stimul ation
+cashe w
+ju das
+best of
+to ire
+susp ends
+scol lege
+real ising
+by tes
+bloo ds
+as si
+ðŁĴ ¿
+o hs
+ðŁį ĭ
+scallo p
+ठµ
+gi fting
+camo gie
+wil kes
+o zzy
+ðŁ¤ ¤
+ver onic
+sav oy
+deme tri
+baby girl
+ðŁĺį ðŁĺŃ
+so x
+cly de
+induc tee
+count down
+self care
+ठľ
+vi ka
+tor re
+phd chat
+pe ars
+aw h
+suff rage
+le sn
+admir ation
+mp p
+shark week
+schul z
+santor ini
+clo ver
+( *
+stras bourg
+ex iting
+so yu
+finger print
+che a
+ãĢ ľ
+vin dic
+song writers
+so a
+prou der
+nam a
+= ))
+simple st
+delici ously
+gil les
+u q
+mn wx
+ep p
+sh un
+ken nel
+fall on
+ðŁIJ £
+sin d
+tra gically
+out es
+modern ism
+co ke
+gy n
+spi on
+âĺ¹ ï¸ı
+le am
+compress or
+apolog ise
+twent yon
+fan atics
+âĻ »
+sco tsman
+sa wa
+ko u
+as er
+ภļ
+welter weight
+phen om
+twick enham
+stri a
+p out
+ka z
+gi am
+cd p
+ho y
+emplo y
+red mond
+ภĦà¸
+sm ere
+trance family
+proto cols
+pie ce
+lu iz
+iter acy
+carl s
+united states
+har med
+phd life
+ch aw
+foot prints
+l é
+cho ker
+z ana
+sli pper
+eric sson
+insul ting
+articho ke
+advis ing
+acquis itions
+op or
+mut ations
+re ar
+ॠģ
+pod cast
+wi ther
+kun g
+íĺ ¸
+win slow
+di apers
+ðŁĵ¸ @
+ec ker
+col lar
+hu ey
+gi ro
+mono gram
+kas ich
+si veness
+malay si
+arom atic
+gre s
+gali leo
+u ji
+rob b
+dr m
+none theless
+as a
+: >
+lo a
+l np
+at work
+ag t
+laksh mi
+pipel ines
+id al
+stre l
+re all
+chain z
+stone wall
+san sk
+ðŁı ´
+pied mont
+hoste ss
+ci u
+t é
+analy ses
+wil helm
+scott y
+rw by
+mosqu it
+use mb
+qu ins
+ðŁij İ
+tu cker
+s conf
+speci fications
+psychi atry
+broo kes
+s ils
+ol af
+de to
+co di
+cli p
+fil th
+womancrush wednesday
+go to
+ang erous
+be ale
+w tc
+paneli st
+ne x
+lar sen
+emili o
+tab leau
+h itters
+conce ived
+americ ani
+or tega
+mar di
+Ñ ĥ
+pain tball
+thir sty
+new yorker
+etis ation
+go ss
+we aker
+u gh
+tro ll
+har ga
+du al
+ght ning
+at ine
+ðŁĺİ ðŁĺİðŁĺİ
+cook out
+pyrene es
+po ss
+authent ication
+sports wear
+yun ho
+kir o
+archi pel
+shen ko
+ren der
+nov ation
+divin ity
+ðŁij £
+su fi
+humb ling
+ge opol
+devote es
+wait ress
+tr ough
+py ro
+i ba
+bl ing
+gra f
+epilo ts
+bt r
+of tball
+bas king
+domin os
+so om
+r ath
+sher yl
+qu el
+astronom ical
+wel d
+track list
+sig nee
+slee pless
+com man
+ch ron
+summ on
+pure michigan
+cri spr
+sli p
+la gi
+ra q
+um u
+thal ap
+char med
+scru mp
+quad copter
+ski p
+peter sen
+mun i
+ðŁĮ ¾
+mon aghan
+tra ys
+ick ed
+canad aday
+te gr
+ï¿ ½
+hot ness
+heavy metal
+ab ar
+gop debate
+az ul
+spider man
+sun flowers
+ľ ë
+web comics
+bar d
+Ð ²
+nichol as
+slu sh
+ram an
+mark ham
+ffici al
+ff ler
+íĬ ¸
+ple ss
+anush ka
+to to
+sk aters
+pro wrestling
+compet es
+ay ala
+myster y
+thr ills
+mp g
+independ ently
+y ul
+imper ative
+formid able
+tire less
+st acking
+ton gues
+mal tese
+pot ts
+mat ti
+char ting
+chill out
+super nova
+ome o
+sky sports
+nu tty
+ðŁĹĵ ï¸ı
+ro han
+insp ired
+concier ge
+ser ra
+ma kk
+gal at
+chi pp
+ye v
+ì £
+reim bur
+op ul
+kimber ley
+i eee
+bre men
+ch itec
+or in
+nak u
+bon kers
+foo ty
+emer gence
+ðŁĨ ĺ
+sti p
+serge i
+zo ey
+ai me
+wou ld
+dy es
+destin y
+vinai grette
+dri er
+circulare conomy
+an archi
+ss r
+sch el
+cin er
+gro om
+determin ing
+gar min
+cal ais
+incarcer ation
+bu kit
+no i
+chelms ford
+mckin ley
+chi pped
+belong ed
+tu mors
+str oud
+mi i
+influen za
+wwen xt
+tun dra
+tele communications
+cat sofinstagram
+t ages
+beat ty
+o du
+ml kday
+oo per
+dang le
+ak ley
+cru mb
+anti gua
+ti mbers
+rou hani
+ðŁĴª ðŁĴªðŁĴª
+ha fi
+... !!
+w cs
+coo p
+sn c
+lit res
+ãĢ Ĭ
+ha z
+co z
+k ant
+green field
+cur ti
+y ale
+flye agles
+what soever
+wor thing
+rou lette
+flyeagles fly
+un da
+a inted
+stand ing
+lusci ous
+h pc
+effic acy
+ash land
+me ghan
+ky wx
+n pr
+bath tub
+ac os
+h ani
+mar cor
+man tis
+da isi
+bo ba
+ab bie
+mu til
+vi al
+spy der
+po z
+g ti
+el fie
+nigh tw
+metro id
+anton i
+mad die
+dh ry
+dar lings
+ten ds
+taek wondo
+atlan ta
+me ow
+chlo e
+ãĥ İ
+ym es
+siber ia
+k con
+gu es
+mar iner
+fac il
+azz le
+[ ...
+han nover
+bav aria
+vir go
+te uk
+u sps
+) #
+wall a
+sam pson
+need less
+ver bally
+hay ley
+bow led
+pi us
+lam pard
+ham string
+vol vo
+road safety
+cho king
+sor bet
+a hem
+healthy food
+brai ded
+horticul ture
+cr ative
+che ek
+ad do
+the force
+ko ko
+schiz oph
+j ie
+w ada
+twentyon epilots
+h bcu
+pro ton
+pau ls
+lou isa
+lat am
+kyr gy
+com pac
+sd k
+sap i
+?? ?
+liber alism
+ep silon
+ai den
+w usa
+spra yed
+baske tball
+kim ono
+blue wave
+ali as
+ë§ Ī
+mug shot
+ce c
+do gre
+ad ora
+ðŁĵ· @
+kra kow
+intrigu ed
+exhau sting
+astron omer
+ven ison
+lady bug
+ci v
+bra e
+us m
+bri be
+acup uncture
+pembro ke
+ke ating
+chi e
+y ad
+t si
+sm i
+see ding
+gate shead
+lis boa
+gy p
+canv ass
+ðŁĶ´ âļªï¸ı
+op i
+ni r
+soci etal
+ly te
+ati es
+c sm
+ar tery
+al in
+aka poor
+abstr acts
+â̦ â̦
+teen wolf
+ne we
+travel gram
+sentim ental
+per ched
+han del
+ho ek
+f ay
+coordin ating
+anim ate
+man ian
+effor t
+jer ky
+f ck
+adri enne
+ma bly
+tra ding
+my el
+spi ro
+sol a
+stor ing
+over drive
+monday morning
+dream team
+pul se
+bon di
+ber nie
+pgat our
+tri poli
+son am
+plat t
+âļ ¡
+ag roup
+îIJ Ĵ
+inv ading
+v cu
+k ell
+ñ os
+un dead
+pod casting
+mercede sam
+mana fort
+cor tex
+que so
+impecc able
+pal mer
+wil doz
+sport sc
+guacam ole
+dispen ser
+cate gori
+stun ts
+per il
+invit ations
+dune din
+xi e
+achi eves
+saf er
+pre ds
+ph an
+knuck les
+k ak
+igno res
+lovemy job
+aru ba
+ound ation
+datac enter
+co vert
+gr ing
+cou ple
+ا ر
+vol i
+mc cle
+arti sans
+lu do
+kal am
+arom a
+under taker
+hu la
+wiz kid
+gu mb
+god frey
+bakers field
+ker n
+engine er
+car ve
+pal in
+guaran tees
+pe bbles
+b ays
+zi eg
+fin k
+â¬ĩï¸ı â¬ĩï¸ı
+down pours
+ro chelle
+rasp berry
+ðŁĺ ®
+gra phies
+stom p
+caf es
+ari zed
+utt ar
+cal vary
+dri e
+crusad er
+bus an
+tux edo
+si u
+seam us
+cul tured
+blan chard
+town house
+ge red
+butter milk
+flu ctu
+roger federer
+hel i
+ðŁ¦ ĥ
+u ous
+ram esh
+mu ppets
+email marketing
+ye ss
+br ice
+ri zio
+pel o
+donnein arte
+u rable
+inve stin
+bump ing
+raji v
+sav a
+thro wer
+fore x
+o hhhh
+th rust
+pull man
+r fid
+sep sis
+le ed
+fri ght
+roun ding
+ne b
+ph ins
+ai sha
+utili zing
+squ ats
+gold smith
+j ic
+bo ks
+vau s
+i po
+exclu sion
+tari ff
+po kes
+min al
+land s
+en force
+washington dc
+or char
+g x
+mar ys
+ey our
+aussi e
+bak ers
+un popular
+latin os
+lar ge
+pu tnam
+bol o
+wa de
+pel o
+di zz
+ob struction
+fla ppy
+weare the
+depend ence
+pajam a
+e te
+y ann
+e wan
+disc la
+a ay
+kar ina
+e ic
+an trim
+w soc
+neg atively
+kai do
+fotogra fia
+dh ru
+colo ssal
+mcle od
+k wang
+mani pu
+ex hilar
+us atoday
+summer slam
+co les
+tapro om
+unbeat able
+de ma
+tic ks
+k ling
+fil s
+campaig ners
+ภķ
+brew ster
+audu bon
+qu ay
+ch s
+ki gali
+d ler
+strength ens
+som al
+sign ingday
+gol ds
+pig ment
+orche stral
+g q
+lin kin
+ðŁı ĩ
+ta w
+algar ve
+ho v
+ear le
+gold fish
+am ig
+ex er
+ben in
+dru id
+ðŁIJ ¸
+she m
+quat tro
+mer cen
+men te
+incorpor ating
+bon anza
+state fair
+en de
+concep tions
+e es
+âĻ¥ï¸ı âĻ¥ï¸ı
+d son
+fire arm
+orb ital
+we h
+multi p
+fo b
+requi em
+p light
+thou se
+sa id
+oc re
+remem brance
+n old
+chi pping
+be v
+er t
+ca thy
+sy m
+ri ggs
+m ley
+dialo gues
+sl ender
+how l
+gau teng
+wd w
+to bi
+smo kes
+im plo
+b pm
+ad n
+mom basa
+cap sul
+bloom field
+artic ul
+cle o
+goog led
+flu ffy
+l ard
+en zyme
+ve sti
+ibra hi
+fl ame
+e mea
+out ages
+dispro por
+ble ak
+an sel
+ick er
+st louis
+stock market
+good friday
+sau lt
+stal led
+pro m
+ep som
+b é
+the se
+sau ces
+me w
+lit fest
+pre d
+re u
+kar ak
+si enna
+ell in
+bio technology
+ï¸ıâĥ£ -
+tac tic
+sa in
+por k
+mon za
+ka j
+lu sh
+compart ment
+chang ing
+shraddha kapoor
+fo al
+ar tem
+cu ando
+can ola
+ori ente
+me sse
+d ited
+br c
+box er
+bbc two
+s st
+ment day
+em ing
+de wey
+kof i
+âŀĸâŀĸ âŀĸâŀĸ
+reali zation
+smo l
+tw ood
+san je
+flag staff
+ber wick
+cor set
+can ary
+whistle blower
+et ched
+com posing
+squee zed
+bow er
+auto desk
+ne h
+mathi eu
+ba ja
+Å Ĥ
+hy dra
+da im
+am eri
+insi sted
+mer lot
+gar ros
+heart news
+gaine sville
+cut ler
+bo de
+ðŁĺī ðŁĺī
+lew es
+scoun try
+g sa
+us u
+cc m
+god awgs
+phara oh
+cra e
+mor ley
+hyp noti
+f ades
+neur ons
+fu zz
+ing co
+high landers
+star k
+vig ne
+pac kets
+amar illo
+reu ben
+insul ts
+bas ic
+vec tor
+n me
+ac ruz
+tro s
+transm itter
+ðŁĺ ŀ
+interpre t
+ðŁĺ ²
+pre quel
+mc gowan
+dis semin
+ðŁĴĺ ðŁĴĺ
+mascul inity
+indie gamedev
+ali ve
+te t
+pe tal
+ema iled
+ar med
+ko o
+he er
+ba ird
+super junior
+metro polis
+delav in
+decl ines
+stit utes
+Û ģ
+p tbo
+g lan
+cho res
+e aling
+chri ssy
+ste mc
+vi an
+assassin ated
+pron ounce
+illeg als
+discover y
+cav ill
+fri fotos
+f al
+so i
+sabot age
+t int
+p dc
+ðŁİīðŁİ Ī
+ãĤ Ĭãģ
+ji o
+endeav or
+in sig
+commit tees
+she arer
+me tz
+mar rying
+h dd
+g by
+fre t
+tri sh
+pu l
+scrip ted
+sa ki
+l w
+ke ye
+shim i
+nan aimo
+ca h
+Ã «
+tem pered
+ici an
+du gg
+dish washer
+air field
+s rugby
+gr inch
+y st
+r ms
+mahat ma
+lan kan
+disc ar
+dige stion
+no des
+l ls
+om ic
+gu tter
+tis garh
+feder ico
+election day
+bo he
+master card
+fire ball
+âľ Ķï¸ı
+oy ster
+p ong
+do k
+en route
+m vc
+beat the
+ali stair
+shu b
+sh aming
+cherno byl
+ghi bli
+the s
+pin ion
+d bs
+sal ts
+ic tion
+epi ph
+nc pol
+in convenience
+whit ley
+inspec ting
+wood ley
+wi ener
+skil let
+no les
+m ca
+h ina
+a sha
+willing ness
+well ness
+tam ed
+show time
+dis advantaged
+ber nat
+us n
+mission aries
+coun selling
+arrog ant
+quant itative
+leg alization
+ho dge
+energye fficiency
+cameron dallas
+pos sessions
+p bb
+harris burg
+v g
+hindu ism
+happy thanksgiving
+fi b
+re acting
+tweeta picture
+pol iti
+mu ppet
+hur rah
+pac e
+coast guard
+guar ded
+as am
+par ry
+fore very
+x q
+oom f
+ke anu
+j ind
+ri st
+customer service
+sac red
+ðŁĺ º
+ton er
+occur rence
+mat u
+val dez
+red d
+is ak
+power rangers
+pe asant
+raj ini
+abra ham
+e mil
+car do
+tr il
+hair styles
+obsole te
+sam pler
+direc tive
+delavin kisses
+ver ton
+glo s
+sp ay
+paler mo
+com ets
+man ziel
+chicag of
+ski pped
+pic torial
+h ant
+b mi
+a ol
+re opens
+pad dling
+devo s
+fra ud
+bas eline
+que ues
+sp ired
+sn are
+eu ve
+descri ptions
+daisi es
+ca ching
+gall eria
+tri mmed
+stin o
+recy cla
+ic ular
+bir ken
+raw lings
+fli x
+chic as
+b gt
+lik eli
+argy ll
+thel ove
+ga ston
+bl anca
+ha k
+f one
+sailor moon
+h aci
+ima c
+fl yn
+de can
+bel les
+ap ic
+zo g
+taun ton
+con stance
+lasag na
+ker nel
+in ka
+har bor
+collec tively
+calcul ated
+av ille
+shil pa
+pur du
+gi mm
+fun er
+a est
+pembroke shire
+nighting ale
+n unes
+hyper tension
+hu bert
+sli ders
+infer tility
+comm ended
+transat lantic
+metr ical
+!! @
+Å Ł
+ss g
+bac ca
+inver ted
+fun factfriday
+it ans
+albu m
+acqu ainted
+ri er
+whel an
+sar ab
+mu e
+snoo ze
+pi ff
+agre eing
+sp itting
+jer maine
+n ye
+âľı ï¸ı
+am bush
+ze ph
+con greg
+univers ity
+s app
+wann abe
+pat rice
+ib d
+do glo
+fri dges
+sun d
+king ston
+ar gon
+kam en
+hardro ck
+ds ley
+do lores
+ì °
+ota ku
+pi ping
+be having
+âŃIJï¸ıâŃIJï¸ı âŃIJï¸ı
+blue bird
+an sari
+teapo t
+fire work
+cro p
+log ans
+ty ped
+thick ness
+ig ers
+c fp
+dys functional
+contra sting
+et ty
+aston martin
+tx st
+dra grace
+at tributes
+marath on
+manu scripts
+john stone
+ðŁĺ± ðŁĺ±
+bo er
+ay u
+aru gula
+poo rest
+con du
+assu mption
+anag h
+no h
+delav in
+sit ter
+g ö
+mor ow
+kick start
+com i
+gl acial
+ghe ad
+ba in
+ker shaw
+en dof
+fre ud
+om at
+i af
+hu g
+sign up
+each other
+defin ite
+tu bing
+shak ira
+ðŁijı ðŁı½
+uu uu
+sw in
+sham bles
+ol as
+sk ell
+brit ain
+kn w
+clu tter
+om y
+j ens
+hang ed
+city scape
+scra ps
+un locking
+dead liest
+er no
+breast cancer
+a it
+inspec t
+fu ri
+ðŁĴ Į
+ku d
+ju le
+or ah
+mi ds
+m dt
+bur gring
+r attle
+pu sa
+stal k
+cle ans
+iss ance
+z ek
+worth it
+nam eis
+musko ka
+council man
+urban art
+bar rac
+un solved
+tu l
+g ita
+white board
+soy beans
+em ent
+cont i
+saturday motivation
+conveni ently
+doc king
+t ado
+âı ©
+sp ino
+puppy love
+po f
+fabric ated
+robb ers
+adop ts
+ti fied
+kk r
+indulg ence
+notic eable
+macqu arie
+chap el
+sensu al
+ki ko
+melan oma
+lore tta
+li ance
+ab en
+sp lus
+ga al
+ac ele
+lib dems
+compar isons
+ðŁĮ µ
+rhy thms
+mer y
+en capsul
+nap ier
+ðŁijĮ ðŁijĮðŁijĮ
+ðŁij IJ
+plat z
+fre sno
+re formed
+ran bir
+el it
+the best
+bhu shan
+vin nie
+impro vised
+s ittin
+re created
+e ba
+ec ker
+ac rob
+pon te
+cor d
+gi ddy
+eur usd
+fe ver
+intu ition
+gar i
+dum mies
+bud weiser
+amend ments
+te tra
+sch nit
+ay as
+mar ys
+ci st
+k ani
+ker mit
+ðŁĺ±ðŁĺ± ðŁĺ±
+tin ker
+strol ling
+di visional
+niger i
+omin ous
+menstru al
+kar ab
+k hy
+bw fc
+pan handle
+l illi
+well er
+stra pped
+son the
+transfer ring
+ethe real
+sne aks
+ru dol
+gab les
+jac king
+cin code
+for tune
+canadi ens
+con for
+ab normal
+frank lin
+tit a
+mu la
+persi st
+cu ties
+ki el
+ðŁĩ± ðŁĩ
+her mann
+aw k
+fi asco
+ko to
+we ta
+hi ker
+budd y
+preven tive
+mcgra w
+game boy
+forsy th
+top shop
+si ob
+sad h
+in tram
+follow art
+so aps
+dragon ball
+ou x
+morri son
+๠ĥ
+lu bric
+adul thood
+morri sons
+âļ łï¸ı
+her mo
+ta ka
+stall one
+mis use
+team gb
+ra gha
+con fined
+at y
+hom ophobic
+nw o
+sky news
+ho ya
+ac rosse
+wi iu
+pur ée
+jed dah
+ðŁ¤ §
+advis ers
+ph ine
+an is
+scrump tious
+ë° ķ
+c ke
+vin y
+ter m
+s dc
+o do
+home school
+vas c
+leop ards
+debor ah
+illic it
+cur ran
+as roma
+nau ght
+mar ig
+brand i
+em p
+ðŁĺį ðŁijĮ
+î Į
+su spend
+lu z
+initi ation
+sch aft
+jensen ackles
+craw ler
+post doc
+des ks
+trail blazer
+den omin
+tri x
+no ise
+po et
+± ï¸ı
+s mug
+vol atile
+proof s
+pharmac ist
+sardin ia
+mash able
+kim chi
+co ed
+schal ke
+doo dled
+c sw
+sh ur
+ro x
+do k
+chris brown
+mathemat ician
+ab ound
+ang elic
+rock ford
+d ole
+yor kers
+ms n
+g man
+xavi er
+bor rowing
+mark ings
+longh orn
+k ja
+diver ted
+mm it
+euph oria
+ay yy
+te a
+pa h
+ck i
+un cut
+li ven
+ky ung
+fan art
+mer ing
+red ding
+amo vie
+gri di
+c thulhu
+schol arly
+ju dah
+th bewithyou
+eu calyp
+ðŁIJ ķ
+hert fordshire
+cour troom
+by u
+auc tioned
+ple ase
+mar cia
+ê° ĵ
+succe eded
+el as
+arvin d
+t lot
+saig on
+re tt
+ra kesh
+fd ny
+as en
+se bring
+gladi ators
+you know
+v lad
+gol a
+par ap
+ÑĢ Ð¸
+sab cnews
+one team
+oh l
+sun e
+ri j
+cd c
+star gate
+run down
+plat o
+ph c
+chat ter
+ra viol
+mn f
+mand ala
+li et
+ภķ
+mari a
+hun gover
+consoli dation
+fer rell
+tradition al
+ilove art
+gal ap
+ðŁı Į
+que zon
+espa ña
+ðŁĩ¨ðŁĩ Ń
+ho bby
+steam boat
+mali gn
+guil lau
+pro hi
+its me
+íĥ Ģ
+in scription
+al z
+mari an
+k ade
+mm on
+adju sting
+ne sts
+intern ally
+ci r
+vik ram
+mal ala
+k ph
+fel icia
+the real
+cap tivity
+at is
+marcor ubio
+kale ido
+che v
+mano j
+le more
+gent ri
+vi ps
+tro pe
+" âĢĶ
+pair ings
+mal nutrition
+fr ay
+desig nation
+brun omars
+az e
+tor rential
+pan zer
+ga il
+under the
+the ological
+schizoph re
+dazz le
+freder ic
+mo par
+ad illa
+so ggy
+ra un
+medi ocre
+colo rec
+i fe
+p inst
+blu ef
+Â ²
+world water
+gir oud
+clar inet
+ad olf
+tar antino
+receip ts
+assu mp
+ðŁij Ł
+coffe es
+âľĬ ðŁı¾
+du plex
+s of
+r x
+lin o
+timber wolves
+pan dit
+mo tm
+e ga
+ay ama
+ach s
+outsi der
+ll en
+co er
+til ly
+cheese burger
+ma ds
+ple dis
+emp ty
+national parks
+az iz
+p mi
+jun kies
+f ener
+sq n
+è s
+gener ation
+cleop atra
+bhuban es
+mosqu es
+ty free
+popp ins
+tw c
+or well
+n age
+ka whi
+hol low
+dal ai
+¨¨ ¨¨
+ou ro
+m health
+gi on
+az o
+vis as
+reneg ade
+re ic
+w sop
+ðŁĴļ ðŁĴĽ
+e chel
+tox icity
+mü n
+bun k
+stimul ating
+asth our
+\ '
+ep h
+ende mic
+cn bc
+shrin king
+peabo dy
+michel angelo
+can yon
+wal e
+su mi
+si ders
+inu it
+? .
+profession alism
+dr acing
+plat oon
+p ons
+out bound
+maple leafs
+de sol
+cen cy
+a than
+ver ma
+ru bbing
+ok an
+ðŁij ł
+mull ins
+authent ic
+Å į
+alman ac
+ga ia
+bb q
+on imo
+ke h
+ty a
+tou ts
+y av
+re posit
+, .
+wi ght
+se eyou
+cal lof
+done sia
+bar gaining
+gr anth
+sd su
+amphi theater
+p su
+re watching
+wine tasting
+peak district
+dete cting
+thur man
+phe e
+èª ķ
+u mich
+re r
+sculp ted
+go le
+name sake
+ðŁĶ ģ
+serv icing
+bau gh
+pu gh
+pen cil
+dar th
+munch kin
+at orium
+ten ers
+sun y
+rolling stones
+mag ing
+star rer
+i dris
+fe instein
+ag ron
+âĺºï¸ı âĺºï¸ı
+supervis ed
+chamele on
+aggre gate
+succe ssive
+mo gul
+inst yle
+pol dark
+custom e
+ohio state
+ha ya
+ci des
+broker age
+angel ou
+fifa wwc
+de forestation
+al ton
+pam ph
+hu gged
+ho bo
+change able
+ku ber
+bur roughs
+demon etisation
+cape cod
+vers atility
+or ice
+le ila
+womenin science
+tu a
+he dges
+embarrass ment
+ali fe
+so ars
+ni ghter
+hy mn
+gi pp
+chas u
+tech s
+ni all
+k illa
+hi ka
+cam els
+valu e
+Â ¢
+sc oops
+mah moud
+clu sive
+adri ana
+pac o
+oz il
+un as
+transl ations
+whispe rer
+s bi
+bu xton
+bio tics
+indi ffe
+ken ney
+k lar
+et ching
+barra best
+inst ability
+se ine
+vo tel
+blo gged
+whis key
+my space
+t ant
+lan dia
+give back
+illu s
+aw ak
+ac ab
+f bloggers
+cloud computing
+blat ant
+syri ans
+band ra
+sty n
+an em
+ke ted
+kar thik
+barun sob
+pin ot
+gu bernat
+gay e
+arti ste
+i fied
+conven tions
+hu an
+geni uses
+eeee ee
+fol ly
+somer ville
+pride month
+ðŁĩºðŁĩ¸ ðŁĩºðŁĩ¸
+chemo therapy
+paul s
+bak ar
+ìĦ¸ë¸ IJ
+taiwan ese
+fol lo
+c ss
+re ign
+nn nn
+fla un
+catastro phe
+iti es
+frag ments
+extre mists
+ym oun
+car men
+eze kiel
+conne cting
+se h
+man ta
+remodel ing
+we ymouth
+at oms
+ce m
+ne well
+lu mi
+the open
+mo c
+mili band
+g land
+z shq
+mag gie
+mani acs
+m sp
+ad y
+cre ams
+le anne
+e sta
+py g
+af finity
+pray er
+dun bar
+ligh troom
+ac adi
+wyn onna
+roman tic
+state dept
+sick le
+wh os
+lam o
+et our
+fin ity
+shru b
+shar pen
+pun dit
+ed on
+af ore
+mar s
+jeff ery
+ter ps
+medal list
+kath arine
+accu sing
+ta z
+roy d
+from home
+confron tation
+alle gh
+ðŁijī ðŁijī
+refresh er
+ran veer
+never land
+jo jo
+lu crative
+en am
+ca ver
+pa edi
+man jaro
+flu ids
+the ssal
+oppre ssed
+mu ss
+joh anna
+Ø ®
+cn g
+buil dthe
+sett les
+s ith
+fu ego
+cl amp
+ar ag
+pay er
+ted x
+mand y
+inter stellar
+fr c
+ch and
+b cc
+mo lo
+len til
+johan sson
+grims by
+nature lovers
+ðŁļ¨ ðŁļ¨ðŁļ¨
+shin de
+x in
+international dayof
+transiti onal
+sat a
+cad dy
+wo d
+if u
+ha ys
+holl yo
+j ang
+ir c
+co im
+grad able
+" "
+ðŁį ´
+ঠ¾
+a el
+n yo
+west lake
+time out
+sof i
+phenom ena
+cultiv ation
+ag no
+un armed
+so t
+con j
+gen o
+royal navy
+nutriti on
+fair mont
+ti relessly
+sn g
+re ty
+mic a
+lu cent
+slo ane
+droo l
+riz al
+od ell
+critici zed
+. '"
+la ze
+deser ted
+co der
+pra s
+l illian
+itiner ary
+dav y
+an ap
+whi pping
+hobo ken
+kare ena
+çľ Ł
+vi us
+ter n
+nan tucket
+mis understood
+bu laga
+st ant
+chin ook
+z am
+reli es
+d ss
+ed mond
+sket chy
+m ell
+fe x
+rec tor
+dist ill
+day dream
+wine maker
+ri pley
+billion aires
+hel ene
+ati f
+cul prit
+bertr and
+wou ldnt
+ma pped
+v ak
+gla dly
+parliam ent
+kidlit art
+ware ness
+goli ath
+âĨ ĵ
+view point
+tat ted
+fu ls
+dor sey
+ang lers
+li ds
+ki ya
+bow les
+be h
+b ite
+compati bility
+ance stral
+pro x
+beha ved
+gubernat orial
+ch field
+sab an
+z h
+teen y
+shibu ya
+holli day
+pan cy
+âĿĦï¸ı âĿĦï¸ı
+seun gri
+? ,
+ðŁĩ¦ ðŁĩ·
+im itation
+impac tful
+any i
+gene vie
+añ os
+bate man
+gli der
+af ar
+ra sheed
+effor tless
+sh war
+dach sh
+er un
+at os
+kin i
+ch d
+kha ki
+k lin
+felici dades
+bel o
+as l
+to ppers
+fin ley
+stac ey
+rigor ous
+kar ting
+le ppard
+car michael
+be ret
+c se
+ak hi
+mer ingue
+ab an
+ha ke
+ger i
+er jee
+re sto
+comm anders
+pr it
+fl or
+ad ven
+ex termin
+remain der
+å IJ
+es g
+martin o
+lulla by
+| @
+mi gn
+in store
+big bang
+cor di
+cau ley
+ante bellum
+dg ate
+cro ck
+span dex
+scaf folding
+ore os
+ê°ĵ ìĦ¸ë¸IJ
+pom ona
+ma uro
+uni versi
+re mi
+af ootball
+t ant
+sm alls
+ne h
+worl do
+tropic al
+mor ph
+jav elin
+gla r
+arqu itec
+reminis cent
+tu bs
+spide y
+make u
+syl la
+progressi ves
+blo t
+shor ten
+keep in
+ch ak
+ang st
+super food
+decad ent
+ston y
+neuro logical
+ar boretum
+ann ak
+fe ma
+per cu
+dis respectful
+small biz
+lo x
+co om
+c sc
+bs bi
+pre valence
+him ss
+esp an
+mo ga
+fr ampton
+sky map
+mas se
+levi athan
+( ).
+noctur nal
+car ameli
+ang or
+amne sia
+outsi ders
+she alth
+rhin o
+ant ag
+ag io
+ðŁĴ° ðŁĴ°
+take me
+kab addi
+c si
+m sh
+coch rane
+thessal oni
+sil a
+ha us
+du sting
+obe se
+mack lemore
+mani sh
+len in
+m dc
+gro wn
+shef field
+s rs
+ke le
+car son
+ch um
+dah lia
+can tore
+opp o
+how ling
+cyber crime
+sur realism
+sc ran
+fa iz
+thre n
+rac ists
+r out
+pk not
+se mana
+sin i
+mc cull
+ma chi
+alfon so
+y b
+sar dar
+kend rick
+den g
+reci pro
+on f
+doom sday
+bri bery
+custom iz
+art is
+c pi
+ðŁĻĪ ðŁĻĪ
+sla va
+let te
+en s
+âĿ¤ï¸ı ðŁĺĺ
+cra yon
+ad an
+tr c
+migr ate
+simp son
+row ers
+king sley
+farmers market
+shee han
+ne phe
+bor non
+car ton
+mic key
+all ure
+u lu
+sli pknot
+heb do
+gui do
+dog celebration
+online marketing
+acceler ating
+) ..
+origin ated
+macar oni
+ed tech
+out field
+mit z
+disc us
+adverti ser
+man or
+ha shi
+descri p
+cap ita
+ful bright
+recep tor
+con n
+con ey
+spion age
+r attle
+pre st
+u li
+blog post
+acker ay
+) â̦
+red velvet
+mat th
+inspir ing
+b sd
+ker ri
+po con
+mil lar
+re pur
+accent ure
+ä ¹
+ram bo
+ragnar ok
+dele ting
+british museum
+pat ory
+leip zig
+flori an
+sci fi
+in ers
+br ate
+yo y
+melis sa
+ab er
+ma sa
+po te
+mosquit oes
+transpl ant
+r pa
+; ))
+bast ille
+yl an
+joye ux
+melo dic
+cap tions
+atri st
+roch dale
+gott i
+pew die
+cuties aturday
+who is
+aqu aculture
+tiv a
+sp el
+he ss
+ha ji
+fred die
+co per
+brand o
+v k
+photo book
+* ,
+my dayin
+micha ela
+brune i
+sr ini
+in te
+Ä ±
+de ol
+d fc
+separ ately
+bun d
+ve sts
+to c
+me ck
+rein forced
+constra ints
+car roll
+sq ft
+re ver
+cam per
+bird man
+in action
+gener ators
+triumph ant
+pe sts
+o vo
+gy pt
+al amo
+sc aled
+suresh pp
+sd n
+is mo
+gi os
+) @
+justic eleague
+restaur ant
+gab i
+den gue
+next gen
+exemp li
+ap ex
+inspir ational
+down side
+kid z
+u pl
+et na
+alvar o
+fel dman
+bar net
+m ha
+es ch
+bloo ded
+>>>> >>>>
+kan i
+ho fficial
+casablanc a
+bir ds
+ty ga
+sw amp
+o day
+new castle
+nb ap
+ci sion
+cho ols
+af lo
+ne p
+mon ton
+ak b
+super model
+down time
+th os
+sc wx
+snoo py
+ag greg
+yo ke
+nor cal
+we tt
+prolon ged
+me tast
+beat er
+f ta
+t lap
+disgu sted
+y h
+voice over
+itch y
+ip c
+ðŁİ ¾
+phe asant
+stra its
+ram pant
+j g
+fer til
+assu res
+fortun es
+sal inas
+liz ards
+kett le
+i bs
+cyn thi
+he g
+mc cr
+soccer oos
+happen ings
+cor den
+ðŁĺĤ ðŁijĮ
+t ches
+egre t
+wolver ines
+congratul ated
+ho gg
+bott ling
+wr i
+fer ri
+bo sch
+af ire
+og den
+s jo
+j dm
+sv t
+con tex
+tol lywood
+min k
+me se
+super sonic
+op oulos
+å ¸
+âĶ ģ
+knuck le
+gu ise
+gam i
+chu cky
+z inger
+radi al
+compla ined
+bo da
+fe tal
+discipl ines
+cor ro
+ðŁĩ®ðŁĩ ¹
+op ted
+filtr ation
+ad nan
+em cee
+mi stre
+insom ni
+fer gus
+tra jec
+on don
+med tech
+tanger ine
+madra s
+gru e
+cab s
+z hu
+sureshpp rabhu
+insul ated
+day swild
+pp m
+band ai
+v day
+s ff
+squ id
+lo thing
+not dead
+expre ssive
+cu ll
+ala stair
+x u
+up front
+fish ers
+en es
+um d
+dis missal
+sti er
+sel s
+lu st
+re active
+prote ster
+eyel ashes
+al im
+goo de
+gre eng
+da ir
+com pen
+anush ka
+proto typing
+ma pu
+bear ings
+ðŁIJ Ł
+for me
+bsbi botany
+timo thy
+out skirts
+am bed
+are tha
+wend ell
+stre aks
+ni m
+k pk
+sne e
+fit ter
+quo ta
+p ate
+win ning
+ðŁį Ń
+sho pping
+ma inst
+cul ver
+ste vie
+mcfad den
+counter parts
+gren fell
+fol som
+dor set
+tech crunch
+⬠ħï¸ı
+tip tuesday
+us l
+tre x
+geor gie
+ranveer official
+lic ks
+se wn
+k f
+' â̦
+jap s
+p ate
+orth op
+fe sta
+stra s
+mon tal
+hammer smith
+fore most
+wido ws
+mad re
+ite z
+mito chondri
+lig ans
+z ona
+cari bou
+m ss
+andre i
+weather channel
+gh c
+: ...
+ta ft
+awe ather
+al isation
+bru tal
+bliss ful
+nik ola
+mal icious
+q m
+mpg vip
+bro die
+bl itz
+applau d
+dri bb
+v ague
+dog go
+transl ating
+interpre ted
+hat ched
+ge tyour
+benefici aries
+spar ring
+caes ars
+aw illiams
+la hat
+bro ke
+ti mp
+virtu es
+rel ying
+pie tro
+k tn
+ici sts
+pab lo
+lou i
+a ag
+pn pp
+cha st
+pul ses
+fini sh
+usair force
+type writer
+thomp son
+dog s
+ut to
+ãģ į
+sand al
+new ly
+do ge
+z w
+wan kers
+ne gr
+mu cha
+determin es
+black fish
+sk unk
+mu ps
+instru ment
+phy to
+daysto go
+skin ned
+hai der
+con ten
+ðŁIJ¾ ðŁIJ¾
+we iler
+undoub tedly
+chair ing
+wall is
+sh ard
+zind abad
+adul t
+absor ption
+pre sto
+deplo ying
+drum mond
+battle front
+seag ulls
+how dy
+juda ism
+des de
+part ition
+âľ Ŀ
+no logy
+national bestfriend
+lesn ar
+film fare
+co asts
+christen sen
+ac an
+mb u
+co pped
+ru bble
+sw c
+fun nier
+far ther
+where as
+nano technology
+with stand
+pil low
+bow ers
+to pe
+it ly
+con fit
+ma kar
+comfor ts
+bo sh
+cli pper
+bal la
+sti k
+mil b
+safe guard
+musi que
+eas port
+ya z
+pad ded
+bad er
+fore ign
+chop in
+archi ve
+o ka
+tran sporting
+tml talk
+aj it
+consequ ence
+sc roo
+ff o
+collabor ated
+pug chat
+ye mi
+jav ed
+au burn
+o of
+ma w
+sau cer
+miti gate
+i les
+evangeli st
+ter ie
+re cl
+indic tment
+cat a
+bright ness
+may the
+whim sical
+un lv
+key word
+cu min
+med way
+west world
+tra w
+im posing
+form ity
+coul ter
+ab z
+ny pd
+grass i
+kel sey
+qld pol
+clock work
+f dr
+di anne
+âĺ ij
+ad h
+p ann
+bra vely
+ae ge
+un lawful
+ver di
+pocaly pse
+phar o
+kar la
+reson ance
+ma stiff
+la dak
+bu u
+ma iled
+hi i
+craw ley
+tor rent
+mach ado
+liby an
+effort lessly
+fal sely
+q vist
+ke ef
+craf thour
+cheri shed
+val kyrie
+s ari
+kal amaz
+be he
+ðŁĮ Ļ
+th im
+ro ddy
+col trane
+but chers
+ach im
+wk end
+awk ward
+cab rera
+:) )))
+fran c
+decl an
+con dos
+a ja
+pandor amusic
+char ter
+ph ill
+mon trose
+hatch back
+handic app
+gre aves
+eucalyp tus
+ut most
+t son
+bur ton
+mid wives
+in cur
+ðŁĺį #
+moo d
+compre ssed
+tom a
+must ang
+mo g
+as ana
+te stic
+sho tel
+in sol
+cor sair
+nh q
+ben ny
+sm ma
+kap ur
+in con
+jon as
+ener gies
+don al
+as ad
+se z
+n pa
+archi ved
+stimul ate
+do p
+hy d
+gri eving
+ãĥ Ī
+ron a
+why te
+tree house
+ss ell
+sand ro
+ko bo
+ther most
+se clu
+hi ya
+ge ez
+mam as
+prisc illa
+flav oured
+fas s
+w old
+maker space
+cospla y
+p tv
+happy valentinesday
+sequo ia
+love craft
+gu an
+d tm
+ci i
+yoko hama
+pos thum
+re q
+ðŁĶµ âļªï¸ı
+galat asar
+dol by
+hamp tons
+disturb ance
+stone henge
+ok c
+disrup ting
+month sary
+jun gle
+head lights
+du stin
+micro sof
+happy mothersday
+ko ko
+gra zi
+te sto
+na idu
+mal ay
+ari al
+ru mb
+ab oo
+har man
+tra pe
+spo ils
+je ho
+go dly
+lock screen
+z un
+pi ous
+ma gento
+l enders
+prob able
+corpor al
+m our
+aw al
+su a
+call me
+ton ne
+go vin
+devast ation
+x j
+gear box
+war lock
+per me
+it ate
+gaza underattack
+du val
+paras ite
+clement e
+le th
+i va
+fro zen
+tho les
+to bin
+cair n
+s ill
+luc kiest
+conver ts
+st ale
+pan cra
+euro pale
+wis dom
+sch ur
+ì ¶
+verti go
+bi j
+u bc
+nu re
+righte ousness
+mt c
+factor y
+ver st
+revers ed
+hur i
+hee chul
+fab er
+ar r
+ul ous
+ven om
+ph at
+green ery
+bra dy
+Ã ¦
+: ((
+never giveup
+di sha
+mo ta
+health care
+dun ham
+dex po
+den zel
+bb ins
+f ics
+wh am
+mc g
+eli an
+wat a
+str alia
+tel lu
+pe sky
+spin off
+ar moured
+re acted
+do fficial
+te du
+sag ar
+mor ally
+paralle led
+fi os
+dow ner
+dau gh
+re do
+world cup
+tari q
+bar ne
+glaci ers
+oc cult
+barbar ian
+her mosa
+!! !)
+y ur
+inter nation
+p ss
+sit u
+p int
+american air
+sw am
+dopp ler
+ðŁĴĻ ðŁĴľ
+cincode mayo
+le van
+hell enic
+mc ne
+ju di
+yu h
+st x
+qu are
+ðŁĺĤ .
+sti g
+g els
+mot ley
+hard work
+euro zone
+e ad
+ç¥ Ń
+seab ir
+ci us
+la id
+alpac a
+presu mably
+pewdie pie
+boo ted
+am ari
+tam ine
+sol ace
+bar row
+acade mies
+x ian
+om ination
+dun geons
+b ma
+de ity
+ai k
+stab il
+hir a
+affection ate
+ving ne
+new port
+ãħĭ ãħĭ
+thir ds
+re tains
+aroma therapy
+ski er
+ni ma
+do pe
+cr inge
+con domin
+to or
+anim ator
+sar aj
+seas cape
+minim alism
+lake shore
+calla way
+berg man
+ठĹ
+whisp ering
+stupi d
+ri ghtful
+requ is
+ir n
+se va
+ut pol
+tuber culo
+squ ish
+de but
+govern mental
+christ ine
+all man
+weap on
+s ito
+bur i
+lo lita
+leaf y
+fu ch
+tin ted
+mck en
+a hahaha
+ðŁĩµðŁĩ ¹
+repe al
+ne gan
+ðŁķ Ĭ
+tail gating
+game insight
+ðŁıŁ ï¸ı
+yaku za
+z t
+ti ring
+pro posing
+bow lers
+tra itors
+ak shi
+cler gy
+cit o
+up sets
+tu scal
+symph onic
+sil ently
+shu ff
+black well
+ðŁĺĤ )
+ko be
+rober to
+ri dg
+dc u
+mer ino
+ft p
+east side
+. ~
+nb l
+mn leg
+ts for
+frau dul
+ca pping
+in my
+gymna st
+ston es
+ss in
+twe aks
+shag gy
+oak land
+dem sin
+sang ria
+mm va
+hen nessy
+down ton
+ri ghtly
+in it
+aga ve
+ob last
+northe ast
+friend ship
+dal a
+tro phy
+ðŁij ½
+mag in
+margar itas
+ê ·
+ww fc
+fa sh
+di ke
+cu d
+char t
+ðŁij ®
+refuge es
+jop lin
+n cs
+imp y
+firm ware
+pas cu
+flam in
+health tech
+bell letstalk
+w aka
+ol ls
+la go
+co wan
+bombar dier
+sh ome
+ðŁĻ ħ
+mc master
+na ve
+well s
+u ta
+tell ers
+mis fits
+kap il
+face off
+af firm
+a pro
+whit epaper
+super yacht
+speci mens
+al located
+... ,
+- __
+ka w
+dachsh und
+djo ker
+s work
+qui ere
+or um
+ðŁIJ ł
+som m
+c mt
+ingh our
+skin ny
+lgb ti
+gi ggles
+break away
+resear ched
+par ity
+my al
+ms l
+re tained
+si vity
+make inindia
+sol ves
+defam ation
+wal tham
+sri racha
+road way
+concep tu
+al in
+iw ant
+å Ī
+del ft
+tender loin
+ga ins
+faul ts
+sw ire
+st ellen
+pol lo
+dy ne
+bornon thisday
+asdf ghj
+sq l
+sali m
+advis es
+vo ip
+ìĹij ìĨ
+un touched
+she il
+ontari o
+uph ill
+so bre
+de shi
+nov ella
+du tton
+craw fish
+ا٠Ĩ
+ma a
+tw ine
+kal in
+ðŁĩµðŁĩ Ń
+ye ss
+brook s
+hoo siers
+ton ka
+umbrel las
+ay ers
+ate am
+acqu iring
+su ction
+ä n
+wi es
+tari ans
+soci o
+mat tb
+shepher ds
+o so
+charity tuesday
+s logans
+ninj as
+al bat
+by te
+bash ir
+trampol ine
+mydayin la
+i ja
+bas el
+ror y
+gol die
+fi rec
+un noticed
+pecu liar
+sch a
+ker son
+mour ns
+liquid ity
+qu ipment
+hi bs
+ar s
+aeron au
+slide show
+sla bs
+delici ousness
+sk itchen
+hta fc
+full erton
+cre ighton
+aer ob
+procrastin ation
+az ores
+white hall
+uss occer
+medi ation
+djoker nole
+and me
+um en
+noxi ous
+jo ss
+ili fe
+anni vers
+sudan ese
+et res
+under mine
+whole foods
+diso be
+kor i
+ade le
+eli z
+can ti
+al on
+gymna sium
+sarko die
+meteoro logist
+yl de
+ste en
+stamp collecting
+nas al
+lo tt
+fran ks
+ex ol
+ack i
+good year
+animal rights
+y les
+vio lets
+mm es
+s thel
+ra pping
+tu scan
+wai ver
+tur ner
+eat local
+northe asthour
+anim ations
+tom morow
+t sh
+ff ame
+bra e
+pe tron
+glam our
+br yn
+d cs
+bal es
+ðŁĶ ¶
+bro v
+bre v
+b ons
+physi que
+car ne
+x e
+elix ir
+vol ved
+l oma
+ìľ ł
+æ ĺ
+van u
+ri gs
+bal ance
+va res
+bon ita
+sprink le
+perfec to
+di on
+le ak
+calcu tta
+o ba
+d ma
+c mon
+tun er
+pneu monia
+bo gus
+apolo ge
+cl ough
+bor ne
+)) ))
+revi ved
+o varian
+ner f
+c legg
+fan fest
+cho u
+reali zes
+mc n
+li gu
+leg alize
+just saying
+for ster
+bo sni
+k hi
+in dom
+hei del
+en cryp
+si ss
+ed di
+mar bles
+brisban e
+y ing
+pre paid
+wal sall
+cooper ate
+orche str
+mar isa
+ho wie
+che wy
+bren ner
+andro meda
+e gan
+sto cki
+cav endish
+ag an
+ban o
+de ir
+go g
+bl k
+re thinking
+ch ig
+rhe u
+sni p
+p eng
+semin ole
+m swx
+an nex
+lyn da
+lewisham ilton
+cu mul
+tb l
+dolph in
+agu ero
+........ ....
+pre lude
+at our
+gr anger
+too ting
+ro tun
+dis ar
+home items
+da res
+**** ****
+ðŁij Ĩ
+compre h
+jin x
+as well
+iri e
+circul ating
+ðŁIJ ¥
+over board
+cultiv ate
+rhe tt
+oriente ering
+ca k
+bal kans
+s itt
+jas min
+britney spears
+ro tor
+se aling
+g bc
+oc ci
+f as
+eman cip
+com er
+war time
+tic kle
+son ny
+pac es
+log g
+at rix
+sr p
+g win
+do bbs
+uz be
+the wanted
+dru sh
+ex tru
+m icky
+honore es
+dar win
+re dux
+mm j
+ram i
+jalape ño
+io c
+do ver
+ju ju
+whit ney
+s eng
+en ly
+au ch
+archipel ago
+vigil ant
+man gal
+wil dest
+parano id
+hal i
+bb ly
+sanc tioned
+real ms
+con co
+u ddin
+c sk
+play time
+libr a
+sav ag
+oc tane
+rec tan
+re turn
+par rish
+mor rha
+cc p
+c mu
+sa iled
+se vent
+ro sie
+pil ing
+he w
+boar ded
+seg ments
+neph ro
+( .
+cr ats
+bak es
+ðŁį ¸
+back tothe
+sibl ing
+kirk land
+ke o
+gu wa
+bre ads
+ðŁĺľ ðŁĺľ
+t q
+haras sed
+ga u
+wil bur
+j isoo
+ep er
+li sam
+tri ppin
+sh ino
+ru kh
+beast mode
+cho a
+inst aweather
+rich land
+gar i
+fe z
+cowboy snation
+fur suit
+k run
+a en
+sycam ore
+se gun
+ent ennial
+di h
+o ax
+demsin philly
+ðŁĻ Ģ
+sn hl
+pen nies
+pass words
+ma kin
+ty e
+d eng
+kni gh
+jeep life
+hel pline
+a for
+zz zz
+ste amy
+pic ker
+iter ate
+happen ingnow
+ki b
+bloom berg
+martyr dom
+bul ly
+assor tment
+a hora
+zo e
+no i
+illu stri
+agar wal
+p sc
+electr onica
+recruit er
+gar diner
+rad ha
+naf ta
+dot net
+pi ero
+geor g
+bel s
+ðŁĺĤ ðŁĺį
+tuberculo sis
+run nin
+mor is
+haul ing
+ev oc
+bre thren
+sha ir
+frame works
+a stu
+ri gid
+ku ma
+kre me
+jin nah
+insu rers
+ny u
+f ere
+nol lywood
+good vibes
+- ...
+toi le
+sk ril
+instaweather pro
+cze ch
+pa vel
+one piece
+nike plus
+fi let
+cav ity
+ðŁı½ âĢįâĻĤï¸ı
+ðŁİ £
+dra stic
+dail ys
+siam ese
+re bu
+oste o
+lar k
+f re
+sh elling
+p é
+glad ys
+ðŁıĢ ðŁıĢ
+gusta ve
+submer ged
+grand stand
+att u
+won t
+f pv
+b ley
+jon i
+ang ames
+weigh ted
+al ou
+ठ¶
+les bians
+f j
+anni es
+am l
+dor ia
+dav in
+be ta
+can c
+madewith unity
+ha j
+bad lands
+mu l
+blu ec
+pa wn
+cov ington
+neuro logy
+htt weets
+dysle xia
+thel ove
+ne at
+fork lift
+autom ate
+une ven
+monte ss
+he in
+ha g
+rel ics
+competiti veness
+can elo
+mar tens
+bullet proof
+sk ittles
+g ya
+pri mo
+americ afirst
+woo o
+abor tions
+?? !!
+ma che
+ld ers
+rl ly
+preli ms
+direc t
+cour se
+swa in
+super cell
+ec centric
+sting ray
+ple ts
+wil cox
+west in
+okan agan
+kir an
+car bo
+bomb ings
+ra rest
+bo h
+gaw d
+di gg
+mo ana
+enti rety
+en closed
+dodge ball
+par ton
+milky way
+at r
+thorough bred
+re ally
+qant as
+epiph any
+ine e
+aero smith
+spi eth
+ar thro
+ell ini
+du bu
+bra ving
+âļ½ âļ½
+re structuring
+illumin ate
+equ ili
+mp i
+ash ton
+pony tail
+ma scots
+flat tering
+cru m
+ast a
+à® °
+stranger things
+bar nab
+ر ÙĬ
+make shift
+got cha
+will am
+cho irs
+kilom etres
+gho sh
+eu than
+dol ly
+un ning
+the ar
+cre we
+w sw
+j ace
+dis miss
+ke an
+ho ta
+kh at
+~ >
+thir u
+ren dez
+hart man
+tee ssi
+cas ca
+z ah
+hydr ange
+fo d
+aw p
+mzan si
+thick er
+nago ya
+ne va
+sti que
+cast el
+dam ian
+there by
+ji ang
+ale k
+music islife
+ra q
+calla han
+gou ache
+somal iland
+sean hannity
+ra heem
+lo se
+elo ve
+whar ton
+rectan gular
+illustr ating
+har ne
+auti sma
+scra pped
+ell and
+decre e
+nag pur
+ki pp
+so re
+n md
+ma as
+gun a
+gart ner
+bel li
+then ight
+je on
+gendere quality
+gi ver
+a el
+gar ments
+ne u
+mardi gras
+mar sden
+ro wer
+pollu ted
+camer aman
+vin od
+be asley
+cro c
+ji u
+hollyo aks
+anesthe sia
+al les
+ste ward
+lati mes
+ðŁĩºðŁĩ¸ðŁĩºðŁĩ¸ ðŁĩºðŁĩ¸
+tic ian
+gor ia
+come dic
+ðŁ¤Ķ ð٤Ķð٤Ķ
+nai ve
+sli ons
+ł Ī
+bur glar
+ðŁĺŃðŁĺŃ ðŁĺŃðŁĺŃðŁĺŃ
+york shi
+se ñ
+fan boy
+lau rel
+inci dence
+potom ac
+rober ta
+presi den
+pr yor
+os bourne
+w ku
+te me
+pal ae
+ðŁ¥ º
+re boun
+itu de
+red dish
+k hand
+coloni alism
+north carolina
+ðĿ Ĵ
+manne quin
+lady bird
+ta sty
+knowledge able
+g shore
+ðŁĮ Į
+à® ©
+qu aker
+salz burg
+med alists
+chy na
+bridesma id
+ma ori
+ro p
+outra ged
+in adequate
+truck ers
+al ana
+ìĿ ¼
+ri x
+oooo oooo
+command ments
+lam beth
+aa j
+eco friendly
+bla z
+morecam be
+boun cy
+rou x
+rai ded
+mi zed
+sh c
+gaw x
+labor atories
+ru bs
+rest room
+consult ations
+ca jun
+virgin i
+so ir
+rev ue
+ple in
+wag er
+ç ¹
+we do
+growing up
+! ðŁĺĬ
+face ted
+sin ners
+ho vering
+ti ene
+seas oning
+an ja
+leg go
+il is
+fla x
+dev o
+ash ram
+mati sse
+ker i
+go wer
+bo tox
+mar shes
+unh cr
+ts m
+opti mus
+dun i
+stu ffs
+so k
+order ly
+n bad
+islam ophobia
+raviol i
+fab er
+cre ds
+won ka
+in fusion
+over weight
+daily news
+assi mil
+acol lege
+medalli on
+kili manjaro
+sti ff
+tham es
+sun ken
+th ard
+my dubai
+hilari ously
+han nel
+plu mber
+fair view
+separ ating
+rasc al
+qui en
+necess ities
+confeder ation
+ll ll
+: ]
+weak nesses
+bron co
+ra ffles
+el ot
+ãĤ¸ ãĥ
+advent calendar
+ðŁİ ¹
+stra vel
+tun ic
+k su
+im peach
+e spionage
+! -
+di ment
+cur rant
+bio de
+commu ting
+by ron
+ðŁĴĵ ðŁĴĵ
+shad ed
+tr uro
+cray ons
+ar ne
+h sc
+fre aked
+dram ati
+fle ek
+u cd
+marl borough
+^ -
+cross ings
+mal o
+black ops
+bin ance
+cho ked
+chen ey
+pl o
+ge stures
+val edic
+ryan air
+rem ington
+v cs
+mc kee
+ec z
+be gs
+nail art
+mayor of
+happy fathersday
+war t
+pet itions
+n ingly
+clean energy
+bro x
+sl alom
+exist ent
+ab ay
+ug liest
+tom p
+stom a
+sel by
+goal scorer
+ben ji
+overwhel mingly
+lan s
+semiconduc tor
+south korea
+re scheduled
+sk yl
+en listed
+dow ski
+si del
+rosen berg
+nas ser
+white head
+pri us
+har are
+en n
+ry der
+í Ĥ
+mon g
+clas ico
+transpor ter
+po tty
+is me
+** ***
+vic e
+sk it
+ode ssa
+l mp
+her n
+raci ally
+pin oy
+paragu ay
+obitu ary
+go es
+bu cha
+side walks
+angu lar
+un constitutional
+transiti oning
+i bu
+gu ys
+un packing
+oooo oo
+black girl
+ber gs
+Â ¯
+wordof theday
+trump train
+thunder bolt
+m si
+fasci sts
+ठ¬
+t sk
+collap ses
+raje sh
+loveis love
+migr ating
+set back
+ðŁĺĬ âĿ¤ï¸ı
+t els
+safety first
+nar rated
+jae joong
+un answered
+lique ur
+en nes
+dal go
+bill ings
+salt water
+mer maids
+lon gs
+clap ham
+we arec
+pic collage
+n ach
+h ace
+pois oned
+lo th
+ag na
+adel rey
+guar dia
+poli shing
+peace keeping
+d all
+p isa
+la pland
+process ors
+de andre
+so bs
+p once
+dra ins
+c be
+ðŁİ¥ :
+spla sh
+meat ball
+fon tana
+worcester shirehour
+ne v
+bri sk
+b int
+ac r
+po x
+cay enne
+skril lex
+j fc
+hahahaha hahaha
+gla s
+en gul
+tempor al
+oni zed
+con cre
+com pose
+vibr ations
+plant ers
+fer t
+criticalrole fanart
+t bli
+sch allenge
+huck abee
+munici pal
+iam bic
+radi os
+ne vis
+dura bility
+mc cla
+horse back
+inst itutes
+ful fill
+atta ch
+ate ur
+ak an
+resi sting
+illumin ation
+hand le
+hair care
+om ent
+macle od
+ka iser
+g no
+bear down
+ly f
+gl omer
+distor tion
+z m
+san k
+roo sters
+is now
+as ports
+ag en
+wo ken
+st george
+ro mper
+my le
+econom ists
+ru to
+t will
+health and
+d ito
+ws l
+tair p
+pra kash
+mic heal
+h ts
+w rights
+kat su
+fioren tina
+defen seman
+d itch
+var sity
+texan scheer
+ba ham
+sc anned
+we il
+seduc tive
+ðŁijį ðŁı½
+fu e
+er win
+dav ison
+ter ran
+moo ds
+wool f
+re source
+@ .
+cu sh
+ðŁį °
+regre ssion
+cur led
+la zer
+jo anne
+ab bott
+mo z
+down ers
+mm mmmm
+valent ina
+k hair
+dream t
+cro ok
+che k
+ste aming
+nephe ws
+cl eric
+as ober
+indefin itely
+w ye
+us news
+joy ce
+flu shing
+wynonna earp
+ron do
+kis s
+hot dog
+bar ns
+sax ophon
+far ley
+gas p
+decre asing
+al way
+pe x
+l sd
+shi ft
+p outine
+ra zz
+rescu ing
+ni ko
+ho ch
+cc l
+u aap
+n ts
+m car
+il wx
+conqu ering
+ket tering
+stur dy
+delay ing
+sto k
+vani shed
+cath ar
+bin gham
+in v
+ic hiro
+he mo
+budge ting
+[... ]
+be ss
+sebasti an
+slow ed
+ðĿ ij
+musli m
+stun s
+acton climate
+ve a
+se ton
+rose tta
+oun t
+hard in
+flu id
+ca w
+ðŁ¥ Ĥ
+yach t
+un l
+sp hy
+provoc ative
+or ic
+is back
+__ _
+nicol as
+gy an
+loo se
+fl in
+reb ate
+: ::
+! "@
+com icon
+she ff
+down stream
+chic hester
+beach life
+mom life
+diabe te
+ar ra
+van e
+ok u
+ye o
+man go
+try out
+app ell
+he irs
+arjun a
+dd u
+na veen
+movi c
+soci alists
+s back
+criteri on
+soyu z
+k her
+da z
+yol anda
+wine oclock
+re ina
+one w
+leon ard
+en dez
+u bs
+support local
+facilit ated
+carameli zed
+b pa
+vuel ta
+my tho
+m ami
+spe are
+nbap layoffs
+fe vre
+nick jonas
+im print
+c so
+craig slist
+la salle
+gi deon
+ha doop
+dis regard
+w ud
+tu c
+ma gee
+acou stics
+ta a
+qui e
+pol a
+cr t
+dw yer
+dis sec
+capit ol
+men tion
+kn oll
+he igh
+fin ders
+plac ements
+l se
+indi ra
+gur i
+madhuri dixit
+kingdom s
+iambic pent
+geor gina
+je ky
+conflic ting
+bay an
+aga tha
+uph old
+dr on
+vic ar
+ex pat
+periph eral
+pe ssi
+fa f
+ance stor
+? ..
+wid get
+pun c
+comm enced
+beav s
+air waves
+ad dis
+po a
+de sses
+co den
+vu e
+ru pee
+kar in
+spo ck
+m sy
+ภ°
+pr ick
+fill more
+ti fication
+thing sto
+sar de
+em ile
+pere ira
+n ad
+bright ening
+arre sting
+wo king
+usc g
+sp ill
+raspberry pi
+hu go
+ite c
+is ma
+cuff links
+optimi zed
+oc c
+mi wx
+en ka
+el ited
+afford able
+sa kh
+coron ado
+ho h
+at ul
+ai oli
+jim cantore
+accoun ted
+vin ay
+her mit
+groo ves
+ran ch
+r illa
+we tter
+ou tof
+veter in
+ni kov
+ki an
+fair banks
+ram apho
+n iti
+k ko
+ru sty
+ne stle
+tv xq
+shahe er
+âĿ¤âĿ¤ âĿ¤âĿ¤
+penn ant
+gem stones
+dem debate
+ðŁIJ Ĭ
+auton ews
+support indiefilm
+mach o
+ve x
+new sat
+ne ti
+conce ssions
+can died
+yof the
+mac au
+den ds
+cricke ters
+san iti
+mari ano
+gh at
+ar toftheday
+¡ ľ
+e gos
+gen oa
+chat bots
+bri er
+al labout
+mon ty
+spi ed
+r tr
+comfor t
+sni ppets
+real time
+gra in
+exam ined
+en lightening
+tt u
+god bless
+release the
+sing ular
+ki ans
+ha ka
+sor ren
+defe ct
+mar g
+equ ities
+d orian
+su ka
+per l
+aishwar ya
+pul lover
+preci sion
+fair way
+ne ve
+rive ting
+vill anova
+en com
+ak o
+passion ately
+europale ague
+siem pre
+x vi
+enligh tened
+c fr
+âĺħâĺħ âĺħâĺħ
+wast eland
+is f
+new comers
+emergen cy
+amphi theatre
+- .
+text books
+figur ative
+tre mb
+pe sc
+ab hin
+ab bot
+ac acia
+har ds
+por sche
+kau ai
+el isa
+car rick
+abo u
+elli er
+be ch
+neu tron
+galap agos
+ru ben
+in nis
+how to
+nun s
+sab ine
+i ac
+clin ched
+no tori
+fi ves
+cairn gor
+per i
+gr c
+ðŁĴ¯ ðŁĴ¯
+mal m
+twelf th
+di ff
+rout ines
+marty n
+lin den
+synthesi zer
+nu mber
+game cube
+fal kirk
+byz antine
+queu ing
+gr ill
+scal able
+char red
+rou ting
+her bali
+gri zz
+ðŁĺŃðŁĺŃ ðŁĺŃ
+tol l
+termin als
+l pc
+ab d
+war mups
+remo vable
+¯ \
+vi go
+pap aya
+ne ve
+lov ingly
+jo kers
+ib les
+sse tt
+poten ti
+pel e
+gi gi
+sadi q
+leg acy
+son o
+ru pees
+retar ded
+ele e
+par r
+fi ance
+ey re
+say ers
+pend ants
+mak nae
+al bans
+adap ting
+p ff
+pu berty
+ji u
+ing rad
+hypocr ite
+diplom ats
+phys ical
+rob by
+bon sai
+ãģ ·
+f att
+catal unya
+âľ ĸï¸ı
+ro ma
+more land
+so e
+conver sions
+stl blues
+shol m
+gra ssy
+pra do
+on u
+assaul ting
+> _
+sett es
+dis graceful
+aph ra
+âļ½ï¸ı âļ½ï¸ı
+ठª
+kil n
+goal tender
+s ru
+philanthro pist
+b als
+th n
+stu den
+sando val
+dogre scue
+eli ons
+asse ssed
+lar go
+hec tares
+sh rm
+sa if
+cle avage
+no ches
+n ene
+fat alities
+cur ing
+clean ser
+al es
+p vp
+south bank
+pizz eria
+marsh als
+kni fe
+an dover
+tbli ghtning
+sr sly
+ou te
+digi mon
+timesof india
+prome the
+le bo
+f su
+wit z
+rever e
+man as
+mam ba
+ch ica
+gu an
+exhibit or
+csr racing
+d ere
+xx xxx
+gu sta
+story time
+ston ey
+organ ics
+and u
+se am
+min ogue
+anushka sharma
+ab a
+ðŁİĻ ï¸ı
+ugand an
+chro matic
+as sn
+document aries
+sh t
+ru paul
+loy d
+k ats
+e us
+ite ch
+me dusa
+pan ty
+kel logg
+et to
+talla de
+sha a
+do st
+p ms
+mari ana
+je ster
+croo ks
+ðŁĶ ¬
+min danao
+ind hoven
+ðŁ¤ ª
+le xi
+tv n
+jan is
+co te
+ãģ Ĩ
+ser rano
+iw m
+ðŁIJ ¬
+k ke
+distribu tors
+cap u
+counterfe it
+camp site
+ag gie
+ðŁĺ ¼
+chhat tisgarh
+~ @
+state u
+san di
+prevent able
+cl s
+can ne
+mm c
+i ver
+sa haran
+pal is
+night out
+do s
+ap ia
+absc bn
+manag erial
+aro se
+mo wx
+aro sa
+ðŁĮ ³
+under dog
+remo ver
+astronom ers
+lent ils
+su scep
+smoo ther
+pend leton
+fau cet
+e mory
+dal mati
+af cb
+tic us
+exem pt
+en rol
+d heim
+ðŁIJ º
+restric tion
+star fish
+sto w
+snor kel
+thunder birds
+she ad
+homo sexual
+dy n
+as li
+andre tti
+dou che
+dom o
+tar mac
+slu mber
+pr onto
+first dayof
+mini ature
+mari achi
+argu s
+recomm ending
+mobi les
+in ce
+illustri ous
+or c
+adver ts
+gr its
+wea sel
+pag oda
+over pass
+gre ys
+maxi mus
+arma gh
+wood land
+sun ni
+ðŁĴ ī
+ë Ŀ
+ti one
+soci o
+ho s
+ðŁ¤Ĺ ð٤Ĺ
+wind sor
+subsequ ent
+munch ies
+id h
+exclu ding
+e mi
+cu th
+z ai
+week days
+law suits
+barn ard
+Ø ª
+pe tting
+net es
+mul ligan
+pharmac ists
+ra quel
+e ton
+cran ston
+gil ded
+cle ary
+ce ph
+ra a
+pam per
+lombar di
+as in
+sher ry
+pro d
+for te
+ari anism
+buffalob ills
+æľ ¬
+ðŁĶ¥ #
+uu u
+just ices
+car ina
+nat in
+mas low
+dro oling
+cog nac
+cam ber
+el ong
+r dr
+in en
+convic tions
+am use
+tro ck
+harm less
+visit ation
+gen omic
+bl and
+beno it
+chim p
+tuscal oosa
+gre asy
+x po
+gil t
+se q
+per mitted
+christma seve
+book s
+mu e
+old school
+human right
+be ati
+ðŁĶ Ŀ
+sh at
+sculp ting
+h wan
+fern andes
+sci utto
+fu entes
+endeav ors
+maid stone
+un paralleled
+shou ted
+queen of
+mer c
+band ic
+ve da
+sel angor
+pi le
+ja han
+intimid ating
+disapp ears
+cl ich
+za ha
+w urst
+hi v
+fod ils
+cor dless
+aaaa aa
+hy dra
+bel inda
+e els
+bu f
+su staining
+rugby league
+no c
+brig itte
+( ðŁĵ¸:
+tromb one
+soo the
+smo g
+ad p
+stab le
+ing ley
+diagno se
+ms g
+we ss
+tic keting
+one e
+nsw pol
+e up
+auto psy
+adity anath
+sun down
+river front
+si ya
+p is
+hier archy
+dur ango
+di jk
+ren shaw
+he aps
+epide mi
+david bowie
+interne tof
+dd i
+nation ality
+mb ar
+air y
+win der
+w alia
+elli ott
+c x
+bav arian
+pl att
+an tw
+wi wx
+sof ter
+ne ha
+h eller
+th and
+dani ela
+bo ast
+degra dation
+ðŁĴ¦ ðŁĴ¦
+transform ing
+man e
+av ut
+ðŁĺĪ ðŁĺĪ
+vo ter
+the e
+t ate
+pu ff
+in door
+sop roud
+boy ce
+boris johnson
+wait in
+immun ology
+ðŁıĨðŁıĨ ðŁıĨ
+âĿ Į
+street food
+liz asober
+cavali er
+c elia
+need le
+motor ing
+g ato
+, )
+ra de
+harve st
+t ms
+jar pad
+on ey
+air men
+v re
+impair ment
+abhi shek
+snoo p
+l ant
+fam ously
+bl ou
+s ze
+g ander
+un touch
+tu f
+dee jay
+col lateral
+b ind
+ðŁļ ©
+pin ning
+ic n
+' ;
+the economist
+ul tram
+worldwater day
+ti poff
+the i
+feed ers
+campa ign
+sc umb
+day weekend
+yo m
+pe dic
+h ough
+ps v
+pl in
+on de
+boston marathon
+az zy
+* _*
+con ley
+thi ago
+hoo o
+gal erie
+luci d
+je tt
+gl itz
+final fantasy
+achiev ers
+y ung
+peregr ine
+op hi
+dam es
+biom ar
+âĺĢï¸ı âĺĢï¸ı
+sk c
+l ics
+fl ank
+ar rahman
+ho of
+uphol stery
+t ats
+wo z
+Â ¿
+snor ing
+ra er
+l ju
+ap d
+pl ating
+kan u
+im ation
+fragr ances
+m ra
+mor ay
+mo tt
+im muni
+hearti es
+bho pal
+tim ers
+g ata
+color way
+car nation
+win get
+si ghs
+s ville
+optimi st
+chate au
+olympi ans
+ci o
+singer songwriter
+ny o
+fi bers
+bur ch
+ag ro
+mil ne
+ig bo
+cr amer
+ation als
+dan ube
+pad ma
+nor mani
+en forced
+bre ck
+boeh ner
+ar den
+sur rendered
+pros thetic
+om a
+ha iled
+calcul ations
+w fa
+bi b
+fcb live
+fon da
+west coast
+que sts
+friend ly
+to wie
+fit ch
+bal ot
+star dom
+scrat ching
+ho sa
+thi ka
+o ven
+stro ke
+out post
+pharmaceu ticals
+hi kari
+mu y
+af d
+fallon tonight
+squ at
+or u
+dra ined
+chocol at
+ë¯ ¼
+wor ths
+ri b
+mu j
+that s
+residen te
+it el
+boo st
+mi gos
+mul led
+la a
+etsy shop
+don keys
+me k
+p tc
+flin ders
+e hs
+ro hit
+mu ir
+g ad
+compos itions
+åĨ Ļ
+combu stion
+i kh
+yemen i
+wav ed
+gar ci
+ak os
+oo ds
+fu sion
+se que
+s lan
+pl ur
+kic chasu
+shenan do
+s ams
+worl den
+horo witz
+with me
+mic robes
+k ki
+ðŁĴĶ ðŁĴĶ
+w su
+patch work
+fre er
+y aki
+the art
+symboli sm
+mil er
+bt n
+ma bu
+side kick
+motiv ates
+sag itt
+natur als
+serv iced
+ps ori
+pa ola
+qu ig
+i badan
+gi ggs
+ë ³
+sciento logy
+si oux
+salam at
+d res
+cad bury
+d hawan
+ci ón
+_ '
+swa pping
+maris ka
+james bond
+explo sives
+ay les
+af er
+s agu
+cen sor
+tom a
+jeff erson
+ring ed
+par tist
+ir responsible
+aguil ar
+vac ay
+equ itable
+altrin cham
+ac ur
+man ish
+ger min
+schoo led
+pu tter
+ed ad
+nav al
+toast y
+sol areclipse
+dish u
+coy ne
+ac co
+mu ck
+mar an
+el os
+len der
+cro ix
+worth less
+ha ber
+gun men
+ðŁį ĵ
+zen ith
+t enders
+hur st
+hol tz
+itali ans
+car low
+u cd
+characteri stic
+bun g
+av l
+u th
+sa sia
+rs l
+red man
+neighbor ing
+green peace
+sti ps
+follow party
+y gk
+en os
+omni bus
+na issance
+chri ssy
+secu re
+call back
+ji hoon
+memor y
+block er
+l anta
+daf fodils
+bil t
+ffer ty
+fau st
+ie c
+nipp les
+so g
+m nd
+jagu ar
+bol dly
+ab poli
+pro position
+gun sense
+evan sville
+cu tters
+we go
+dou n
+do x
+stal lions
+ka j
+shi ppers
+j awa
+vol o
+le ven
+pap rika
+kov ich
+jor di
+induc tees
+app alling
+dial ysis
+allevi ate
+âĢĶ âĢĶ
+pie ter
+mid wi
+q tr
+juli ette
+inter mission
+haw ks
+act ment
+one ill
+k lin
+vam ps
+fam ous
+cou ld
+autom obi
+da an
+west end
+elli p
+nh c
+mel anch
+web series
+ton gue
+snat ched
+smy th
+tan gible
+sl i
+e asing
+bar stool
+over lay
+afford ability
+ting ed
+ter as
+ay ush
+wanna one
+rh ine
+dan a
+sh ana
+kend al
+fer tile
+w ir
+repl eni
+lar vae
+is ro
+con vos
+ab brevi
+u cc
+hun gry
+bur rows
+ag er
+nav i
+mat in
+du per
+cer n
+ma don
+ķ ï¸ı
+é ģ
+tu ps
+hy att
+sh ep
+friday night
+wis er
+hei di
+hat ton
+p gh
+foun tain
+wrist bands
+ahmadi yya
+aeri al
+subscri bed
+so los
+m ace
+sla yed
+for fe
+dul ce
+christ mass
+arun jaitley
+viol ate
+ob stru
+ni eces
+w vu
+idy l
+fa ze
+pre serves
+infr inge
+premi ers
+inter vals
+agen cy
+( ©
+stand alone
+di mes
+bo er
+param eters
+ge tit
+ðŁĺĺðŁĺĺ ðŁĺĺðŁĺĺ
+tu lane
+for given
+scol l
+mb ps
+smash bros
+rob bi
+prima vera
+ali st
+ghost ly
+ay at
+ye ats
+impre ssionist
+ear phones
+caul field
+wai kiki
+sal ute
+sc ou
+mu ay
+louis vuitton
+bak hta
+ado g
+inven tions
+hur d
+forec lo
+stream line
+thalai var
+ch snews
+will ard
+t sn
+euro parl
+cru sher
+my sore
+gro wer
+ra ping
+pat ti
+g den
+sm w
+muf ti
+kid man
+ab r
+soun ders
+skep tical
+ðŁĶ İ
+sun dar
+i me
+fer g
+feather weight
+ar lington
+pas qu
+ag azine
+wearab le
+nati c
+mccl ure
+inter mitt
+hor de
+six ties
+car te
+bha v
+ze al
+experi ential
+ador ned
+som mer
+eno te
+hypo thesis
+stin ky
+pro to
+dead lines
+vo gel
+mus ings
+monc ton
+gu ter
+f le
+aci on
+voice of
+ta sha
+inhabit ants
+type face
+s ba
+bts x
+ðŁĶ Ĵ
+wor x
+u hc
+jo ko
+cell ars
+gor o
+continu um
+... &
+weather cee
+ha p
+sr k
+ris ers
+lonely planet
+un named
+co eur
+ðŁį Į
+the world
+ili ke
+fa sten
+ami go
+ri ba
+ramapho sa
+staf fers
+had ley
+? ?"
+fi ore
+sal ut
+hu ff
+bez os
+Ñ ĭ
+ra der
+kam ala
+in line
+fill ers
+um atic
+all in
+shat ter
+re in
+o ku
+ch ases
+fla gged
+baby metal
+water stones
+ts b
+cut out
+op hel
+aam a
+rockab illy
+sto lic
+jet blue
+ich ick
+down ton
+uzbe kistan
+pat na
+la q
+gr ange
+) _/
+subsi di
+sc p
+newsc ast
+it sa
+twee tyour
+e mor
+archae ologists
+uni fication
+por ta
+q x
+protec tors
+pro hib
+charis ma
+car tag
+ren fre
+scul pt
+guwa hati
+de ma
+boo p
+unf pa
+dex ter
+lay la
+alleg es
+sou ps
+never again
+l ys
+cal c
+bar oness
+visu alize
+ger ber
+absor bed
+i ers
+a han
+fon tein
+detec tors
+verst appen
+sv c
+formul ated
+ac dc
+li x
+in competent
+bh k
+lour des
+water house
+snow ed
+appreci ative
+sig ma
+lizasober ano
+pen ned
+pay check
+tall inn
+fanc afe
+par isi
+av alley
+vi g
+ru fc
+hard ship
+so cute
+po ise
+ì ¹
+roth schild
+k ly
+???? ????
+l hp
+il ay
+f hs
+am ad
+ide als
+brad bury
+bal boa
+nic ot
+kid nap
+wol ve
+tas manian
+op t
+matthi as
+ãĥ³ ãĤ
+super markets
+mylittle pony
+me lee
+li ster
+gr oun
+fe dora
+kind ness
+en en
+bra hms
+¯\ _(
+ros well
+mar lene
+ic u
+re formation
+or ail
+he brides
+dispar ities
+terrac otta
+swal lows
+re id
+influ encing
+flu or
+den e
+tum our
+blon des
+thunder bird
+sh eva
+moga dishu
+ka b
+cre eps
+i ving
+ene ed
+anno y
+âĶ Ģ
+intri gue
+enqu iry
+ar aj
+tur al
+kuber netes
+end lessly
+divi dends
+tor a
+ti sh
+commemor ates
+un ra
+tri b
+pon ty
+ne m
+diss ent
+brew ingco
+ðŁĺ ½
+nor mali
+bi of
+( ...
+chil len
+ì£ ¼
+mell on
+av is
+mccor mack
+ing ra
+enrich ed
+custome rexperience
+testo sterone
+snu g
+sett i
+ger onimo
+inqui rer
+bre aches
+very thing
+bloom ing
+mu ra
+dispo s
+bi de
+de va
+shade sof
+in trin
+sh ev
+s ven
+nayanth ara
+gan esha
+c ws
+ber ta
+label led
+use um
+nick named
+ma han
+car uso
+ap ur
+ðŁij Ĩ
+w q
+orphan age
+discar ded
+mag nu
+lu e
+je on
+bridge port
+pac ing
+mercur y
+( ðŁĵ¸
+marx ist
+amphi bious
+transplant ation
+stit ching
+then burg
+gradu al
+ãĤ Į
+ro ft
+ma ils
+ine c
+guy ana
+dopp elg
+ver o
+re write
+head less
+harb augh
+gate way
+car sforsale
+sw i
+st is
+mach t
+un de
+sura baya
+stap leton
+nur turing
+mil ner
+ya o
+lma oooo
+ko sh
+arsen al
+k ame
+er ry
+ar royo
+dis misses
+ru bbed
+rc b
+lew d
+dil u
+and or
+vi de
+ur in
+inter sec
+ha ar
+al b
+year swith
+app leton
+é al
+ul livan
+suc cu
+monter rey
+d mx
+artem is
+ron nie
+farm land
+s football
+gro tto
+anth i
+ãĢ ģ
+à® Ł
+vid ya
+jimmy fallon
+ൠį
+t zer
+gravit ational
+w thr
+u hhh
+e hr
+tin ker
+ti juana
+scran ton
+ram charan
+bar clay
+re van
+m si
+ka p
+wr s
+we thenorth
+tor al
+sat u
+gro m
+fac ep
+erick son
+z yn
+se dge
+oo dle
+spur sofficial
+ds p
+sic ilian
+soli hull
+recei vers
+ladak h
+hend rick
+ther i
+presi ding
+mc guinness
+litt ers
+gun nar
+gh oul
+wi b
+n tv
+kar o
+fro ck
+b lau
+ampli fy
+all is
+ul lah
+memo irs
+kh loe
+intercep tions
+pet day
+lo oney
+con fin
+ch ay
+piyush goyal
+frequ encies
+ut z
+event ual
+warm ly
+obli vion
+an ka
+ta it
+âĿ¤ï¸ı .
+director ial
+ru lers
+prince s
+mu ck
+stur ridge
+deu ce
+abri dged
+bagu ette
+un cles
+pen du
+min ding
+forre ster
+av ila
+wall er
+wall street
+ment or
+hin o
+high way
+crom well
+fanart friday
+mb i
+co yle
+a hi
+tro ve
+spie gel
+pay tm
+mcin tosh
+jan sen
+nit i
+nash ville
+len o
+leicester shire
+le gos
+dic t
+ðŁĵ ½
+sp ad
+beverly hills
+sy rah
+separ ates
+z ain
+un fit
+dra gs
+tan ia
+over flowing
+hri thik
+haw thorn
+z ani
+mac far
+fi de
+to tem
+pe ds
+fundament ally
+cal ico
+sin ner
+j ä
+hil de
+ds d
+ten ay
+ta hit
+mil f
+lie b
+inform ing
+up lift
+ra el
+mortg ages
+lec t
+ii ii
+guillau me
+compos ites
+old smobile
+l end
+gar th
+com mish
+bapti zed
+scorpi ons
+ru cker
+bringback our
+alli ance
+thalap athy
+tal i
+sp ans
+eri dge
+wither spoon
+lin da
+sky lar
+kor n
+hom s
+Ä į
+sil enced
+caf fe
+ar ty
+dist inguish
+to wed
+pun g
+jessic a
+ear nest
+beau fort
+t ama
+study abroad
+si khs
+new bie
+nav ratri
+mar ble
+loun ging
+lit ter
+dal it
+so sa
+iz es
+gra de
+com promising
+tr iton
+de tta
+v j
+chau ffe
+spec tral
+powe red
+montess ori
+artic ulate
+hal ton
+al co
+ye y
+mn twins
+acoun ty
+ðŁijı ðŁı¾
+âī Ī
+mad men
+kal a
+gru m
+chi k
+ati s
+su me
+akh tar
+job search
+high lighter
+bo ath
+âĦ ¹
+tar zan
+lam bo
+âĽĦ ï¸ı
+ox fam
+dump ster
+pretz els
+mac os
+incl ined
+fac tual
+adverti sers
+shu i
+pu ree
+ml pfi
+anti dote
+cap o
+pa str
+merc ado
+but ton
+ar min
+ag g
+lol la
+horri bly
+er rands
+christop he
+time snow
+monday motiv
+li ss
+scand als
+mc i
+dispropor tion
+âĺ İ
+sur pass
+samar itan
+so tho
+pu rest
+fl att
+trivi atuesday
+delec table
+leop old
+hermi one
+chou dhary
+en rich
+¡ ¡
+subsi diary
+ine qualities
+bachel or
+auto immune
+la kota
+i hop
+ad jec
+the simpsons
+sh es
+se k
+gret chen
+up stream
+hin akhan
+coper nic
+x tina
+lu g
+tough ness
+e ad
+cli pped
+bi us
+sl v
+fah ren
+dee pak
+ca u
+x an
+im mature
+dig ni
+bo bs
+shred ding
+but tery
+accommod ations
+de ven
+chun ks
+super league
+sky bet
+kil dare
+je et
+ë į
+ce k
+wrec ks
+pro pane
+oh l
+tb d
+quo i
+trum pp
+mi mo
+reluct ant
+ver ne
+o ic
+ma gh
+ar nau
+se ver
+li dge
+stair way
+kicchasu deep
+ðŁĶ º
+mach ining
+aama admi
+ot i
+c da
+al it
+pan y
+inst alls
+ac ct
+e shop
+di em
+hard well
+fulfill ment
+sc afe
+qu ack
+extrac ts
+swee tened
+fi ghton
+f di
+d inger
+wal tham
+us ur
+refe rees
+seok jin
+gran n
+af rin
+th n
+sch af
+par cels
+bet is
+amar ine
+nom an
+kh tar
+mor itz
+cou pling
+bar ons
+ðŁIJ ¸
+Ã ¸
+sl p
+sad ler
+x ander
+tri ad
+mc millan
+kh z
+divi ding
+ìĹijìĨ Į
+dar yl
+zed d
+le ys
+pla ques
+flu ori
+tipper ary
+on nell
+di dier
+lang ford
+im c
+the sun
+bir dies
+ar cha
+ye ssss
+t di
+dar ia
+cand ace
+al tam
+pal aces
+ch it
+sant am
+event ful
+book of
+ad b
+mon stax
+cre ole
+co el
+âĸ ½
+we aren
+sten nis
+she ath
+ati sm
+gron ingen
+mlpfi m
+le pre
+wrong ly
+rsp ca
+rendez vous
+acknowle dging
+pel vic
+solic itor
+sla ys
+nue stra
+lo d
+is lander
+fer oci
+fashion show
+ra ss
+dge on
+adole scents
+sma shes
+negli gence
+grate ful
+ved ere
+sw oop
+ing l
+apol ice
+vand alism
+gan n
+jo ao
+di supdates
+zimbab we
+under age
+radi ance
+w of
+bour geo
+pla s
+cr ani
+gh ue
+wrec kem
+warran ts
+re form
+jim mie
+at wood
+ys l
+neil himself
+l bj
+i man
+tan to
+nois se
+ver bs
+equip o
+al together
+mam ent
+l ice
+dou glass
+tier ney
+pri med
+j hal
+furn itu
+braz ili
+v ill
+past els
+n ison
+u ff
+paral ysis
+jay e
+im po
+ðŁij ģ
+strate gically
+pakistan is
+was sup
+super bike
+thank u
+tru elove
+sha ikh
+israel is
+vi p
+to g
+li en
+la ker
+grey hounds
+cul ars
+bian chi
+balot elli
+ar ran
+loo s
+str ates
+he bron
+ar vo
+sunder land
+the al
+tomb stone
+sand man
+c pac
+thanks giving
+love him
+lat ino
+an in
+aka if
+ĭ ãĤ
+tor quay
+di est
+alli anz
+ðŁĺ ķ
+golf club
+cl lr
+wal cott
+sch nau
+promp ted
+nomin ating
+len nox
+val et
+mon ro
+may ward
+e ph
+ðŁĶ Ķ
+inter oper
+r da
+re flex
+arm chair
+ê° ķ
+stri pper
+por ti
+ph arm
+ham za
+ni reland
+ne ue
+h pv
+port foli
+sun burn
+fris bee
+be al
+bapti ste
+x h
+ty m
+pr ati
+o vers
+haz rat
+deser t
+der ry
+us ky
+em mett
+ach arya
+)_/ ¯
+shu d
+may a
+ham ill
+ra im
+nr c
+fitt ings
+cur vy
+ðŁı ĩ
+ster ling
+ॠĢ
+wal kin
+short cuts
+mil ly
+ast ur
+alpha be
+pl i
+pe z
+miss you
+rad ford
+ml g
+ta eyang
+notjust lakes
+du mps
+seren dip
+le ur
+ra ving
+e ster
+de priv
+absc bn
+ðŁijĩ ðŁı»
+scar city
+o cr
+mean ings
+cap t
+da hl
+fer mentation
+bri oche
+to win
+out lander
+massi mo
+en cro
+ðŁ¥ ³
+buil t
+po tam
+kir i
+tm w
+monit ored
+k ites
+peoples vote
+gray son
+íģ ¬
+afri ka
+a dies
+i vote
+gy ne
+g annon
+di x
+c mc
+ou ral
+fox andfriends
+bel i
+ig ne
+gl an
+katrin akaif
+co politics
+qual itative
+p si
+lu cci
+disc oura
+âĺ ®
+kel li
+gau tam
+carac as
+reale st
+pu la
+in us
+hill top
+make aw
+atten borough
+tw y
+r arity
+peck ham
+ma hon
+corn elius
+clin icians
+ton line
+tb i
+paradi se
+ka si
+inev it
+fresh ness
+colling wood
+lun atic
+defen se
+cop d
+in fra
+wain wright
+sains bury
+alab am
+te ma
+lac o
+chec ker
+releg ated
+tren t
+stal ks
+huff post
+bhubanes war
+ast ral
+share your
+prim rose
+hi me
+cat an
+end ment
+en dow
+cle mens
+mal oney
+hil ary
+game time
+den ise
+collabor ators
+b wo
+radic als
+gue tta
+ici on
+au a
+snap matic
+sat chel
+excav ation
+base man
+s ão
+gn ation
+fel d
+surve y
+shah zad
+ma st
+anirud hofficial
+tru cker
+ot ago
+geo graph
+ethe l
+âļ¡ï¸ı âļ¡ï¸ı
+s ver
+mu tt
+internetof things
+ancho red
+wh ouse
+bang la
+bal main
+ç¹ ĭãģ
+break fa
+á Ģ
+twi ster
+te tris
+ca v
+stag s
+g z
+au b
+stor med
+hel ens
+yar mouth
+st asy
+gustav o
+co sc
+vin son
+up p
+sc ricket
+assump tions
+app e
+nu h
+u er
+pre mise
+n aga
+e amon
+coron ary
+na f
+north side
+el mer
+ro tar
+out lining
+el f
+re surg
+kat elyn
+in can
+hyster ia
+ce e
+am bani
+pro lly
+Į ãĤĬãģ
+ax es
+san jose
+rem brandt
+mag pie
+even ly
+scor sese
+qu aint
+f g
+b buk
+indian football
+weare all
+spd wy
+pis ces
+ec g
+âĺħâĺħâĺħâĺħ âĺħ
+pre orders
+: |
+ni pple
+sal azar
+ju me
+jail break
+min n
+bas sett
+ze tta
+jef free
+ad jun
+tic on
+san diego
+drink local
+chol era
+solic itors
+o bo
+com post
+ni an
+wr a
+tre ach
+ic ic
+profession al
+del ve
+leg ate
+histor ia
+cro issant
+con noisse
+nam o
+palli ative
+chem trails
+i ority
+global warming
+comic art
+behavi oural
+re sted
+li as
+cli mates
+Ł ãģĦ
+rut land
+nou rish
+menopau se
+hot ties
+demen ti
+ve spa
+mel ville
+anal ogue
+tz man
+str ung
+im perfect
+gl are
+cir cling
+ros berg
+rec o
+oc ity
+lo ire
+em be
+do ssier
+ne el
+nan do
+me a
+gal vani
+fin esse
+ag p
+berke ley
+asi m
+âĺº âĺº
+quil ted
+ish ere
+un matched
+po tion
+for z
+at re
+selfi es
+juli ana
+ðŁļ ¶
+âĸ º
+mel ton
+âłĢâłĢâłĢâłĢ âłĢâłĢâłĢâłĢ
+spin rilla
+pur cell
+ed p
+at leti
+tony awards
+ra ja
+pro gno
+mol ten
+stu ff
+p ally
+nobel prize
+âĻ» ï¸ı
+spiritu al
+spe ake
+sa sha
+bri um
+tru ss
+critici ze
+assassinscre ed
+yor uba
+u lo
+fire man
+workin progress
+ef cc
+fla res
+ro bot
+hi kers
+cl l
+shado wing
+pat sy
+leh man
+c ns
+å ±
+guad al
+à± į
+ra pe
+r honda
+paralle ls
+son ja
+langu age
+land ings
+z ola
+cr amps
+bur ning
+apprais al
+jol la
+ham m
+kas a
+gul ly
+f go
+uly sses
+ri be
+ðŁĴ Ħ
+ib u
+eti enne
+bri ar
+fin ely
+comb ating
+y ql
+go tham
+we chat
+to paz
+primar ies
+l se
+iz z
+hel e
+dispon ible
+cy stic
+bel ichick
+th rush
+kansas city
+ge om
+soli di
+red bubble
+by stand
+cambridge shire
+par fait
+ast le
+ow o
+ind ore
+stom ping
+sm elly
+ðŁ¤ ĸ
+locom o
+adm itting
+hol me
+clock wise
+min sk
+mc co
+for get
+ev p
+cam ra
+ab ella
+yo tes
+universit yof
+mé xico
+silver ado
+ric ket
+crom bie
+pu j
+eradic ate
+deli ght
+y go
+glam ping
+vic a
+du ggan
+coun ters
+cf d
+sc our
+react js
+pu ram
+paras ites
+in ki
+vill en
+stel la
+li mbo
+ang as
+k cr
+ðŁĴļðŁĴļ ðŁĴļ
+vap ori
+mum ford
+oli gar
+à ¼
+al oo
+boo ties
+ad r
+k elli
+dru mmers
+av ici
+nature uk
+ron al
+in trac
+un splash
+le che
+g oma
+el ine
+envir o
+bi onic
+bu eno
+mi k
+av in
+star ling
+em powers
+cake day
+boy cot
+ðŁĴļ ðŁĴļ
+ðŁĮ¸ ðŁĮ¸
+v ach
+m ci
+fractu res
+ger i
+sk ing
+exclu ded
+lu ce
+ja ve
+ig gy
+evi den
+aki stan
+a wn
+mor als
+luci fer
+ha ban
+tumb ling
+sunday motivation
+mo sley
+captain america
+sch icago
+the one
+mo td
+d ts
+ðŁIJ ¼
+rep ell
+ii i
+locu st
+geo spatial
+mer sey
+immer se
+desc end
+ber nade
+j s
+boat sales
+win der
+cran k
+sing leton
+candid acy
+ben a
+ðŁı» âĢį
+high lander
+ol t
+k prs
+healthy lifestyle
+four teen
+end the
+ith aca
+circul ated
+r ans
+pre valent
+ha vas
+splend or
+roo ster
+kalamaz oo
+jewell ers
+enne dy
+rou sey
+es y
+cann ons
+ornam ental
+// //
+ren don
+win ne
+mol ding
+eid mubarak
+coun tess
+simon a
+ha wa
+fo es
+du ster
+sb u
+por tray
+mar ries
+goo dday
+cho co
+achi ever
+ðŁĺ¹ ðŁĺ¹
+pre neur
+tr amp
+tom i
+n bat
+garden chat
+farra khan
+ever glades
+ab ru
+sou sa
+se ce
+homes wee
+terre strial
+bar it
+sri devi
+ol u
+mel inda
+f rick
+can dies
+ðŁĺŃ ðŁĴķ
+qu reshi
+family fun
+exor cist
+cardin al
+ny t
+dies el
+cu mulus
+capric orn
+si ology
+lor na
+dou gie
+an die
+super sport
+c fl
+п ÑĢи
+say ang
+pe ek
+ภĬ
+lo be
+j em
+ing lis
+gg led
+c sn
+amne sty
+chu ps
+ba es
+sau er
+ðŁı IJ
+mongo lian
+en et
+back street
+dr illed
+acce ssing
+ce o
+b se
+ai ken
+pur r
+wor sen
+whe res
+war k
+testi fying
+bu ri
+bla st
+aw g
+ðŁĵ ĭ
+re defining
+hear ing
+u ci
+c mp
+bon i
+tail oring
+ta ji
+noc chi
+em t
+stephen king
+ne et
+compla ins
+campaig ner
+luci ano
+twili ght
+ti esto
+pas sports
+flo yd
+cathe dr
+na ked
+caregi ver
+b coz
+ade cides
+ku ri
+ly k
+br aries
+dren ched
+disc lose
+ðŁĴª ðŁı½
+le blanc
+je tty
+gar ty
+chip mun
+b su
+rhyth mic
+ic z
+fri d
+anne x
+ame x
+solo ist
+lanc ers
+arro whead
+speci fication
+simul ated
+na is
+inver te
+bo wing
+wor ship
+f z
+abo ss
+sha q
+ì¶ ķ
+challeng ers
+an arch
+aamaadmi party
+ãħĭãħĭ ãħĭ
+suffol k
+so corro
+sn ell
+cla dding
+absor bing
+shaw a
+particip ates
+ðŁį Ķ
+book stores
+bak u
+seap ort
+ko jima
+gab y
+pack ard
+electr ician
+let it
+mo wing
+fa wad
+young jae
+hot mail
+men ing
+u rie
+intim acy
+con ti
+: ")
+lifeis good
+in ciner
+i dri
+craz iness
+jour nos
+fran chi
+bott len
+al da
+ff es
+k x
+south we
+air a
+clay ton
+sco ti
+f j
+bri ga
+ð٤ĺ ðŁı»
+demonstr ators
+y z
+stor k
+na q
+casc ades
+travel chat
+plat a
+pad ma
+fran ci
+at tain
+bat girl
+lom bard
+hoo s
+d dos
+neon atal
+discla imer
+r ss
+r ant
+di sen
+tex aste
+so cal
+frac tal
+cam ry
+stri fe
+sn acking
+mu h
+sant ander
+mor ons
+gra f
+par ades
+hu ston
+dru pal
+mi ento
+kir stel
+hy de
+vom it
+forti fied
+sphin x
+da v
+bir yani
+win nings
+s baseball
+mer ged
+lovel ondon
+ling ering
+dream big
+car leton
+liveli hood
+djan go
+astri d
+gri ds
+down e
+bru ised
+s ne
+scarec row
+hel ium
+f nc
+bi ggs
+an ter
+restor ative
+em pires
+ab del
+life style
+kiwan is
+colloqui um
+me en
+pr ick
+anti que
+ze b
+mi mic
+edmon ds
+ðŁijĬ ðŁijĬ
+q ing
+pp el
+mc gill
+interpre ting
+âŀ ķ
+rash ad
+do ka
+narr ator
+electro magnetic
+ash by
+sau ra
+iran deal
+âģ īï¸ı
+krish nan
+in di
+ff en
+bre a
+os man
+multin ational
+chi ppe
+recruit ers
+aus biz
+p ounding
+re gen
+cur sor
+refu sal
+mac s
+in ak
+ax ial
+wa ifu
+up cycled
+hindu stan
+cas sini
+carly le
+scrat ches
+re ef
+man atee
+eat ery
+ðŁĵ ¢
+un condition
+sen pai
+on ther
+comic book
+pro sciutto
+de mar
+mi se
+ma ge
+fre ec
+aye sha
+al der
+android games
+ley ton
+ho ck
+door way
+chicagof ire
+aali yah
+sw elling
+bi x
+. ðŁĺĤ
+evan kirstel
+torpe do
+kon stant
+genevie ve
+ma ia
+ha user
+do torg
+hide ous
+fi k
+sp raw
+e ek
+z appa
+wan dered
+' '
+ra jan
+bam bi
+( $)
+wid ening
+tool box
+sa ir
+illumin ating
+pra ys
+out patient
+i w
+day o
+lo b
+sw fl
+sha des
+gu ms
+coo kin
+ko di
+gri ffin
+traum ati
+ste a
+slaugh tered
+god bless
+air time
+pseu do
+b sa
+hau led
+ar if
+à¸Ńภĩ
+le l
+wc po
+mil iti
+char ters
+worl da
+ru k
+k gs
+digital india
+is able
+idyl lic
+esp ino
+marie tta
+e bo
+team canada
+ab our
+wil ton
+rock stars
+fav ored
+phys ic
+wrink le
+tb r
+d print
+ball arat
+ad al
+z ey
+ðŁĺį ðŁĶ¥
+tom lin
+mt r
+pal sy
+fener bah
+tight en
+phil ia
+ir oning
+ry u
+b ant
+enqu ire
+ca ir
+abur ger
+tru n
+green berg
+chau han
+ir ina
+sh ani
+trend setter
+pre tt
+zaf ar
+alo ve
+v ici
+pan ic
+no o
+lu stre
+disrup ted
+bal lis
+son sof
+mon si
+inst ac
+ake st
+ëĭ ¤
+kw ame
+horror movies
+distric t
+sau cy
+mb an
+ar mies
+with drawn
+med ics
+loft us
+er oom
+be kind
+ar ns
+all on
+un ison
+davi ds
+cr at
+nicot ine
+so or
+sm x
+on co
+cospla ying
+zombi es
+har ms
+e ger
+ro sy
+moon shine
+fe in
+ce tt
+du brov
+reg ents
+ben itez
+ðŁijıðŁı¼ ðŁijıðŁı¼
+ste c
+m alia
+prioriti ze
+ic eland
+ft se
+v amo
+lam ont
+homo sexuality
+bre es
+regu i
+cb p
+te j
+sky sports
+deter gent
+sha sta
+de rel
+conserv ancy
+colori zed
+accol ades
+vis o
+show your
+nan ow
+bice ps
+us ability
+bi m
+dailys ketch
+pearl jam
+stran gest
+mega deth
+broad casts
+bar ren
+ar ton
+chri ss
+confi gu
+lu res
+is the
+e ul
+railway ana
+global health
+gi anni
+u aap
+s lum
+consci ously
+ab re
+n up
+bud get
+v ada
+e sch
+real ness
+er ased
+th unt
+be z
+armist ice
+ðŁij ¹
+sh run
+o led
+driver less
+ðŁ¤· ðŁı»âĢįâĻĢï¸ı
+won dr
+sk an
+sal aam
+mother land
+h wang
+gen o
+gang nam
+tw right
+endor sing
+en ic
+ador ation
+pau sed
+patric ks
+do cked
+plat te
+ff xv
+ethnic ity
+auto show
+side show
+after life
+re located
+orphan ed
+food network
+dare to
+and ra
+sla ps
+v live
+swim s
+re imagined
+mist le
+re vise
+real ity
+bhar ti
+ðŁĴĻ ðŁĴĽ
+late st
+prou dest
+gra sses
+lan yard
+fresh est
+carcin oma
+anom aly
+zieg ler
+sum ner
+ly rix
+gor g
+is d
+av el
+swild life
+me squ
+john cena
+euro league
+sab er
+master ful
+yar ra
+cogn ition
+jacob son
+abo lic
+sir loin
+shuk la
+moj ito
+su pere
+st weet
+me z
+e sa
+rudol f
+gur a
+where you
+tt m
+win s
+trust worthy
+ny k
+bra den
+table top
+good food
+es on
+be k
+lingui stic
+gra ys
+ch ath
+h cs
+mon i
+de ans
+cu ssions
+ch ell
+slo ws
+he mi
+d app
+shar pie
+boo sters
+a os
+str ack
+se dona
+mu eller
+hard wick
+or nate
+thor a
+sal ud
+o twol
+ch um
+mi ho
+for age
+thel ittle
+tear ful
+ones elf
+min dy
+sm g
+gmb h
+emer ald
+ðŁĶ´ âļªï¸ı
+tu tti
+recep tions
+re vising
+i brox
+tope ka
+sal ami
+expan se
+i books
+dob son
+cli o
+at s
+ðŁļ Į
+mo ha
+is ance
+shu tters
+moo t
+jan ine
+marvel comics
+jor dani
+pos er
+kenne th
+hy ung
+de ja
+ase ball
+speci ality
+eu ston
+classic car
+had ith
+ðŁIJ ī
+chas ing
+iz o
+gros ven
+ag lia
+thisdayin history
+t row
+om ile
+hu ar
+by n
+sal ine
+div ine
+demon ic
+ty ran
+han dover
+revit alization
+pa ella
+cryp tic
+se dg
+m end
+dun kirk
+bre d
+wal d
+sport scar
+a ard
+whe aton
+da ener
+k lan
+br t
+bakhta war
+spi res
+schu bert
+ro ti
+poli sh
+o se
+ag ame
+wonder con
+prote stant
+bo sa
+ðŁĺ Ł
+d ü
+joy ride
+ger trude
+âĿ Ŀ
+gil a
+v h
+tw a
+tra v
+swal lowed
+star ve
+la in
+ent ren
+rei ki
+su kh
+cra ic
+az u
+web page
+kee fe
+hypo the
+hir sch
+hel le
+camp ground
+w amy
+tra vi
+sha hi
+san deep
+ru i
+han uman
+dw p
+reposit ory
+no or
+no ff
+un real
+p ell
+black history
+har vick
+ma scar
+pay ee
+pa sha
+gastron omy
+d ÃŃ
+ai g
+rosen thal
+open day
+embelli shed
+t tip
+sun bathing
+go pack
+end ome
+ï¸ı #
+invali d
+final four
+st fu
+squish y
+ra sta
+mo sch
+jam esc
+die trich
+sel a
+mel b
+el vi
+t dp
+sun i
+sli t
+j ha
+bi za
+spi ked
+l li
+l illard
+vam pi
+syno psis
+az har
+kendrick lamar
+ĮãĤĬãģ ŁãģĦ
+heart less
+country file
+air play
+arrog ance
+pre e
+virtu oso
+ãħłãħł ãħłãħł
+raj u
+le bu
+for ward
+tu g
+dro s
+mondaymotiv aton
+concep cion
+thel o
+pad i
+looo ol
+ÑĢ Ð¾Ð´
+it ss
+eth ical
+end uro
+__ :
+expend iture
+mon ste
+mas king
+terri ers
+ib is
+e mber
+cu mple
+punctu ation
+pi per
+ir vin
+ade e
+yy yyyy
+flash backs
+cel sius
+don nie
+bo gota
+ben evol
+the script
+shil pa
+pro se
+fin dia
+ze ke
+ne ko
+do ves
+blues lyrix
+fro sh
+sowe to
+mp lo
+al ai
+sab i
+raq qa
+wf tv
+stro ller
+ian somerhalder
+ðŁĶ ª
+an on
+mo seley
+! ?!?
+sta king
+mol y
+car tri
+c sg
+ast or
+transc end
+ma er
+de ux
+cow girl
+sas k
+pun ter
+ma ken
+o ates
+love tt
+grow ler
+sag in
+v n
+ssi ble
+officeof rg
+y mc
+sab ar
+faul ty
+ap ha
+ak on
+ðŁij «
+snow don
+ae w
+raise the
+ðĿ ĵ
+grue some
+clement ine
+sp ing
+lat a
+worlden viron
+mi mic
+can aria
+bakhtawar bz
+ao a
+fal a
+ãĤ Ń
+avi va
+you uuu
+thi gh
+la dders
+gu mbo
+tz ky
+fu zz
+plastic pollution
+est ate
+strength ened
+k ant
+dr in
+cal vert
+transform ational
+frigh tened
+mac lean
+elited angerous
+ear thy
+t son
+to da
+j nu
+.. ,
+mic hal
+i ban
+je ong
+is real
+sim coe
+exclu sives
+blue bells
+ben e
+te u
+pil sner
+pens ke
+athe ists
+m pu
+cartag ena
+ðŁĴĹ ðŁĴĹ
+million aires
+kk kk
+it ar
+subscri ptions
+remo te
+ma fi
+hin ton
+w cc
+ho k
+ds b
+ab leton
+sevent y
+pun ks
+e indhoven
+sh one
+mcfar lane
+lim popo
+empha si
+Ã ¼
+sin fo
+pe tre
+man grove
+ch ino
+ber tie
+play lists
+push awards
+p af
+deb bie
+c do
+r ino
+ðŁı¾ âĢįâĻĤï¸ı
+fol ke
+bon nar
+th ine
+sl an
+hal ter
+evi e
+aw some
+vul tures
+spar ky
+seiz ures
+âľ Ķ
+ram one
+ine ffe
+al n
+pro ctor
+ast ra
+the voice
+gro te
+sci on
+dead line
+am aya
+tain ted
+patter ned
+exce eding
+cross fit
+kay lee
+drop box
+ru shes
+tack led
+mo by
+retro gamer
+n cbd
+benef itting
+shay kh
+guild hall
+gen try
+dream cast
+dread ed
+bun dled
+th aw
+revol ving
+n pt
+kylie jenner
+imagin ative
+ron i
+over came
+family time
+ds burg
+car naval
+relation ship
+recogni zable
+cor oner
+ho le
+fan fic
+emir ates
+bur ritos
+analy se
+thin ner
+ne es
+galli poli
+bl r
+cat woman
+-- >>
+au lt
+ada ily
+nau ghty
+ili o
+solit aire
+mtv br
+jocel yn
+arun ach
+rep ent
+south gate
+hy acin
+essenti al
+fent on
+and um
+it or
+go pal
+sl inger
+po sei
+aw il
+wi elding
+ra ila
+eli as
+a sto
+Ã ¤
+tend ency
+str ata
+ker t
+< -
+im acele
+da es
+sti mulus
+han ley
+fit nes
+ec stasy
+lim ous
+ha iling
+ðŁ¤ Ń
+chis wick
+tar ies
+sla v
+pul i
+moderni zation
+black mail
+b ingham
+h fx
++ +
+ðŁĩ®ðŁĩ ³
+ni v
+we a
+profess or
+k off
+bol ster
+su ave
+sequ ences
+pepper oni
+not te
+dre n
+ãģ¨ ç¹ĭãģ
+hs v
+o ga
+ap tly
+z ad
+excel si
+rin ka
+mol dova
+min n
+ma bel
+conferen cing
+bas ing
+of er
+ob si
+hamill himself
+care less
+brief ed
+inhe rent
+par ish
+dub nation
+town sville
+sar awak
+gee ky
+doncaster isgreat
+was abi
+gu p
+phen o
+dra inthe
+carrie underwood
+ble eds
+bbc world
+ane w
+alta f
+dul wich
+ani ston
+w ti
+sumat ra
+gra fton
+bl n
+me ster
+bode ga
+re go
+es q
+an jo
+sump tuous
+mai sie
+ï¿ ½
+wil t
+jak ob
+el vis
+se pul
+mu ster
+air pollution
+president e
+happy monday
+exten sively
+fl ondon
+t ls
+play ing
+pe ed
+din ho
+var dy
+pi ka
+n iro
+au cus
+ðŁį ¦
+nu ll
+el ondon
+juvent us
+imag ines
+dis ab
+lit o
+d ura
+work places
+promo te
+mc caf
+wood work
+waw x
+à® ª
+tt ino
+shar i
+sem per
+better together
+ðŁijĬ ðŁı»
+ze bra
+pon dering
+en chil
+ho m
+cosm ic
+tan z
+mo cked
+ec cc
+ath ed
+abo lish
+prop eller
+paris agreement
+assemb lies
+indu stry
+fraudul ent
+pe sa
+chang min
+ax x
+ðŁĴ µ
+irr ational
+cu sa
+ramad han
+octa via
+on elove
+jac ki
+bar ak
+taxi der
+seri ous
+nathan fillion
+mc en
+ch k
+po part
+grav ity
+copp ola
+reading fc
+illu sions
+j ig
+ww x
+re sh
+ex porting
+buzz ard
+âĻ ¤
+p cm
+lan apar
+ko s
+arom as
+antal ya
+ww dc
+ven a
+phil a
+ball in
+ðŁij Ħ
+quin ta
+ma o
+f ery
+eigh ty
+sentim ents
+safe guarding
+r wa
+pu ffs
+luc ille
+de cath
+sl u
+nu gent
+de ter
+braz il
+ze iss
+super bowl
+subsi dy
+alter n
+hi dalgo
+enz ymes
+ä ½
+tag ne
+hair dresser
+adri en
+walk out
+oppo ses
+can tina
+bed side
+af an
+ðŁĶ Ĺ
+prophe tic
+dan es
+un successful
+super charged
+pk k
+exem ption
+hart le
+secu lar
+cli pping
+br s
+united way
+c net
+pat chy
+ha gan
+e en
+âļ ľ
+var a
+sym pathi
+never trump
+affir mation
+om f
+ny cfc
+ma ja
+sur ro
+keer th
+up scale
+sandal wood
+mon archy
+kno bs
+å ĭ
+po tholes
+hunger games
+ter races
+na sir
+coun sell
+welcome to
+wa q
+se aman
+m ita
+stun ningly
+on theroad
+in ability
+) !!
+bon go
+ant v
+sp ut
+worldenviron mentday
+resu sc
+y td
+fi m
+eun hyuk
+sa chin
+rose anne
+cler mont
+ape c
+am ina
+v ening
+n antes
+al most
+sin us
+ex as
+ty l
+ti en
+ple ad
+lanc s
+bur naby
+re k
+jo om
+observ ers
+disco graphy
+cl g
+âĻ ¦
+sn ack
+r ti
+o ily
+crystal li
+bru te
+web development
+topp ings
+la f
+an is
+ad der
+reli ving
+car lin
+battle of
+we g
+syri an
+pon t
+n dc
+lagh ate
+yu ma
+sp p
+p iti
+ro bbing
+mart ing
+rey kja
+raj put
+nc ds
+kie wicz
+âĢ¢ âĢ¢
+vam pire
+substan tially
+opio ids
+nepal i
+k line
+ar oo
+under stand
+lit t
+u it
+thro mbo
+sar ies
+qu ot
+b alling
+t tr
+s gh
+philip p
+br ant
+ac l
+m ello
+whit taker
+. ;
+defi ant
+b gc
+repl ying
+mir ren
+metamor pho
+sch wab
+bul ge
+utili zed
+pick ering
+par don
+d sa
+ภĪ
+doo ley
+cumul ative
+Ð »
+ur gency
+e mir
++ /-
+¦ Ī
+ot as
+âı ³
+station ed
+grape vine
+ar ac
+karan johar
+f ancy
+sau l
+coo gs
+lgbt q
+ا٠ħ
+jav i
+u mmer
+pl l
+den is
+dai pur
+pu ffin
+lewi sham
+fand om
+co pe
+ves matter
+s ve
+hel pless
+deo dor
+ostr ich
+kaz an
+friday the
+con dor
+v x
+sophom ores
+rob les
+cu tt
+cli mbers
+ë¦ ¬
+sle g
+sn f
+mac ys
+hydr ating
+grou pe
+po yn
+mou lin
+hg tv
+lmfa ooo
+sulph ur
+asdfghj kl
+annab elle
+hump back
+bra ved
+viswas am
+multi purpose
+hu midi
+escor ted
+barb ican
+f ad
+cor sa
+ðŁ¤ «
+pi ppa
+here to
+can y
+ser gi
+or cas
+o vie
+ed ou
+s any
+glob alization
+man cini
+food truck
+f is
+defi brill
+sch re
+sma fia
+love wins
+la ut
+k aka
+hol lande
+game on
+resurg ence
+out side
+olympi ad
+int an
+abstr action
+rapi d
+pal om
+cal le
+jas min
+attack ers
+swag g
+mit ra
+ky lo
+à® ²
+her mitage
+gor do
+e ira
+so sfam
+roll out
+exc ite
+sy nod
+mer rill
+c als
+as sa
+liveli hoods
+ju ve
+the black
+gopack go
+ant lers
+alban ian
+wool ly
+qu iche
+puri fication
+are th
+smar thome
+ne k
+all blacks
+mex icans
+is m
+ger ms
+comple xion
+mar ck
+u shi
+ðŁIJ IJ
+char l
+ca stic
+till erson
+giuli ani
+biode gradable
+mal bec
+bo is
+ju bil
+im es
+r ame
+gene tic
+esp nu
+ch ley
+so ho
+go pher
+g sc
+buu ren
+cu be
+bridesma ids
+webin ars
+to e
+mani pur
+viol ently
+notic ias
+ex changing
+chi ev
+replac eable
+muay thai
+bu ss
+sp il
+instal ment
+div ya
+cait lin
+o lim
+fil tering
+whirl wind
+sta red
+prior it
+pr am
+pompe ii
+mono logue
+k ite
+bu ka
+â̦ ..
+vac cine
+bre ro
+woz ni
+sol ent
+re ferr
+my rt
+gridi ron
+galatasar ay
+fro ze
+clare mont
+ðŁ¥ ĥ
+victori as
+ssel dorf
+pa stures
+net neutrality
+ch or
+ðŁij ģ
+ಠ¿
+we ho
+symp tom
+jo sel
+in ous
+dragon con
+power ball
+p te
+four thofjuly
+ec la
+ear buds
+where abouts
+salt life
+depriv ation
+ch ter
+wi ggle
+syste m
+ps st
+ch az
+d any
+ri mo
+oax aca
+lanapar rilla
+barcel on
+melanch oly
+way back
+ho tro
+n si
+l illy
+kur o
+ja han
+intellec t
+board game
+ðŁı Ĭ
+sneak peek
+k prc
+jail s
+cand el
+zan zi
+mor timer
+star ch
+ra gs
+p fa
+long live
+k art
+gir ona
+cro cker
+christop h
+precau tions
+war ship
+per m
+paren t
+van gogh
+gif ford
+allegh eny
+ra yn
+ut m
+sten cil
+rec alling
+pen ney
+z azzle
+ìĥ Ŀ
+hin ds
+aren as
+nu ev
+law ler
+gu in
+do this
+ðŁij ķ
+ì¶ķ íķĺ
+we g
+ti b
+ri din
+complex es
+turbul ent
+pe sos
+de marcus
+vall arta
+sam sun
+kis ses
+hein rich
+deport es
+wil ms
+ur d
+then ext
+inki gayo
+ho wi
+fir sts
+carri age
+clean liness
+mas war
+is ch
+ax el
+si zzle
+road house
+fr ans
+ent ourage
+co bble
+boo th
+benedic t
+tal on
+fc u
+year ofthe
+ray on
+raider nation
+fo yle
+ko val
+pi anos
+l pg
+bur mese
+man ure
+geo caching
+cosc ino
+b np
+fer ra
+stro phy
+mar ais
+ce es
+legen dof
+kat niss
+eno ch
+av ed
+you know
+d prk
+ðŁĺ¢ ðŁĺ¢
+sp un
+pro st
+sor rows
+cent red
+ke a
+gal icia
+? ð٤Ķ
+ÑĢод а
+bou chard
+ðŁĴĻ ðŁĴľ
+yu i
+seed lings
+jon ah
+reco vers
+ny rd
+board room
+su ma
+my japs
+tun g
+sha i
+ir gc
+eli o
+wag ons
+ka shi
+polic emen
+john nie
+ale coscino
+shop ify
+dot ted
+de tri
+va w
+to fficial
+in your
+chal mers
+trac ed
+no vi
+by es
+ari el
+nipp on
+la pel
+gri ez
+b gs
+fool ing
+d ita
+vijay sethu
+nm wx
+as ot
+kr anti
+hel m
+ve di
+sic kest
+mo chi
+k abo
+shru bs
+he red
+b sp
+sq m
+ham r
+dul kar
+anth a
+nr f
+avoid ance
+at en
+publi x
+be arers
+nas i
+ha p
+h ells
+ðŁĸ ¥
+ภ·
+thelast jedi
+oh wx
+ðŁį «
+wa hoo
+there se
+rec aps
+ss nhq
+bird photography
+v ay
+pet ti
+pau lo
+bel vedere
+( *
+gr l
+du vet
+c pec
+sa it
+por sch
+meas urable
+avi ators
+fre mantle
+bre en
+on om
+me and
+life saving
+eu ref
+en don
+embar as
+aira sia
+el is
+dun kin
+star magic
+s ill
+porto bello
+ki efer
+ex e
+mu ted
+ãģ ¦
+we thepeople
+logi a
+liber al
+theforce awakens
+min ed
+haun ts
+freck les
+care taker
+s india
+âķ IJ
+dev lin
+list on
+direction er
+oh n
+fi garo
+em manuel
+du bois
+cl ones
+bru ise
+ðŁİĪ ðŁİī
+disin fe
+der matology
+as r
+s watch
+dis comfort
+tam anna
+pi day
+mack en
+k atic
+delu sional
+shaw nee
+gu d
+al bino
+p ali
+din gh
+cucu mbers
+coffe y
+anticip ating
+treas ured
+web summit
+shel tered
+sav or
+pedago gy
+m gs
+sh ma
+s bu
+den ali
+cam pos
+bubble gum
+o ir
+le aps
+y ler
+r one
+sansk rit
+min t
+meat less
+futuri st
+du de
+a vel
+prote sted
+squ ire
+z aki
+sz n
+har court
+cycl one
+bour dain
+gather ings
+d ant
+advent urer
+parag on
+alt man
+dd ing
+ban erjee
+snorkel ing
+mother well
+mis sy
+en der
+glo ws
+ki wis
+chick pea
+por o
+e fron
+app t
+u y
+speci fied
+gab by
+e strada
+com bos
+bour bon
+vin i
+var un
+steph ani
+key words
+car vings
+amit abh
+wr ought
+tw al
+re els
+clu bbing
+ubi quit
+cri t
+ambed kar
+æ Ļ
+prun ing
+vaccin ated
+boe ing
+s ks
+lo ona
+hypno sis
+edel man
+pho l
+he w
+colo sse
+mckin sey
+u on
+to te
+sacrific ing
+ox i
+n ang
+e mu
+пÑĢи ÑĢода
+m th
+kers wednesday
+argu ed
+timel apse
+ris king
+regul ating
+ni gh
+likeli hood
+cu bic
+au ction
+rein for
+pi stor
+no ses
+ye l
+snu ggles
+pe i
+jean ette
+ta ku
+ri th
+guy z
+ภŀ
+y te
+ver ted
+pay soff
+jau regui
+hoo ligans
+procedu ral
+mi b
+har dy
+el eng
+chec kers
+all ine
+the met
+prou dof
+keerth yofficial
+collabor ator
+ni u
+infl icted
+adv ani
+re twee
+memor iam
+f icial
+ti ghter
+sal em
+re viewers
+br ics
+ben digo
+am ell
+tur kish
+sush maswar
+paul son
+pal awan
+mol lie
+stitch er
+s burgh
+ir u
+hay dn
+en ers
+aro a
+u zzi
+saraj evo
+hel a
+apol lo
+nine ty
+vac a
+sp on
+vent u
+jel ena
+hei fer
+avo ids
+sp ine
+pri ze
+mar ist
+re creating
+me de
+woo den
+find lay
+ro fl
+n di
+compreh end
+yu go
+y ü
+to work
+u fos
+son ar
+pi ston
+recor ding
+tent ative
+art forsale
+pel lets
+fre do
+ÙĪ Ø±
+mu ses
+custom ization
+pro found
+is ner
+ide ally
+si am
+plan kton
+cm dr
+man ger
+fran ken
+customiz able
+ठ®
+walk away
+swi vel
+vast ly
+no ton
+lex a
+ex moor
+z as
+tan te
+reduc tions
+lol ly
+hip sters
+benef ited
+ë ²
+ww www
+mascul ine
+fi ji
+dre y
+ph ill
+ane ous
+nic ol
+men dez
+disapp ro
+ch ner
+through s
+shen mue
+east man
+ðŁIJ İ
+yu ck
+under tale
+re ys
+go beavs
+eng en
+c na
+mer r
+bir k
+ãģ¨ç¹ĭãģ ĮãĤĬãģŁãģĦ
+âĥ£ @
+yn na
+ste ed
+offen der
+at um
+vani shing
+presi denti
+love them
+g nocchi
+fri ggin
+per il
+mad hya
+ag ne
+dee jay
+mar nock
+m tb
+fold able
+@ ___
+stand re
+bron x
+bow ski
+fin ite
+cro ckett
+b sf
+ge tit
+seren awilliams
+mir o
+ignati us
+sla y
+rin se
+fon due
+sel dom
+s more
+gan i
+dy ce
+dmit ry
+cru mb
+late post
+pri mark
+oh ana
+flor als
+do a
+remembrance day
+d ds
+azi one
+toon ami
+air port
+æĿ ±
+th ad
+fi st
+dine sh
+dr who
+ad words
+admi rer
+pro je
+kyrgy z
+à «
+manife station
+le wan
+j ic
+thi bau
+le ased
+van ity
+nouri shed
+never theless
+aug mente
+fu elled
+che ad
+wil shere
+ru di
+p z
+my co
+mor ro
+herbali fe
+hardro ck
+de man
+dre ality
+sp ades
+ce vic
+bha i
+bar on
+ultimat efan
+hou news
+to bi
+stru t
+ke el
+affili ation
+the masters
+sm al
+hu e
+este ban
+con v
+om nic
+datab ases
+co v
+ter ti
+st g
+snoop dogg
+metab ol
+leth bridge
+ðŁı» âĢįâĻĢï¸ı
+year ling
+residente vil
+nws l
+iy aki
+griez mann
+c ous
+ðŁĵĿ :
+tor ian
+sam i
+ðŁĶ¥ðŁĶ¥ ðŁĶ¥ðŁĶ¥ðŁĶ¥
+g are
+alli ances
+whit field
+we ther
+refin ing
+coy i
+kra ken
+ðŁĺĺ âĿ¤
+singul arity
+lil i
+h ns
+bol dand
+waw rinka
+misogy ny
+lo vers
+c q
+b dg
+ad ona
+gar ter
+women of
+sc d
+recogn ising
+mun a
+str ou
+sign alling
+lare do
+hell boy
+alek sand
+un available
+pedi atric
+as in
+mer ia
+ri shi
+futuri sm
+w ye
+polari zed
+e we
+pro pel
+in forms
+cre ase
+~ "
+arti ston
+like for
+heidel berg
+er ra
+life in
+len ny
+inter rupt
+cohe rent
+ca z
+vick ers
+le veled
+f bs
+cab ins
+bu mmed
+apost les
+we h
+ten don
+souven irs
+infu ri
+pier ce
+asse t
+m las
+go th
+di ggin
+ann as
+yl or
+th waite
+sw el
+pan era
+mur derers
+croo ked
+bs go
+ac u
+a on
+re an
+one of
+ko hl
+bloo dh
+pest icide
+lost dog
+fle xing
+ëĤ ĺ
+su pra
+eter nally
+ðŁļ Ļ
+pa olo
+ol an
+mom o
+is elle
+captain marvel
+s lou
+mistak enly
+akhi lesh
+mer t
+il inan
+bu on
+bal kan
+mir ro
+mill en
+der ail
+dam on
+tit i
+bi os
+re don
+pic ard
+par te
+ðŁ¤ Ł
+Ø º
+son ics
+fir sth
+dd c
+veg ans
+tur ban
+ni gan
+lot tie
+lyn don
+star buck
+pink floyd
+life styles
+am ara
+a she
+r sc
+val a
+sm er
+cw gc
+cli ent
+buen as
+jag an
+coo ps
+ðŁijij ðŁijij
+speci alizes
+snag ged
+g lar
+ben net
+wildlife wednesday
+bow den
+pi k
+art in
+empor ium
+ar l
+re ba
+pas ser
+disappo ints
+additi ve
+âľĬ ðŁı½
+bay er
+missou la
+ha skell
+comm ences
+ni x
+ne man
+explo ited
+plastic surgery
+cc d
+aso cial
+vo t
+sie gel
+fro ome
+kap am
+far a
+e ha
+pro bes
+mw f
+meet ing
+p bb
+ak ins
+mistle toe
+kingdom hearts
+for kids
+ec r
+bal e
+escor ts
+adidas originals
+k wa
+k ts
+hallo ffame
+ðŁĺį .
+wag s
+pot ted
+o wing
+honey comb
+he fty
+uro logy
+mer le
+b pd
+stri pping
+re ich
+k state
+gu ay
+yon ge
+shak ti
+g loom
+bat t
+son om
+n ery
+el ba
+blan ks
+hel le
+triple ts
+bom bay
+ak arta
+ab ia
+transm itted
+rol f
+ja is
+angular js
+fi erc
+m ss
+trac e
+ॠĩ
+tom bs
+old man
+kom bucha
+fo l
+e health
+cere als
+are lli
+in ari
+ðŁĴ ©
+wo l
+liber ties
+fa wn
+af firm
+nun avut
+hyster ical
+k drama
+art es
+âĢ¢âĢ¢âĢ¢âĢ¢ âĢ¢âĢ¢âĢ¢âĢ¢
+valent in
+man slaughter
+gal es
+eo in
+energi zed
+del s
+with draws
+st les
+sar castic
+ram esh
+incredi bles
+lock hart
+ya wn
+ultimatefan live
+oooooooo oooooooo
+mu en
+guru dev
+te er
+pe eling
+new snow
+lingui stics
+direc tv
+ag end
+uni lever
+ru ger
+han dedly
+ero se
+li mel
+the c
+royal ties
+fini shers
+nr g
+m gt
+fid get
+com ps
+bac on
+aggre ssively
+ab it
+ch â
+tar de
+slu gger
+q anda
+gre ening
+d ats
+ensla ved
+spec tor
+o ye
+fre ef
+b hand
+stop brexit
+mis conceptions
+cav a
+ðŁĺįðŁĺįðŁĺįðŁĺį ðŁĺįðŁĺįðŁĺįðŁĺį
+multit asking
+hou sel
+ferre ira
+cen time
+ank les
+jo dh
+hel ly
+fro me
+out tuesday
+nar nia
+bal aji
+l bloggers
+jyo ti
+ðŁį ĩ
+lan cia
+cap ri
+y ap
+nat ash
+down fall
+." âĢĶ
+Ã ®
+ligam ent
+coat ings
+ai ded
+hi ko
+fall ing
+encryp ted
+yeg food
+infringe ment
+cu di
+ce p
+ðŁĺį ðŁĺĤ
+tra d
+super rugby
+ed win
+wh iche
+vi meo
+lay ne
+in vigor
+he he
+dubrov nik
+bie ber
+u tr
+sham an
+op ers
+ham ill
+en ig
+di f
+ar um
+scrap book
+min h
+diver gence
+mckin non
+life time
+guter res
+wil le
+ple as
+patt y
+mic ron
+k z
+dom aine
+ru sher
+m ds
+ches ney
+screw driver
+âģ© ,
+sle dge
+hau er
+chan a
+stam ina
+sprink ler
+pl n
+he ff
+bol ton
+om on
+car rington
+accor dion
+jor ge
+inter ception
+in puts
+gu ll
+tran scription
+vanu atu
+it ical
+eth os
+tic h
+spac ey
+pee king
+u mi
+ha ger
+psycho tic
+illi an
+illi a
+bonnar oo
+an ese
+pu c
+laghate parth
+en hall
+econom ical
+dre dge
+% -
+u we
+tu bular
+scoun cil
+pe asants
+fl er
+tumb ler
+he p
+ford ham
+row ley
+initi als
+ev asion
+er nation
+plu gins
+coch ran
+c attle
+acid ity
+ðŁİĬ ðŁİī
+re grann
+jump man
+ef ace
+x ma
+patri archy
+esco bar
+cristi an
+tip ton
+nu eva
+hack ney
+back seat
+kill arney
+aid an
+sta dion
+simul taneous
+ida ho
+a je
+u th
+figu re
+clo s
+bur k
+volun tar
+rec ite
+macfar lane
+cur few
+bou do
+w gn
+sti x
+sla p
+scrat ched
+philli p
+jour ne
+ex pelled
+wa z
+u ke
+tati ana
+ou e
+ho pp
+dimit ri
+ðŁĵ £
+mato logist
+electri fying
+blu ffs
+bill smafia
+az cardinals
+y aa
+x mas
+shar a
+r ith
+g ills
+dre s
+bar ton
+authori zation
+imperi alism
+home of
+to do
+foot path
+band width
+visit spain
+moh sin
+erup ted
+mi ki
+insig nia
+mike l
+ss h
+ger a
+bank holiday
+aw an
+t weak
+star craft
+e al
+construc tion
+skelet ons
+le ep
+ine m
+bar clay
+ship wreck
+monsi eur
+yo h
+ron t
+form ative
+ser o
+le p
+horse man
+hoo sier
+haz mat
+cylin ders
+cen ti
+ðŁĴ¥ðŁĴ¥ ðŁĴ¥
+re em
+na ire
+mus ically
+gras shopper
+est onian
+termin ology
+ro main
+blogger rt
+tox in
+stan ce
+cultiv ated
+an ast
+ðŁIJ į
+shi mano
+go pher
+ene i
+recycla ble
+gam ification
+fight for
+c q
+avoc ados
+ke ys
+eli ke
+gly cer
+shak ur
+mobili zation
+gal ley
+expla in
+ex changed
+pe th
+obe dience
+illa ge
+en nis
+ãĥ ŀ
+wi v
+walla bies
+ma ar
+ig ers
+fin tech
+fin alized
+wo j
+meaning less
+in field
+onna ise
+e et
+bron te
+pass ages
+ðŁij §
+strick land
+northern lights
+lom ond
+h tc
+wr ay
+shi fter
+di alog
+ðŁį į
+>> >>>>
+te atime
+ste ch
+sic huan
+qu ill
+fran ca
+comple mentary
+bar rington
+marcu s
+mal am
+goo oo
+for sa
+elec tra
+af s
+âĹ Ĩ
+tri fe
+sn azzy
+fo lia
+and olan
+after dark
+wood son
+stra de
+litt lest
+o gun
+con wy
+co wards
+ðŁĺĤðŁĺĤðŁĺĤðŁĺĤ ðŁĺĤðŁĺĤðŁĺĤ
+íĬ ¸
+se ul
+mur phy
+dun ks
+kapil shar
+jo achim
+wom ack
+equal ity
+aver ages
+a ine
+ðŁ¦ Ī
+tac ular
+dis ability
+u ked
+mid century
+bar thol
+teas ers
+tab ern
+nj caa
+sp out
+op i
+ku bball
+bl om
+so ar
+popu lism
+meth yl
+ðŁijĬ ðŁı¼
+o spre
+alo ils
+ðŁĵ ĸ
+ðŁĮ ļ
+x er
+sp illing
+publ ica
+car dam
+adi sh
+sa cha
+p kg
+bu da
+lyric ist
+i bc
+gru mp
+ho ver
+hal ep
+anti body
+anem one
+âĻ¥âĻ¥ âĻ¥âĻ¥
+m cl
+litho graph
+cc u
+s fest
+path ic
+calli ster
+otta wa
+gun sn
+rut ger
+hali but
+en vision
+differenti ate
+ðŁļĢ ðŁļĢ
+pir an
+lat el
+uc n
+trou bad
+ra ine
+fierc ely
+learn english
+lea se
+wex mondays
+em it
+dray ton
+bur rell
+scuba diving
+hol ler
+dr u
+clo cked
+w ral
+ap ro
+trans lucent
+w bo
+patri arch
+mo ja
+lan nister
+fish ery
+ne derland
+mil dly
+mi rai
+ma ko
+ja p
+ðŁĺ©ðŁĺ© ðŁĺ©
+pro statec
+p anna
+ar ama
+under taking
+tomp kins
+ne op
+soli ds
+sav oury
+e ames
+cut lery
+wood bridge
+steam er
+ri zzo
+wild cat
+rat na
+lamin ated
+kin eni
+jal ap
+ai des
+acknowle dges
+?! ?!?!
+! ðŁİī
+w afc
+mag gio
+ha ves
+dar je
+of i
+gr il
+v asi
+bru x
+mo hd
+fake speare
+arn old
+r mb
+for be
+wal leye
+ro di
+therapeu tics
+strate gi
+ob ste
+mu dder
+download able
+dd ings
+d ca
+asi angames
+campe on
+appropri ation
+th century
+ram atta
+dra ped
+bul lion
+mu c
+one x
+se greg
+ophel ia
+bod ily
+âĿ¤ ðŁĺį
+wi zar
+te ased
+ade my
+to id
+sur a
+lazar us
+sn ickers
+ma se
+lo h
+bow ed
+bibli o
+x change
+har lan
+gho shal
+flavor ful
+bha gat
+alle z
+whiche ver
+ten stein
+disc er
+organ iser
+mt g
+dream liner
+t se
+hok kaido
+mo k
+indulg ent
+hick man
+blin ded
+al yn
+aaa ah
+sp ool
+lough borough
+inter pret
+et v
+aristo tle
+optimi zing
+avici i
+madu rai
+ju li
+naw az
+mat chups
+ab ide
+paint ing
+w elling
+vel i
+octag on
+in scribed
+po king
+plac er
+life cycle
+kili g
+g sp
+eli ves
+cle ments
+na sheed
+me sut
+incarcer ated
+dist illed
+wal ang
+delic acy
+del gado
+che z
+ch ita
+ad ero
+tu x
+pati l
+o do
+abh cosmetics
+tv c
+p bc
+in accurate
+hardwork paysoff
+ball er
+quot ation
+merchandi sing
+ga stri
+defen ses
+dro gba
+bex hill
+ban kno
+win ona
+si eg
+p gs
+hahah ha
+agu chi
+su bram
+mirac le
+de sch
+li bre
+ba cher
+ent ine
+bbcra di
+lou dest
+r ps
+pi erc
+fr yer
+storm trooper
+rafael nadal
+pas co
+exhau stion
+epic onetsy
+rc tid
+kel lie
+ga ines
+d bz
+sm riti
+s bridge
+lim ited
+cla w
+technic al
+bio graphical
+ado red
+ภ°
+exclu de
+ac adia
+key boards
+fur man
+so ca
+sur u
+ni ps
+sw aps
+server less
+run e
+pu ffy
+north ampton
+nish ings
+hen der
+cartri dges
+gun shot
+ðŁĵ ¹
+fil ament
+respon dents
+pey ton
+mountaine er
+mer ging
+life span
+intimid ation
+p afc
+nl wx
+expan sive
+pur r
+f ck
+ca e
+at ti
+tele thon
+so hn
+mend el
+lo pes
+dor i
+un broken
+te red
+tast ings
+in active
+disin tegr
+t assel
+share the
+pi ano
+is lay
+air space
+z awa
+ricci ardo
+ming ton
+fresh er
+cur ry
+re vs
+pharo ah
+h mv
+exhilar ating
+wh oo
+lin kin
+kri spy
+competen cy
+ste wards
+ne bu
+kat su
+ad mins
+baz ar
+as ar
+giving back
+s summit
+song z
+lin us
+raj kumar
+farm ington
+fanta sia
+ðŁĺ´ ðŁĺ´
+so bri
+lis se
+barry more
+pri sm
+blo b
+sen ew
+mono xide
+exp ire
+eigh teen
+di pper
+xi ao
+kil t
+hin ch
+bbc sport
+bam boo
+p ter
+ex al
+ðŁ¦ ĭ
+ham lin
+expe ditions
+star gazing
+food security
+wy lie
+ul f
+st ingly
+on storm
+lo eb
+bro ome
+bn ha
+pancre atic
+eli ve
+!!!!!!!! !!!
+ther apper
+ortho pedic
+avengers endgame
+antit rust
+ìļ °
+go te
+om d
+off side
+gy llen
+win eries
+white water
+ad l
+lu pita
+exce eds
+consi sted
+chew bacca
+ash leigh
+nhl jets
+is san
+sh ld
+hay at
+cran berries
+ð٤ĺ ðŁı½
+rock the
+spring training
+fall out
+dairy free
+wa j
+un decided
+so wn
+rc n
+north wales
+htt r
+fu mble
+d its
+comp elled
+popu list
+min ted
+blan chett
+. ''
+pro pulsion
+m illa
+au berg
+her tz
+h ta
+u daipur
+serendip ity
+azte cs
+als ace
+ðŁIJ ij
+lu n
+sho es
+char li
+gar za
+ðŁĴ Ł
+pro biotics
+fox tv
+ol is
+mi ff
+loc alized
+diffu ser
+si gue
+fun ko
+rend ous
+ðŁĴ ij
+jeky ll
diff --git a/ComfyUI/comfy/sd1_tokenizer/special_tokens_map.json b/ComfyUI/comfy/sd1_tokenizer/special_tokens_map.json
new file mode 100644
index 0000000000000000000000000000000000000000..2c2130b544c0c5a72d5d00da071ba130a9800fb2
--- /dev/null
+++ b/ComfyUI/comfy/sd1_tokenizer/special_tokens_map.json
@@ -0,0 +1,24 @@
+{
+ "bos_token": {
+ "content": "<|startoftext|>",
+ "lstrip": false,
+ "normalized": true,
+ "rstrip": false,
+ "single_word": false
+ },
+ "eos_token": {
+ "content": "<|endoftext|>",
+ "lstrip": false,
+ "normalized": true,
+ "rstrip": false,
+ "single_word": false
+ },
+ "pad_token": "<|endoftext|>",
+ "unk_token": {
+ "content": "<|endoftext|>",
+ "lstrip": false,
+ "normalized": true,
+ "rstrip": false,
+ "single_word": false
+ }
+}
diff --git a/ComfyUI/comfy/sd1_tokenizer/tokenizer_config.json b/ComfyUI/comfy/sd1_tokenizer/tokenizer_config.json
new file mode 100644
index 0000000000000000000000000000000000000000..8f7b3151d008bdee5739e317b887be0fc3b805c3
--- /dev/null
+++ b/ComfyUI/comfy/sd1_tokenizer/tokenizer_config.json
@@ -0,0 +1,34 @@
+{
+ "add_prefix_space": false,
+ "bos_token": {
+ "__type": "AddedToken",
+ "content": "<|startoftext|>",
+ "lstrip": false,
+ "normalized": true,
+ "rstrip": false,
+ "single_word": false
+ },
+ "do_lower_case": true,
+ "eos_token": {
+ "__type": "AddedToken",
+ "content": "<|endoftext|>",
+ "lstrip": false,
+ "normalized": true,
+ "rstrip": false,
+ "single_word": false
+ },
+ "errors": "replace",
+ "model_max_length": 8192,
+ "name_or_path": "openai/clip-vit-large-patch14",
+ "pad_token": "<|endoftext|>",
+ "special_tokens_map_file": "./special_tokens_map.json",
+ "tokenizer_class": "CLIPTokenizer",
+ "unk_token": {
+ "__type": "AddedToken",
+ "content": "<|endoftext|>",
+ "lstrip": false,
+ "normalized": true,
+ "rstrip": false,
+ "single_word": false
+ }
+}
diff --git a/ComfyUI/comfy/sd1_tokenizer/vocab.json b/ComfyUI/comfy/sd1_tokenizer/vocab.json
new file mode 100644
index 0000000000000000000000000000000000000000..469be27c5c010538f845f518c4f5e8574c78f7c8
--- /dev/null
+++ b/ComfyUI/comfy/sd1_tokenizer/vocab.json
@@ -0,0 +1,49410 @@
+{
+ "!": 0,
+ "!!": 1443,
+ "!!!": 11194,
+ "!!!!": 4003,
+ "!!!!!!!!": 11281,
+ "!!!!!!!!!!!!!!!!": 30146,
+ "!!!!!!!!!!!": 49339,
+ "!!!!!!!!!!": 35579,
+ "!!!!!!!!!": 28560,
+ "!!!!!!!!": 21622,
+ "!!!!!!!": 15203,
+ "!!!!!!": 9168,
+ "!!!!!": 5203,
+ "!!!!": 2360,
+ "!!!\"": 28048,
+ "!!!)": 42532,
+ "!!!": 995,
+ "!!\"": 20556,
+ "!!#": 34997,
+ "!!)": 28352,
+ "!!": 748,
+ "!!@": 40705,
+ "!\"": 2947,
+ "!\"@": 43819,
+ "!#": 9670,
+ "!'": 13222,
+ "!),": 37904,
+ "!).": 26225,
+ "!)": 4571,
+ "!*": 37737,
+ "!,": 29325,
+ "!-": 43499,
+ "!...": 22121,
+ "!..": 35475,
+ "!.": 22517,
+ "!:)": 31671,
+ "!:": 17545,
+ "!": 256,
+ "!?!": 29767,
+ "!?!?": 47081,
+ "!?": 6004,
+ "!@": 15117,
+ "!]": 34466,
+ "!â̦": 35068,
+ "!âĿ¤ï¸ı": 32559,
+ "!ðŁİī": 49085,
+ "!ðŁĺĬ": 43434,
+ "!ðŁĺį": 36438,
+ "\"": 1,
+ "\"!": 10377,
+ "\"\"": 41530,
+ "\"\"\"": 25539,
+ "\"\"": 8575,
+ "\"#": 8345,
+ "\"'": 31065,
+ "\"(": 32741,
+ "\")": 13112,
+ "\",": 4332,
+ "\"-": 9375,
+ "\"....": 37785,
+ "\"...": 9049,
+ "\"..": 25403,
+ "\".": 2811,
+ "\"/": 39486,
+ "\":": 7811,
+ "\";": 37549,
+ "\"": 257,
+ "\"?": 11727,
+ "\"@": 1512,
+ "\"@_": 20236,
+ "\"[": 36930,
+ "\"â̦": 33993,
+ "\"âĢĶ": 41151,
+ "#": 2,
+ "##": 15483,
+ "#...": 31491,
+ "#:": 30144,
+ "#": 258,
+ "#@": 35062,
+ "#â̦": 12834,
+ "#âĢİ": 34262,
+ "$": 3,
+ "$$": 24233,
+ "$$$": 31859,
+ "$$": 14929,
+ "$)": 39460,
+ "$.": 34682,
+ "$": 259,
+ "%": 4,
+ "%!": 35070,
+ "%),": 37819,
+ "%)": 16063,
+ "%,": 14505,
+ "%-": 48784,
+ "%.": 12475,
+ "%;": 33379,
+ "%": 260,
+ "&": 5,
+ "&&": 27791,
+ "&": 261,
+ "'": 6,
+ "'!": 13781,
+ "'\"": 19479,
+ "'#": 15319,
+ "''": 46594,
+ "''": 8445,
+ "')": 19175,
+ "',": 5662,
+ "'-": 26152,
+ "'...": 20474,
+ "'.": 4645,
+ "':": 7182,
+ "';": 44517,
+ "'": 262,
+ "'?": 17242,
+ "'@": 26397,
+ "'d": 1896,
+ "'ll": 1342,
+ "'m": 880,
+ "'re": 982,
+ "'s": 568,
+ "'t": 713,
+ "'ve": 1200,
+ "'â̦": 42120,
+ "(": 7,
+ "(!)": 30253,
+ "(\"": 18741,
+ "(#": 6229,
+ "($)": 46597,
+ "($": 15186,
+ "(&": 15042,
+ "('": 18235,
+ "((": 22944,
+ "(((": 33287,
+ "((": 13796,
+ "().": 41737,
+ "()": 8475,
+ "(*": 48004,
+ "(*": 39575,
+ "(+": 12903,
+ "(-": 20228,
+ "(...": 45159,
+ "(.": 43055,
+ "(:": 8528,
+ "(;": 23983,
+ "(": 263,
+ "(?)": 22885,
+ "(@": 2181,
+ "(£": 33987,
+ "(©": 44886,
+ "(ðŁĵ·:": 34610,
+ "(ðŁĵ·": 37999,
+ "(ðŁĵ¸:": 44422,
+ "(ðŁĵ¸": 45204,
+ ")": 8,
+ ")!!": 47518,
+ ")!": 7805,
+ ")\"": 13046,
+ ")#": 39981,
+ ")'": 23613,
+ ")(": 27956,
+ "))": 13720,
+ "))))": 42911,
+ "))))": 34181,
+ ")))": 18305,
+ "))": 5167,
+ "),": 2361,
+ ")-": 19034,
+ ")...": 15274,
+ ")..": 41822,
+ ").": 1818,
+ ")/": 26616,
+ "):": 4143,
+ ");": 19686,
+ ")": 264,
+ ")?": 18765,
+ ")@": 41928,
+ ")_/": 45028,
+ ")_/¯": 45781,
+ ")â̦": 41844,
+ "*": 9,
+ "*)": 30956,
+ "**": 9825,
+ "****": 21326,
+ "********": 42974,
+ "*****": 43571,
+ "****": 25167,
+ "***": 7829,
+ "**": 4441,
+ "*,": 41895,
+ "*-*": 23568,
+ "*.": 31304,
+ "*": 265,
+ "*_*": 44535,
+ "+": 10,
+ "+)": 34810,
+ "++": 47298,
+ "+++": 35986,
+ "++": 19056,
+ "+,": 35885,
+ "+.": 25238,
+ "+/-": 47614,
+ "+": 266,
+ ",": 11,
+ ",\"": 3823,
+ ",#": 11215,
+ ",&": 26905,
+ ",'": 10599,
+ ",)": 44493,
+ ",,": 21340,
+ ",,,,": 33225,
+ ",,,": 14811,
+ ",,": 8844,
+ ",-": 29821,
+ ",...": 20365,
+ ",.": 41277,
+ ",": 267,
+ ",@": 13975,
+ ",â̦": 14601,
+ "-": 12,
+ "-\"": 18646,
+ "-#": 10151,
+ "-$": 24946,
+ "-'": 28010,
+ "-(": 33345,
+ "-)": 3535,
+ "-*": 21527,
+ "--": 2154,
+ "----": 5753,
+ "--------": 11772,
+ "----------------": 23122,
+ "----": 30164,
+ "---->": 35999,
+ "---": 11079,
+ "--->": 14518,
+ "--": 2432,
+ "-->": 6422,
+ "-->>": 47252,
+ "-.-": 32765,
+ "-...": 43147,
+ "-.": 44040,
+ "-": 268,
+ "->": 5081,
+ "-@": 10087,
+ "-_-": 27227,
+ "-__": 42718,
+ "-â̦": 30047,
+ ".": 13,
+ ".!!": 37805,
+ ".!": 14030,
+ ".\"": 18650,
+ ".\"-": 21234,
+ ".\"": 1081,
+ ".\"âĢĶ": 48703,
+ ".#": 5014,
+ ".'\"": 41558,
+ ".''": 49379,
+ ".'": 5938,
+ ".(": 22294,
+ ".)": 5376,
+ ".*": 26145,
+ ".,": 5276,
+ ".-": 12481,
+ "..": 608,
+ "..!!": 23707,
+ "..!": 17994,
+ "..\"": 15229,
+ "..#": 15735,
+ "..,": 47143,
+ "...": 3002,
+ "...!!!": 38351,
+ "...!!": 39915,
+ "...!": 16860,
+ "...\"": 5240,
+ "...#": 8195,
+ "...&": 44979,
+ "...'": 23167,
+ "...(": 37981,
+ "...)": 14040,
+ "...,": 42717,
+ "....": 2386,
+ "....\"": 26689,
+ "....#": 20346,
+ ".....": 34151,
+ ".....#": 38867,
+ "........": 8246,
+ "................": 24855,
+ "............": 42965,
+ "...........": 35008,
+ "..........": 25526,
+ ".........": 19881,
+ "........": 14720,
+ ".......": 9917,
+ "......": 5590,
+ ".....": 3104,
+ "....": 1390,
+ "....@": 29790,
+ "...:": 34570,
+ "...": 678,
+ "...?": 16388,
+ "...@": 12672,
+ "..": 852,
+ "..?": 23875,
+ "..@": 21124,
+ "./": 31975,
+ ".:": 15811,
+ ".;": 47596,
+ ".": 269,
+ ".<": 29442,
+ ".?": 29294,
+ ".@": 1230,
+ ".]": 33511,
+ ".~": 42651,
+ ".â̦": 18047,
+ ".âĿ¤ï¸ı": 39085,
+ ".âłĢ": 30097,
+ ".ðŁĺĤ": 46580,
+ "/": 14,
+ "/#": 13217,
+ "/$": 36266,
+ "/-": 19811,
+ "/.": 39382,
+ "//": 15348,
+ "////": 46271,
+ "///": 22734,
+ "//": 3502,
+ "/": 270,
+ "/@": 8216,
+ "0": 15,
+ "0": 271,
+ "1": 16,
+ "1": 272,
+ "2": 17,
+ "2": 273,
+ "3": 18,
+ "3": 274,
+ "4": 19,
+ "4": 275,
+ "5": 20,
+ "5": 276,
+ "6": 21,
+ "6": 277,
+ "7": 22,
+ "7": 278,
+ "8": 23,
+ "8": 279,
+ "9": 24,
+ "9": 280,
+ ":": 25,
+ ":\"": 29498,
+ ":\")": 46432,
+ ":\"": 12089,
+ ":#": 26625,
+ ":$": 33769,
+ ":'": 8017,
+ ":'(": 21250,
+ ":')": 10701,
+ ":'": 23851,
+ ":((": 42496,
+ ":(": 5965,
+ ":)": 11070,
+ ":))))": 42339,
+ ":)))": 21840,
+ ":))": 10164,
+ ":).": 39010,
+ ":)": 1408,
+ ":*": 12617,
+ ":-": 13021,
+ ":-(": 25137,
+ ":-)": 4223,
+ ":-": 10323,
+ ":...": 42140,
+ "://": 12441,
+ ":/": 13604,
+ "::": 33077,
+ ":::": 43818,
+ "::": 9788,
+ ":": 281,
+ ":>": 39677,
+ ":@": 14339,
+ ":]": 43486,
+ ":|": 45986,
+ ":â̦": 22365,
+ ";": 26,
+ ";))": 41873,
+ ";)": 3661,
+ ";-": 35657,
+ ";-)": 10475,
+ ";;": 34824,
+ ";;": 24492,
+ ";": 282,
+ "<": 27,
+ "<-": 47280,
+ "": 34308,
+ "<<": 24588,
+ "<": 283,
+ "<<": 16482,
+ "<<<": 35054,
+ "<|endoftext|>": 49407,
+ "<|startoftext|>": 49406,
+ "=": 28,
+ "=))": 39587,
+ "=)": 17840,
+ "=": 284,
+ "==": 11748,
+ "====": 21734,
+ "========": 38952,
+ "==>": 29688,
+ "=>": 9714,
+ ">": 29,
+ ">.<": 38507,
+ ">:": 36196,
+ ">": 285,
+ "><": 28015,
+ ">>": 8270,
+ ">>": 2988,
+ ">>>": 6395,
+ ">>>>": 18461,
+ ">>>>": 18435,
+ ">>>>>": 32972,
+ ">>>>>>": 48947,
+ ">>>>>>>>": 41947,
+ ">_": 44144,
+ "?": 30,
+ "?!": 9785,
+ "?!!": 25342,
+ "?!\"": 29315,
+ "?!": 2835,
+ "?!?!": 16349,
+ "?!?!?!": 49084,
+ "?!?!?": 37619,
+ "?!?": 11395,
+ "?\"": 3283,
+ "?#": 24018,
+ "?'": 13610,
+ "?)": 9626,
+ "?,": 41628,
+ "?...": 22641,
+ "?..": 43905,
+ "?.": 41251,
+ "?:": 21067,
+ "?": 286,
+ "??": 5195,
+ "??!!": 43219,
+ "??!": 37341,
+ "??\"": 44996,
+ "??": 2197,
+ "???": 40017,
+ "???": 3824,
+ "????": 15936,
+ "????": 10362,
+ "?????": 21370,
+ "??????": 34589,
+ "????????": 45091,
+ "?@": 29258,
+ "?ð٤Ķ": 47928,
+ "@": 31,
+ "@#": 39397,
+ "@.": 43730,
+ "@/": 28639,
+ "@": 287,
+ "@@": 30314,
+ "@_": 2692,
+ "@__": 17042,
+ "@___": 48308,
+ "A": 32,
+ "A": 288,
+ "B": 33,
+ "B": 289,
+ "C": 34,
+ "C": 290,
+ "D": 35,
+ "D": 291,
+ "E": 36,
+ "E": 292,
+ "F": 37,
+ "F": 293,
+ "G": 38,
+ "G": 294,
+ "H": 39,
+ "H": 295,
+ "I": 40,
+ "I": 296,
+ "J": 41,
+ "J": 297,
+ "K": 42,
+ "K": 298,
+ "L": 43,
+ "L": 299,
+ "M": 44,
+ "M": 300,
+ "N": 45,
+ "N": 301,
+ "O": 46,
+ "O": 302,
+ "P": 47,
+ "P": 303,
+ "Q": 48,
+ "Q": 304,
+ "R": 49,
+ "R": 305,
+ "S": 50,
+ "S": 306,
+ "T": 51,
+ "T": 307,
+ "U": 52,
+ "U": 308,
+ "V": 53,
+ "V": 309,
+ "W": 54,
+ "W": 310,
+ "X": 55,
+ "X": 311,
+ "Y": 56,
+ "Y": 312,
+ "Z": 57,
+ "Z": 313,
+ "[": 58,
+ "[#": 11115,
+ "[...": 39975,
+ "[...]": 43790,
+ "[": 314,
+ "[@": 15148,
+ "[]": 22240,
+ "\\": 59,
+ "\\'": 41239,
+ "\\": 315,
+ "]": 60,
+ "]\"": 39434,
+ "],": 34067,
+ "].": 26262,
+ "]:": 21641,
+ "]": 316,
+ "][#": 39009,
+ "][": 29329,
+ "^": 61,
+ "^)": 30720,
+ "^-": 43516,
+ "^.": 31552,
+ "^.^": 35791,
+ "^": 317,
+ "^^": 34454,
+ "^^": 9064,
+ "^_": 14423,
+ "^_^": 15995,
+ "_": 62,
+ "_'": 44701,
+ "_(": 36951,
+ "_)": 37393,
+ "_*": 36237,
+ "_,": 31417,
+ "_-": 23193,
+ "_.": 26841,
+ "_/": 37647,
+ "_:": 13109,
+ "_": 318,
+ "__": 2355,
+ "__:": 47043,
+ "__": 3838,
+ "___": 43812,
+ "___": 13530,
+ "____": 4727,
+ "____": 25350,
+ "_____": 38803,
+ "________": 9549,
+ "________________": 20115,
+ "`": 63,
+ "`": 319,
+ "a": 64,
+ "a": 320,
+ "aa": 1821,
+ "aa": 3894,
+ "aaa": 14376,
+ "aaa": 9583,
+ "aaaa": 6727,
+ "aaaa": 19336,
+ "aaaaa": 31095,
+ "aaaaaa": 44413,
+ "aaaaaaaa": 23126,
+ "aaaah": 49151,
+ "aaah": 35856,
+ "aaay": 37846,
+ "aab": 34108,
+ "aac": 23251,
+ "aac": 11346,
+ "aad": 20464,
+ "aad": 35894,
+ "aaf": 37638,
+ "aaf": 31534,
+ "aag": 42174,
+ "aah": 28990,
+ "aaj": 28727,
+ "aaj": 43411,
+ "aak": 37739,
+ "aal": 22268,
+ "aal": 30208,
+ "aali": 27896,
+ "aaliyah": 46577,
+ "aam": 12943,
+ "aam": 22775,
+ "aama": 45018,
+ "aamaadmi": 45563,
+ "aamaadmiparty": 46406,
+ "aamir": 27456,
+ "aan": 20705,
+ "aan": 13426,
+ "aand": 38054,
+ "aap": 12023,
+ "aap": 12052,
+ "aapl": 34516,
+ "aar": 4695,
+ "aar": 13234,
+ "aard": 46932,
+ "aaron": 13948,
+ "aaron": 7709,
+ "aas": 28542,
+ "aas": 32205,
+ "aat": 34018,
+ "aat": 35004,
+ "aau": 35426,
+ "aay": 38281,
+ "aay": 40249,
+ "aaz": 26770,
+ "ab": 596,
+ "ab": 3937,
+ "aba": 44204,
+ "aba": 11102,
+ "abad": 33444,
+ "abad": 7155,
+ "aban": 41662,
+ "aband": 8595,
+ "abandon": 28805,
+ "abandoned": 11227,
+ "abar": 17860,
+ "abar": 39805,
+ "abas": 25402,
+ "abay": 43542,
+ "abb": 38954,
+ "abb": 38297,
+ "abba": 30870,
+ "abbas": 37494,
+ "abbas": 24412,
+ "abbey": 31927,
+ "abbey": 10132,
+ "abbie": 39949,
+ "abbo": 13536,
+ "abbot": 44046,
+ "abbott": 43737,
+ "abbott": 15649,
+ "abbrevi": 44843,
+ "abby": 30586,
+ "abby": 14694,
+ "abc": 13137,
+ "abc": 5334,
+ "abcnews": 31566,
+ "abd": 44093,
+ "abdel": 46511,
+ "abdomin": 35335,
+ "abdominal": 39328,
+ "abdu": 13361,
+ "abduc": 17884,
+ "abducted": 31520,
+ "abduction": 36984,
+ "abdul": 14227,
+ "abdul": 15593,
+ "abdullah": 21317,
+ "abe": 15856,
+ "abe": 12734,
+ "abee": 36037,
+ "abel": 31938,
+ "abel": 25318,
+ "abella": 46156,
+ "aben": 40865,
+ "aber": 7828,
+ "aber": 41867,
+ "aberdeen": 30539,
+ "aberdeen": 17236,
+ "abh": 27484,
+ "abh": 33649,
+ "abhcosmetics": 49189,
+ "abhi": 18113,
+ "abhin": 44045,
+ "abhishek": 44502,
+ "abi": 16867,
+ "abi": 14161,
+ "abia": 48604,
+ "abide": 49163,
+ "abig": 20863,
+ "abigail": 25686,
+ "abil": 21135,
+ "abilities": 8724,
+ "ability": 35146,
+ "ability": 3024,
+ "abit": 48668,
+ "ablanc": 33716,
+ "able": 10102,
+ "able": 863,
+ "abled": 10655,
+ "ableg": 24055,
+ "ables": 8486,
+ "ableton": 47169,
+ "ably": 6748,
+ "abnormal": 40934,
+ "abo": 2889,
+ "abo": 21861,
+ "aboard": 11661,
+ "abol": 31768,
+ "abolic": 46827,
+ "abolish": 47403,
+ "aboo": 42433,
+ "abor": 8416,
+ "aboriginal": 20422,
+ "abortion": 12336,
+ "abortions": 43218,
+ "aboss": 46401,
+ "abou": 36455,
+ "abou": 44053,
+ "abound": 41037,
+ "abour": 46637,
+ "about": 20204,
+ "about": 781,
+ "abouts": 36339,
+ "above": 35019,
+ "above": 4348,
+ "aboy": 37077,
+ "abpoli": 44779,
+ "abq": 38767,
+ "abr": 44932,
+ "abra": 10694,
+ "abra": 35087,
+ "abraham": 40623,
+ "abraham": 15869,
+ "abram": 33255,
+ "abrams": 29852,
+ "abre": 22472,
+ "abre": 46756,
+ "abri": 28605,
+ "abridged": 45333,
+ "abroad": 11253,
+ "abru": 46295,
+ "abs": 18431,
+ "abs": 11109,
+ "absc": 25389,
+ "abscbn": 44260,
+ "abscbn": 45810,
+ "absen": 32453,
+ "absence": 19240,
+ "absent": 30363,
+ "absol": 4624,
+ "absolu": 7055,
+ "absolut": 4666,
+ "absolute": 7501,
+ "absolutely": 4703,
+ "absor": 14303,
+ "absorb": 35806,
+ "absorbed": 45059,
+ "absorbing": 46412,
+ "absorption": 42210,
+ "abstr": 7530,
+ "abstract": 23885,
+ "abstract": 10197,
+ "abstractart": 31170,
+ "abstraction": 47696,
+ "abstracts": 40065,
+ "absur": 21639,
+ "absurd": 29757,
+ "abt": 9850,
+ "abu": 9167,
+ "abu": 11787,
+ "abud": 20180,
+ "abudha": 21450,
+ "abudhabi": 25256,
+ "abuja": 23371,
+ "abun": 20544,
+ "abundance": 23236,
+ "abundant": 31611,
+ "abur": 23377,
+ "aburger": 46660,
+ "abuse": 7678,
+ "abused": 23855,
+ "abuses": 37132,
+ "abusing": 36558,
+ "abusive": 26858,
+ "abv": 34172,
+ "aby": 16342,
+ "aby": 31378,
+ "abyss": 33632,
+ "abz": 42292,
+ "ac": 546,
+ "ac": 2816,
+ "aca": 9213,
+ "acab": 41388,
+ "acacia": 44047,
+ "acad": 32537,
+ "acade": 2892,
+ "academia": 22662,
+ "academic": 31178,
+ "academic": 7935,
+ "academics": 26417,
+ "academies": 42569,
+ "academy": 29968,
+ "academy": 4041,
+ "acadi": 41455,
+ "acadia": 49236,
+ "acam": 26172,
+ "acan": 42227,
+ "acan": 26318,
+ "acap": 32357,
+ "acar": 22232,
+ "acare": 16961,
+ "acc": 26805,
+ "acc": 9318,
+ "acca": 30883,
+ "acce": 8564,
+ "acceler": 10161,
+ "accelerate": 23619,
+ "accelerated": 38513,
+ "accelerating": 41821,
+ "acceleration": 39387,
+ "accelerator": 25261,
+ "accent": 28110,
+ "accent": 18931,
+ "accents": 31738,
+ "accenture": 41853,
+ "accep": 4616,
+ "accept": 16447,
+ "accept": 9338,
+ "acceptable": 14209,
+ "acceptance": 17090,
+ "accepted": 9159,
+ "accepting": 12855,
+ "accepts": 22338,
+ "access": 7596,
+ "access": 3822,
+ "accessi": 10787,
+ "accessibility": 23407,
+ "accessible": 13977,
+ "accessing": 46339,
+ "accessories": 10220,
+ "accessory": 20417,
+ "acci": 4263,
+ "acci": 33943,
+ "accident": 6608,
+ "accidental": 24895,
+ "accidentally": 11061,
+ "accidents": 22072,
+ "acclaimed": 21172,
+ "acco": 44730,
+ "accol": 33858,
+ "accolades": 46731,
+ "accom": 23658,
+ "accommo": 34495,
+ "accommod": 14386,
+ "accommodate": 34708,
+ "accommodation": 18066,
+ "accommodations": 45536,
+ "accomp": 24985,
+ "accompan": 14746,
+ "accompanied": 20715,
+ "accompany": 34142,
+ "accompanying": 38179,
+ "accompli": 10205,
+ "accomplish": 25542,
+ "accomplished": 16462,
+ "accomplishment": 26100,
+ "accomplishments": 24965,
+ "accor": 4182,
+ "accord": 34293,
+ "accord": 28513,
+ "according": 4717,
+ "accordingly": 35535,
+ "accordion": 48760,
+ "accoun": 3081,
+ "account": 18424,
+ "account": 4684,
+ "accountability": 19377,
+ "accountable": 24216,
+ "accountant": 31026,
+ "accountants": 37222,
+ "accounted": 43951,
+ "accounting": 14805,
+ "accounts": 9974,
+ "accra": 31900,
+ "accred": 17451,
+ "accreditation": 27015,
+ "accredited": 27647,
+ "acct": 45569,
+ "accu": 5618,
+ "accumul": 19275,
+ "accumulation": 37112,
+ "accur": 6551,
+ "accuracy": 18423,
+ "accurate": 8858,
+ "accurately": 24206,
+ "accusations": 33615,
+ "accuse": 39414,
+ "accused": 9434,
+ "accuses": 27496,
+ "accusing": 41474,
+ "acdc": 45067,
+ "ace": 2675,
+ "ace": 804,
+ "acea": 35219,
+ "aceae": 38153,
+ "acele": 40868,
+ "aceous": 33610,
+ "acer": 37990,
+ "acer": 25809,
+ "aces": 5725,
+ "acet": 28735,
+ "acf": 38389,
+ "ach": 972,
+ "ach": 987,
+ "acha": 22686,
+ "acharya": 45780,
+ "achat": 32706,
+ "ache": 27771,
+ "ache": 7214,
+ "ached": 17048,
+ "acher": 38442,
+ "acher": 17936,
+ "achers": 25051,
+ "aches": 14823,
+ "achi": 3264,
+ "achi": 9087,
+ "achiev": 8160,
+ "achieve": 14798,
+ "achieve": 8175,
+ "achieved": 12359,
+ "achievement": 8245,
+ "achievements": 16114,
+ "achiever": 46286,
+ "achievers": 44544,
+ "achieves": 40123,
+ "achieving": 16120,
+ "achilles": 33327,
+ "achim": 42335,
+ "aching": 12864,
+ "acho": 33130,
+ "achs": 41195,
+ "aci": 4359,
+ "aci": 34100,
+ "acia": 30163,
+ "acial": 32422,
+ "acid": 35474,
+ "acid": 10085,
+ "acidity": 48800,
+ "acids": 27751,
+ "acies": 20162,
+ "acin": 39442,
+ "acing": 9442,
+ "acio": 26202,
+ "acion": 44965,
+ "acion": 24968,
+ "acional": 26435,
+ "aciones": 35832,
+ "acious": 16020,
+ "acity": 7511,
+ "ación": 38175,
+ "ack": 877,
+ "ack": 725,
+ "acked": 5698,
+ "acker": 31201,
+ "acker": 7940,
+ "ackeray": 41843,
+ "acki": 42857,
+ "acking": 5515,
+ "ackles": 28503,
+ "acknow": 13563,
+ "acknowle": 18100,
+ "acknowledge": 25209,
+ "acknowledged": 35913,
+ "acknowledges": 49083,
+ "acknowledging": 45645,
+ "acks": 3858,
+ "acl": 47593,
+ "acl": 23073,
+ "acle": 6504,
+ "acles": 34164,
+ "aclu": 37354,
+ "acm": 39317,
+ "acmilan": 36500,
+ "acne": 24195,
+ "aco": 9463,
+ "aco": 8800,
+ "acol": 17431,
+ "acollege": 43468,
+ "acom": 17224,
+ "acom": 22342,
+ "acon": 11621,
+ "acon": 11571,
+ "aconf": 38851,
+ "acons": 31599,
+ "acor": 22076,
+ "acorn": 37537,
+ "acos": 39943,
+ "acosta": 31994,
+ "acou": 8794,
+ "acoun": 31295,
+ "acounty": 45449,
+ "acoustic": 10616,
+ "acoustics": 43873,
+ "acp": 19627,
+ "acqu": 7946,
+ "acquainted": 40713,
+ "acqui": 12194,
+ "acquire": 21576,
+ "acquired": 15932,
+ "acquires": 27376,
+ "acquiring": 42785,
+ "acquis": 14207,
+ "acquisition": 16543,
+ "acquisitions": 39649,
+ "acr": 43648,
+ "acre": 26749,
+ "acre": 9493,
+ "acres": 11630,
+ "acro": 21060,
+ "acrob": 40891,
+ "acron": 37770,
+ "across": 2500,
+ "acrosse": 40979,
+ "acruz": 40455,
+ "acry": 10440,
+ "acrylic": 12252,
+ "acs": 11782,
+ "act": 10305,
+ "act": 1393,
+ "acted": 10971,
+ "acti": 4786,
+ "acting": 6319,
+ "action": 12493,
+ "action": 1816,
+ "actions": 6271,
+ "activ": 3430,
+ "activate": 26737,
+ "activated": 22249,
+ "activation": 26769,
+ "active": 19009,
+ "active": 4046,
+ "actively": 18645,
+ "activi": 7230,
+ "activism": 20117,
+ "activist": 10850,
+ "activists": 12649,
+ "activities": 6514,
+ "activity": 6206,
+ "actment": 44807,
+ "acton": 36167,
+ "acton": 36697,
+ "actonclimate": 43797,
+ "actor": 12181,
+ "actor": 4035,
+ "actors": 9255,
+ "actorslife": 25117,
+ "actorvijay": 34033,
+ "actress": 5805,
+ "actresses": 33639,
+ "acts": 6816,
+ "actu": 2375,
+ "actual": 7488,
+ "actually": 2955,
+ "acu": 9204,
+ "acu": 48475,
+ "aculture": 38145,
+ "acup": 30869,
+ "acup": 27278,
+ "acupuncture": 40043,
+ "acur": 44719,
+ "acura": 30120,
+ "acus": 33710,
+ "acute": 19734,
+ "acy": 18717,
+ "acy": 2356,
+ "ad": 594,
+ "ad": 680,
+ "ada": 25785,
+ "ada": 1886,
+ "adaily": 47254,
+ "adal": 46646,
+ "adam": 6037,
+ "adam": 4944,
+ "adamlambert": 27659,
+ "adams": 7942,
+ "adan": 41802,
+ "adani": 37499,
+ "adap": 6341,
+ "adapt": 22666,
+ "adaptation": 16566,
+ "adapted": 26657,
+ "adapter": 21839,
+ "adapting": 44120,
+ "adaptive": 28672,
+ "adar": 27702,
+ "adar": 32681,
+ "adas": 23250,
+ "adata": 39500,
+ "aday": 31367,
+ "aday": 10280,
+ "adays": 24337,
+ "adb": 45630,
+ "adc": 38201,
+ "add": 19408,
+ "add": 3536,
+ "addams": 38912,
+ "added": 4149,
+ "adder": 47557,
+ "addi": 36378,
+ "addic": 5709,
+ "addict": 14614,
+ "addicted": 16275,
+ "addiction": 11751,
+ "addictive": 29638,
+ "addicts": 29997,
+ "adding": 8676,
+ "addis": 43911,
+ "addison": 32369,
+ "additi": 26927,
+ "addition": 6698,
+ "additional": 10666,
+ "additions": 22575,
+ "additive": 48546,
+ "addo": 40001,
+ "address": 5834,
+ "addressed": 20817,
+ "addresses": 12702,
+ "addressing": 10594,
+ "adds": 9944,
+ "addy": 24746,
+ "ade": 2194,
+ "ade": 1928,
+ "adecides": 46374,
+ "aded": 9994,
+ "adee": 47054,
+ "adel": 4434,
+ "adel": 27308,
+ "adelaide": 38193,
+ "adelaide": 11611,
+ "adele": 42843,
+ "adele": 21220,
+ "adelrey": 43627,
+ "ademy": 49123,
+ "aden": 28669,
+ "aden": 28688,
+ "adena": 23648,
+ "adequ": 18232,
+ "adequate": 22281,
+ "ader": 21365,
+ "adero": 49185,
+ "aders": 27672,
+ "ades": 5793,
+ "adh": 42301,
+ "adhd": 32649,
+ "adhe": 21175,
+ "adhesive": 38429,
+ "adi": 2486,
+ "adi": 8779,
+ "adia": 26874,
+ "adic": 36780,
+ "adid": 8086,
+ "adidas": 22396,
+ "adidas": 9589,
+ "adidasoriginals": 48575,
+ "adies": 45834,
+ "adifference": 37217,
+ "adilla": 41167,
+ "ading": 15000,
+ "adio": 15060,
+ "adirond": 36843,
+ "adish": 49009,
+ "adity": 28596,
+ "aditya": 37186,
+ "adityanath": 44437,
+ "adjac": 32517,
+ "adjacent": 33836,
+ "adjec": 45512,
+ "adju": 16413,
+ "adjun": 45995,
+ "adjust": 13784,
+ "adjust": 28073,
+ "adjustable": 20476,
+ "adjusted": 30515,
+ "adjusting": 41132,
+ "adjustment": 36081,
+ "adjustments": 36331,
+ "adl": 49351,
+ "adler": 30222,
+ "adm": 9892,
+ "adm": 33604,
+ "admi": 11666,
+ "admin": 12528,
+ "admini": 6434,
+ "administr": 12174,
+ "administration": 9502,
+ "administrative": 22424,
+ "administrator": 22603,
+ "administrators": 36123,
+ "admins": 49297,
+ "admir": 17031,
+ "admiral": 21013,
+ "admiration": 39569,
+ "admire": 17791,
+ "admired": 36103,
+ "admirer": 48344,
+ "admiring": 29835,
+ "admission": 11315,
+ "admissions": 22463,
+ "admit": 13769,
+ "admits": 16332,
+ "admitted": 20427,
+ "admitting": 46148,
+ "adn": 40339,
+ "adnan": 42037,
+ "ado": 4775,
+ "ado": 2933,
+ "adobe": 29256,
+ "adobe": 16484,
+ "adog": 44913,
+ "adol": 33512,
+ "adole": 22704,
+ "adolescent": 36793,
+ "adolescents": 45656,
+ "adolf": 41179,
+ "adon": 25907,
+ "adona": 48419,
+ "adop": 4183,
+ "adopt": 16441,
+ "adopt": 11159,
+ "adoptable": 36905,
+ "adoptdont": 19674,
+ "adoptdontshop": 20089,
+ "adopted": 12538,
+ "adopting": 30158,
+ "adoption": 11544,
+ "adopts": 40853,
+ "ador": 4992,
+ "ador": 9162,
+ "adora": 40031,
+ "adorable": 6298,
+ "adoration": 46781,
+ "adore": 15502,
+ "adored": 49233,
+ "adores": 30290,
+ "adorned": 44953,
+ "ados": 20079,
+ "adox": 32188,
+ "adp": 44426,
+ "adr": 46189,
+ "adren": 24204,
+ "adrenaline": 35552,
+ "adri": 5935,
+ "adrian": 25012,
+ "adrian": 13163,
+ "adriana": 41363,
+ "adrid": 26562,
+ "adrien": 47469,
+ "adrienne": 40081,
+ "ads": 2485,
+ "adu": 16882,
+ "adu": 24446,
+ "adukone": 30511,
+ "adul": 7222,
+ "adult": 42209,
+ "adult": 7115,
+ "adulthood": 40964,
+ "adults": 9391,
+ "adv": 1647,
+ "adv": 21018,
+ "advan": 33411,
+ "advance": 27291,
+ "advance": 7022,
+ "advanced": 7465,
+ "advancement": 35437,
+ "advances": 15852,
+ "advancing": 21355,
+ "advani": 48189,
+ "advant": 7017,
+ "advantage": 8573,
+ "advantaged": 38361,
+ "advantages": 23506,
+ "adven": 41670,
+ "advent": 3071,
+ "advent": 15199,
+ "adventcalendar": 43492,
+ "adventur": 29627,
+ "adventure": 17251,
+ "adventure": 4377,
+ "adventurer": 48098,
+ "adventures": 7941,
+ "adventurous": 31179,
+ "adver": 4806,
+ "adverse": 30348,
+ "adversity": 32516,
+ "advert": 19080,
+ "adverti": 5682,
+ "advertise": 31473,
+ "advertised": 38987,
+ "advertisement": 18713,
+ "advertiser": 41829,
+ "advertisers": 45472,
+ "advertising": 8158,
+ "adverts": 44306,
+ "advice": 4973,
+ "advis": 4634,
+ "advise": 25962,
+ "advised": 23196,
+ "adviser": 20367,
+ "advisers": 40984,
+ "advises": 42761,
+ "advising": 39648,
+ "advisor": 12380,
+ "advisors": 23197,
+ "advisory": 10224,
+ "advoc": 6657,
+ "advocacy": 14443,
+ "advocate": 12044,
+ "advocates": 17757,
+ "adwords": 48343,
+ "ady": 41446,
+ "ady": 8781,
+ "ae": 5548,
+ "ae": 4542,
+ "aea": 37048,
+ "aed": 26912,
+ "aege": 42304,
+ "ael": 41533,
+ "ael": 43340,
+ "aen": 43085,
+ "aer": 10195,
+ "aeri": 27685,
+ "aerial": 44866,
+ "aerial": 12440,
+ "aero": 10196,
+ "aero": 25026,
+ "aerob": 42824,
+ "aeron": 37286,
+ "aeronau": 42816,
+ "aerop": 27735,
+ "aerosmith": 43253,
+ "aerospace": 20530,
+ "aes": 10617,
+ "aes": 35677,
+ "aest": 40694,
+ "aesthe": 21181,
+ "aesthetic": 16179,
+ "aesthetics": 29295,
+ "aew": 47108,
+ "af": 702,
+ "af": 4391,
+ "afa": 24953,
+ "afan": 47474,
+ "afar": 41637,
+ "afar": 37866,
+ "afb": 27022,
+ "afc": 29742,
+ "afc": 6571,
+ "afcb": 44276,
+ "afcon": 30019,
+ "afd": 44626,
+ "afe": 30487,
+ "afe": 13912,
+ "afer": 44707,
+ "aff": 8849,
+ "aff": 14864,
+ "affair": 13998,
+ "affairs": 9830,
+ "affe": 4556,
+ "affect": 11361,
+ "affected": 9715,
+ "affecting": 18448,
+ "affection": 33780,
+ "affection": 28381,
+ "affectionate": 42578,
+ "affects": 17285,
+ "affili": 12120,
+ "affiliate": 18652,
+ "affiliated": 37540,
+ "affiliation": 48377,
+ "affinity": 41451,
+ "affir": 25343,
+ "affirm": 42711,
+ "affirm": 48625,
+ "affirmation": 47495,
+ "affl": 34036,
+ "affleck": 35584,
+ "afford": 7951,
+ "afford": 13223,
+ "affordability": 44828,
+ "affordable": 43944,
+ "affordable": 8926,
+ "afg": 33994,
+ "afgh": 9029,
+ "afghan": 15919,
+ "afghanistan": 9836,
+ "afi": 24074,
+ "afi": 31958,
+ "afil": 27209,
+ "afire": 42010,
+ "afirst": 38601,
+ "afl": 15132,
+ "afl": 14356,
+ "aflo": 41959,
+ "afm": 38385,
+ "afootball": 41694,
+ "afor": 43102,
+ "afore": 41468,
+ "afp": 18311,
+ "afraid": 9474,
+ "afri": 13888,
+ "afric": 2136,
+ "africa": 3093,
+ "african": 17471,
+ "african": 4736,
+ "africans": 26534,
+ "afridi": 37651,
+ "afrika": 45833,
+ "afrin": 45586,
+ "afro": 16267,
+ "afro": 21795,
+ "afs": 48960,
+ "aft": 22693,
+ "after": 2278,
+ "after": 953,
+ "afterdark": 48966,
+ "afterlife": 46790,
+ "aftermath": 20958,
+ "afterno": 22330,
+ "afternoon": 39035,
+ "afternoon": 2716,
+ "afternoons": 31631,
+ "afterparty": 35305,
+ "afterwards": 23911,
+ "ag": 602,
+ "ag": 5241,
+ "aga": 1050,
+ "aga": 4654,
+ "again": 1495,
+ "against": 23838,
+ "against": 1601,
+ "agame": 46943,
+ "agan": 42946,
+ "agan": 9178,
+ "agar": 13199,
+ "agar": 17544,
+ "agarwal": 43117,
+ "agas": 20430,
+ "agate": 25454,
+ "agatha": 43896,
+ "agave": 42671,
+ "agawa": 39433,
+ "agazine": 44942,
+ "age": 4758,
+ "age": 805,
+ "aged": 3889,
+ "ageing": 25349,
+ "agen": 10101,
+ "agen": 43696,
+ "agencies": 13887,
+ "agency": 44885,
+ "agency": 6270,
+ "agend": 48653,
+ "agenda": 8728,
+ "agent": 21210,
+ "agent": 6576,
+ "agents": 10199,
+ "agentsof": 37074,
+ "agentsofshield": 38801,
+ "ager": 44847,
+ "ager": 10443,
+ "agers": 22123,
+ "ages": 2321,
+ "agg": 45482,
+ "aggarwal": 39386,
+ "agger": 27836,
+ "aggi": 36844,
+ "aggie": 44244,
+ "aggie": 37618,
+ "aggies": 31047,
+ "aggio": 36685,
+ "aggrav": 35203,
+ "aggre": 10426,
+ "aggreg": 41968,
+ "aggregate": 41318,
+ "aggression": 28900,
+ "aggressive": 16295,
+ "aggressively": 48667,
+ "agh": 17917,
+ "agh": 14402,
+ "aghan": 31276,
+ "agi": 24036,
+ "agi": 17645,
+ "agic": 37652,
+ "agile": 16276,
+ "agility": 32161,
+ "aging": 4336,
+ "agio": 41746,
+ "agirl": 35469,
+ "agle": 37035,
+ "agle": 16702,
+ "agles": 36374,
+ "agles": 22679,
+ "aglia": 46912,
+ "agm": 19162,
+ "agn": 36474,
+ "agna": 43626,
+ "agne": 29374,
+ "agne": 48303,
+ "agnes": 26213,
+ "agno": 41540,
+ "ago": 6276,
+ "ago": 1468,
+ "agomez": 27127,
+ "agon": 26775,
+ "agon": 14901,
+ "agony": 36977,
+ "agor": 38920,
+ "agos": 32657,
+ "agov": 34227,
+ "agp": 46048,
+ "agr": 36639,
+ "agra": 26660,
+ "agra": 29830,
+ "agram": 2447,
+ "agre": 3180,
+ "agreat": 37594,
+ "agree": 5953,
+ "agreed": 12774,
+ "agreeing": 40720,
+ "agreement": 8286,
+ "agreements": 25865,
+ "agrees": 17854,
+ "agri": 20527,
+ "agri": 30326,
+ "agricul": 7234,
+ "agricultural": 15440,
+ "agriculture": 9720,
+ "agro": 33178,
+ "agro": 44589,
+ "agron": 41314,
+ "agroup": 40099,
+ "ags": 16926,
+ "agt": 39681,
+ "agu": 3922,
+ "agu": 36544,
+ "agua": 18482,
+ "aguchi": 49206,
+ "ague": 2095,
+ "aguero": 42964,
+ "agues": 7000,
+ "aguil": 27946,
+ "aguilar": 44715,
+ "ah": 1772,
+ "ah": 1288,
+ "aha": 12082,
+ "aha": 8429,
+ "ahah": 38661,
+ "ahaha": 32423,
+ "ahahaha": 42620,
+ "aham": 36036,
+ "ahan": 45061,
+ "ahan": 19255,
+ "ahar": 31038,
+ "ahar": 38760,
+ "ahe": 27688,
+ "ahead": 3158,
+ "ahem": 39995,
+ "ahh": 13152,
+ "ahhh": 14769,
+ "ahhhh": 21054,
+ "ahhhhh": 36392,
+ "ahi": 45349,
+ "ahi": 24154,
+ "ahl": 30433,
+ "ahmad": 32167,
+ "ahmad": 16902,
+ "ahmadi": 38656,
+ "ahmadiyya": 44865,
+ "ahmed": 19491,
+ "ahmed": 12081,
+ "ahmedabad": 26966,
+ "ahn": 33405,
+ "aho": 28114,
+ "aho": 38444,
+ "ahora": 43113,
+ "ahouse": 33197,
+ "ahoy": 38652,
+ "ahs": 16937,
+ "ahu": 11908,
+ "ahu": 16515,
+ "ai": 2014,
+ "ai": 2215,
+ "aia": 27046,
+ "aib": 34780,
+ "aic": 29454,
+ "aid": 13723,
+ "aid": 5182,
+ "aida": 33830,
+ "aidan": 48814,
+ "aidan": 26945,
+ "aide": 31558,
+ "aide": 9746,
+ "aided": 48707,
+ "aiden": 40020,
+ "aides": 49082,
+ "aids": 11759,
+ "aig": 27295,
+ "aig": 46989,
+ "aii": 22478,
+ "aik": 42575,
+ "aiken": 46342,
+ "ail": 1457,
+ "ail": 9154,
+ "ailed": 38919,
+ "ailing": 29999,
+ "ails": 27024,
+ "aim": 6787,
+ "aim": 11255,
+ "aime": 39872,
+ "aimed": 20247,
+ "aimee": 36318,
+ "aiming": 21768,
+ "aimo": 36706,
+ "aims": 13326,
+ "ain": 8326,
+ "ain": 2210,
+ "aine": 48983,
+ "aine": 17634,
+ "ains": 27621,
+ "aint": 29543,
+ "aint": 13099,
+ "ainted": 39933,
+ "aioli": 43949,
+ "air": 1281,
+ "air": 1922,
+ "aira": 35085,
+ "aira": 46444,
+ "airasia": 48020,
+ "airbnb": 23098,
+ "airborne": 22755,
+ "airbus": 15324,
+ "aircraft": 7706,
+ "airdrop": 38434,
+ "aire": 7682,
+ "aired": 21938,
+ "aires": 17034,
+ "airfield": 40525,
+ "airforce": 23511,
+ "airing": 20453,
+ "airline": 14847,
+ "airlines": 8929,
+ "airmen": 44499,
+ "airplane": 16451,
+ "airplanes": 33319,
+ "airplay": 47024,
+ "airpollution": 47362,
+ "airport": 48337,
+ "airport": 3259,
+ "airports": 21543,
+ "airs": 18539,
+ "airshow": 27139,
+ "airsoft": 30134,
+ "airspace": 49280,
+ "airstrikes": 37220,
+ "airtel": 34784,
+ "airtime": 46617,
+ "airwaves": 43910,
+ "airways": 14299,
+ "airy": 44453,
+ "ais": 7616,
+ "ais": 11393,
+ "aise": 30505,
+ "aish": 21946,
+ "aisha": 40211,
+ "aishwar": 29687,
+ "aishwarya": 44019,
+ "aisle": 26917,
+ "ait": 25613,
+ "ait": 40814,
+ "aj": 3990,
+ "aj": 6342,
+ "aja": 42343,
+ "aja": 19633,
+ "ajax": 21933,
+ "ajay": 22494,
+ "ajay": 28726,
+ "ajaydevgn": 35515,
+ "aje": 48818,
+ "aje": 33315,
+ "ajes": 38791,
+ "aji": 26102,
+ "aji": 21153,
+ "ajit": 42261,
+ "ajith": 24118,
+ "ajo": 26958,
+ "aju": 36855,
+ "ak": 819,
+ "ak": 1196,
+ "aka": 19154,
+ "aka": 3412,
+ "akaif": 45736,
+ "akan": 43678,
+ "akan": 38244,
+ "akapoor": 40064,
+ "akarta": 48603,
+ "akb": 41962,
+ "akbar": 27180,
+ "ake": 10558,
+ "ake": 5776,
+ "aked": 6115,
+ "aker": 14245,
+ "aker": 3074,
+ "akers": 5788,
+ "akes": 4764,
+ "akest": 46679,
+ "akh": 14821,
+ "akh": 30660,
+ "akhan": 28158,
+ "akhi": 41660,
+ "akhilesh": 48495,
+ "akhtar": 45458,
+ "aki": 18173,
+ "aki": 6592,
+ "akin": 24630,
+ "akin": 13601,
+ "aking": 1809,
+ "akins": 48568,
+ "akira": 34001,
+ "akis": 27732,
+ "akistan": 46221,
+ "akley": 39908,
+ "ako": 44027,
+ "ako": 14541,
+ "akon": 47105,
+ "akos": 44659,
+ "akrish": 37434,
+ "akron": 26115,
+ "aks": 2953,
+ "aksh": 28226,
+ "akshay": 21483,
+ "akshay": 38914,
+ "akshaykumar": 23624,
+ "akshi": 42634,
+ "aku": 18151,
+ "aku": 20815,
+ "aky": 11977,
+ "al": 526,
+ "al": 566,
+ "ala": 12783,
+ "ala": 3449,
+ "alab": 6365,
+ "alabam": 45880,
+ "alabama": 8422,
+ "alach": 24622,
+ "alad": 23074,
+ "aladdin": 29951,
+ "alai": 47072,
+ "alain": 28999,
+ "alam": 16612,
+ "alam": 16012,
+ "alamo": 41922,
+ "alamo": 34632,
+ "alan": 9563,
+ "alan": 5773,
+ "alana": 43405,
+ "aland": 34304,
+ "aland": 6819,
+ "alar": 34333,
+ "alarm": 11321,
+ "alarming": 37209,
+ "alarms": 31236,
+ "alarts": 31422,
+ "alas": 7276,
+ "alas": 22412,
+ "alaska": 9562,
+ "alaskan": 33898,
+ "alastair": 42062,
+ "alay": 30289,
+ "alay": 36450,
+ "alaya": 36397,
+ "alb": 45248,
+ "alba": 25254,
+ "alban": 10882,
+ "albania": 29170,
+ "albanian": 47721,
+ "albans": 44119,
+ "albany": 17359,
+ "albat": 42797,
+ "albeit": 38984,
+ "alber": 6413,
+ "albert": 34174,
+ "albert": 9507,
+ "alberta": 11048,
+ "alberto": 22714,
+ "albi": 18512,
+ "albino": 48062,
+ "albion": 24071,
+ "albu": 2216,
+ "album": 40712,
+ "album": 2431,
+ "albums": 10705,
+ "albuquerque": 31079,
+ "alcat": 35361,
+ "alche": 37909,
+ "alchemist": 38913,
+ "alchemy": 39501,
+ "alco": 6848,
+ "alco": 45446,
+ "alcohol": 9426,
+ "alcoholic": 25098,
+ "ald": 4539,
+ "ald": 2928,
+ "alda": 46440,
+ "alde": 33114,
+ "alden": 17155,
+ "alden": 27710,
+ "aldenrichards": 20051,
+ "alder": 18220,
+ "alder": 46571,
+ "aldi": 23204,
+ "aldo": 9933,
+ "aldridge": 38084,
+ "alds": 14285,
+ "aldu": 6505,
+ "aldub": 10532,
+ "aldub": 15247,
+ "ale": 1440,
+ "ale": 1336,
+ "alea": 26518,
+ "aleague": 38909,
+ "alec": 29804,
+ "alec": 19954,
+ "alecoscino": 47948,
+ "aled": 4970,
+ "alee": 24515,
+ "alej": 23440,
+ "alejandro": 32950,
+ "alek": 26906,
+ "alek": 43310,
+ "aleksand": 48429,
+ "alem": 11825,
+ "aleppo": 19258,
+ "aler": 25674,
+ "aler": 27335,
+ "alert": 4662,
+ "alerts": 22144,
+ "ales": 44171,
+ "ales": 5962,
+ "aless": 21864,
+ "alessandro": 37344,
+ "alestine": 31945,
+ "alex": 2959,
+ "alex": 4134,
+ "alexa": 16273,
+ "alexand": 10696,
+ "alexander": 25527,
+ "alexander": 7563,
+ "alexandra": 19054,
+ "alexandre": 35711,
+ "alexandria": 21171,
+ "alexis": 35023,
+ "alexis": 14243,
+ "aley": 21635,
+ "alf": 27098,
+ "alfa": 23482,
+ "alfar": 38870,
+ "alfie": 28598,
+ "alfon": 31947,
+ "alfonso": 41784,
+ "alfre": 20982,
+ "alfred": 16553,
+ "alfredo": 32291,
+ "algae": 25654,
+ "algar": 36291,
+ "algarve": 40290,
+ "alge": 24336,
+ "algebra": 33694,
+ "alger": 18568,
+ "algeria": 25257,
+ "algon": 33007,
+ "algori": 14912,
+ "algorithm": 23295,
+ "algorithms": 26039,
+ "alham": 23352,
+ "alhamdulil": 35129,
+ "alhamdulillah": 38982,
+ "ali": 835,
+ "ali": 3558,
+ "alia": 2492,
+ "aliaa": 36468,
+ "alian": 3464,
+ "alias": 40026,
+ "alibaba": 39231,
+ "alic": 25265,
+ "alice": 23759,
+ "alice": 9192,
+ "alici": 31630,
+ "alicia": 20914,
+ "alie": 8697,
+ "alien": 22846,
+ "alien": 9639,
+ "aliens": 14883,
+ "alier": 39493,
+ "alies": 38086,
+ "alife": 41347,
+ "alife": 21100,
+ "alig": 21272,
+ "alight": 36157,
+ "align": 31160,
+ "aligned": 29292,
+ "alignment": 27267,
+ "alik": 31141,
+ "alike": 12665,
+ "alim": 42075,
+ "alin": 42746,
+ "alin": 40063,
+ "alina": 39529,
+ "aline": 21799,
+ "aling": 5169,
+ "alion": 19049,
+ "alis": 21308,
+ "alis": 20114,
+ "alisa": 38918,
+ "alisation": 42143,
+ "alise": 36718,
+ "alised": 25099,
+ "alism": 5607,
+ "alison": 28653,
+ "alison": 16970,
+ "alist": 44900,
+ "alist": 3320,
+ "alistair": 40551,
+ "alistic": 22302,
+ "alists": 5653,
+ "alit": 45566,
+ "alities": 27925,
+ "ality": 1694,
+ "alive": 40467,
+ "alive": 4716,
+ "aliz": 30979,
+ "alization": 8026,
+ "alize": 10268,
+ "alized": 6141,
+ "alizer": 38922,
+ "alizes": 26181,
+ "alizing": 13023,
+ "alk": 30246,
+ "alk": 21577,
+ "alkal": 33450,
+ "alkaline": 39210,
+ "all": 813,
+ "all": 615,
+ "alla": 13884,
+ "alla": 14000,
+ "allabout": 43996,
+ "allah": 6378,
+ "allan": 36552,
+ "allan": 15404,
+ "allblacks": 47728,
+ "allday": 35862,
+ "alle": 4870,
+ "alle": 29478,
+ "alled": 7379,
+ "alleg": 7456,
+ "allegations": 16992,
+ "alleged": 12133,
+ "allegedly": 14177,
+ "alleges": 45051,
+ "allegh": 41479,
+ "allegheny": 47851,
+ "allegi": 28832,
+ "allegiance": 30955,
+ "allen": 16712,
+ "allen": 6386,
+ "allenge": 31387,
+ "aller": 10116,
+ "aller": 30630,
+ "allergic": 28809,
+ "allergies": 28247,
+ "allergy": 24408,
+ "allery": 32542,
+ "alles": 43354,
+ "allevi": 31682,
+ "alleviate": 44799,
+ "alley": 36205,
+ "alley": 10329,
+ "allez": 49137,
+ "alli": 4123,
+ "alli": 15268,
+ "alliance": 45404,
+ "alliance": 8945,
+ "alliances": 48403,
+ "allianz": 45740,
+ "allie": 25040,
+ "allied": 20045,
+ "allies": 17277,
+ "alligator": 28574,
+ "allin": 45007,
+ "allin": 22395,
+ "alline": 48182,
+ "alling": 2992,
+ "allis": 45309,
+ "allison": 34602,
+ "allison": 16578,
+ "allman": 42611,
+ "allo": 8107,
+ "allo": 18389,
+ "allocated": 42716,
+ "allocation": 35139,
+ "allon": 46693,
+ "allot": 26363,
+ "allotment": 33750,
+ "allow": 5645,
+ "allow": 6722,
+ "allowance": 35696,
+ "allowed": 7885,
+ "allowing": 12458,
+ "allows": 9966,
+ "alloy": 22467,
+ "alls": 1997,
+ "allstar": 31247,
+ "allstar": 22974,
+ "allstars": 31198,
+ "allthe": 29253,
+ "allu": 20157,
+ "alluarjun": 39333,
+ "allure": 41814,
+ "ally": 7461,
+ "ally": 769,
+ "alm": 28303,
+ "alma": 32933,
+ "alma": 18337,
+ "alman": 29394,
+ "almanac": 41268,
+ "almighty": 21898,
+ "almond": 15646,
+ "almonds": 30468,
+ "almost": 47534,
+ "almost": 2671,
+ "aln": 47203,
+ "alo": 3435,
+ "alo": 6183,
+ "aloe": 30728,
+ "alog": 15813,
+ "alogue": 9101,
+ "aloha": 23160,
+ "aloils": 49002,
+ "alom": 22236,
+ "alon": 14097,
+ "alon": 42846,
+ "alone": 4702,
+ "along": 8300,
+ "along": 2528,
+ "alongside": 8646,
+ "alonso": 25704,
+ "aloo": 46187,
+ "alore": 14323,
+ "alot": 16945,
+ "alou": 43180,
+ "aloud": 30028,
+ "alove": 46669,
+ "alove": 37045,
+ "alp": 32020,
+ "alp": 39342,
+ "alpac": 30128,
+ "alpaca": 42561,
+ "alph": 6720,
+ "alpha": 11807,
+ "alpha": 8624,
+ "alphabe": 45796,
+ "alphabet": 22335,
+ "alphon": 37865,
+ "alpine": 17055,
+ "alps": 18191,
+ "already": 2426,
+ "alright": 10866,
+ "als": 23982,
+ "als": 938,
+ "alsace": 49388,
+ "also": 1446,
+ "alt": 9995,
+ "alt": 10006,
+ "alta": 24470,
+ "alta": 25378,
+ "altaf": 47342,
+ "altam": 45624,
+ "altar": 16385,
+ "alter": 4949,
+ "alter": 21393,
+ "altered": 25201,
+ "altern": 47463,
+ "alternate": 15926,
+ "alternati": 16699,
+ "alternative": 37327,
+ "alternative": 8248,
+ "alternatives": 25041,
+ "alth": 23463,
+ "alth": 5863,
+ "although": 9421,
+ "alti": 35531,
+ "alties": 17276,
+ "altitude": 23241,
+ "altman": 48100,
+ "alto": 35053,
+ "alto": 17518,
+ "altogether": 45689,
+ "alton": 41331,
+ "alton": 36550,
+ "altrin": 38458,
+ "altrincham": 44718,
+ "alty": 5546,
+ "alu": 4776,
+ "alu": 27991,
+ "alum": 5404,
+ "alum": 10553,
+ "alumin": 14563,
+ "alumini": 22908,
+ "aluminium": 23631,
+ "aluminum": 15251,
+ "alumna": 30313,
+ "alumni": 6646,
+ "alumnus": 23633,
+ "alums": 30155,
+ "alv": 20928,
+ "alvar": 25196,
+ "alvarez": 26924,
+ "alvaro": 41941,
+ "alves": 38547,
+ "alvin": 27023,
+ "alway": 14046,
+ "alway": 43764,
+ "always": 24997,
+ "always": 1466,
+ "alwx": 32768,
+ "aly": 6468,
+ "aly": 12910,
+ "alyn": 49150,
+ "alyss": 29490,
+ "alyssa": 18898,
+ "alz": 12936,
+ "alz": 41128,
+ "alzheim": 15212,
+ "alzheimer": 21151,
+ "alzheimers": 34592,
+ "am": 548,
+ "am": 687,
+ "ama": 18206,
+ "ama": 1696,
+ "amad": 45095,
+ "amade": 37366,
+ "amag": 32049,
+ "amal": 15315,
+ "amal": 36753,
+ "aman": 19890,
+ "aman": 10110,
+ "amand": 14560,
+ "amanda": 10036,
+ "amar": 6424,
+ "amar": 19607,
+ "amara": 48522,
+ "amari": 42565,
+ "amarillo": 40449,
+ "amarine": 45591,
+ "amarketing": 30788,
+ "amas": 22716,
+ "amas": 15667,
+ "amat": 38664,
+ "amat": 25455,
+ "amate": 12453,
+ "amateur": 14287,
+ "amaya": 47210,
+ "amaz": 1185,
+ "amaze": 24846,
+ "amazed": 18944,
+ "amazing": 15949,
+ "amazing": 1370,
+ "amazingly": 20368,
+ "amazon": 13630,
+ "amazon": 4140,
+ "amb": 9042,
+ "amb": 16853,
+ "amba": 27003,
+ "ambani": 45967,
+ "ambas": 5634,
+ "ambassad": 5758,
+ "ambassador": 6795,
+ "ambassadors": 16832,
+ "ambed": 42089,
+ "ambedkar": 48131,
+ "amber": 18292,
+ "amber": 9986,
+ "ambi": 11844,
+ "ambient": 23447,
+ "ambigu": 35702,
+ "ambition": 20673,
+ "ambitions": 34152,
+ "ambitious": 18666,
+ "ambro": 17585,
+ "ambrose": 24253,
+ "ambu": 34423,
+ "ambul": 13944,
+ "ambulance": 15555,
+ "ambush": 40725,
+ "amc": 24942,
+ "amc": 16921,
+ "amd": 20845,
+ "ame": 3995,
+ "ame": 780,
+ "amed": 5660,
+ "ameen": 24229,
+ "amel": 31988,
+ "amel": 10960,
+ "ameli": 21599,
+ "amelia": 21433,
+ "amell": 48198,
+ "amen": 18716,
+ "amen": 12335,
+ "amend": 12425,
+ "amendment": 15019,
+ "amendments": 40901,
+ "amenities": 30096,
+ "ament": 27528,
+ "amer": 17081,
+ "amer": 16147,
+ "ameri": 40422,
+ "americ": 1283,
+ "america": 2224,
+ "americafirst": 43216,
+ "american": 8746,
+ "american": 2151,
+ "americana": 26221,
+ "americanair": 42538,
+ "americani": 39726,
+ "americans": 6676,
+ "americas": 33343,
+ "americas": 18142,
+ "ames": 5469,
+ "ameter": 23393,
+ "amethy": 30291,
+ "amethyst": 31485,
+ "amex": 46390,
+ "amg": 21324,
+ "amher": 32311,
+ "amherst": 39065,
+ "ami": 6100,
+ "ami": 3065,
+ "amic": 25824,
+ "amic": 21383,
+ "amid": 18908,
+ "amid": 11953,
+ "amide": 30952,
+ "amidst": 25172,
+ "amie": 36901,
+ "amig": 40294,
+ "amiga": 35329,
+ "amigo": 44991,
+ "amigos": 28176,
+ "amii": 35462,
+ "amiibo": 38871,
+ "amily": 36732,
+ "amin": 14337,
+ "amin": 20235,
+ "amina": 47531,
+ "amination": 30355,
+ "amine": 35823,
+ "aming": 3507,
+ "amino": 33464,
+ "amir": 26029,
+ "amir": 21973,
+ "amis": 29829,
+ "amish": 24958,
+ "amit": 15083,
+ "amit": 25255,
+ "amitabh": 48124,
+ "amitshah": 32374,
+ "aml": 43185,
+ "amma": 29786,
+ "amman": 29243,
+ "ammo": 33474,
+ "ammunition": 35060,
+ "amn": 24073,
+ "amne": 14596,
+ "amnesia": 41741,
+ "amnesty": 46330,
+ "amnesty": 21177,
+ "amo": 4833,
+ "amo": 11156,
+ "amodi": 9826,
+ "amon": 17492,
+ "amon": 24046,
+ "among": 12310,
+ "among": 4265,
+ "amongst": 12520,
+ "amoo": 26977,
+ "amor": 19977,
+ "amor": 15973,
+ "amore": 38937,
+ "amore": 22691,
+ "amores": 36338,
+ "amos": 18133,
+ "amoto": 25492,
+ "amount": 6403,
+ "amounts": 16747,
+ "amour": 29908,
+ "amovie": 41062,
+ "amp": 3521,
+ "amp": 6259,
+ "amped": 22640,
+ "amphi": 16379,
+ "amphibious": 45206,
+ "amphitheater": 41285,
+ "amphitheatre": 44039,
+ "ample": 34162,
+ "amples": 14536,
+ "ampli": 15647,
+ "amplifier": 31743,
+ "amplify": 45308,
+ "amps": 19252,
+ "ampton": 29410,
+ "ampton": 9347,
+ "amr": 30916,
+ "amreading": 16546,
+ "amrit": 33849,
+ "ams": 1396,
+ "amster": 9110,
+ "amsterdam": 9441,
+ "amtrak": 27855,
+ "amu": 11347,
+ "amu": 32336,
+ "amur": 35014,
+ "amura": 35487,
+ "amus": 36269,
+ "amuse": 21421,
+ "amuse": 44367,
+ "amused": 30212,
+ "amusement": 32570,
+ "amusic": 20266,
+ "amusing": 31789,
+ "amwriting": 9660,
+ "amy": 10547,
+ "amy": 5187,
+ "an": 514,
+ "an": 550,
+ "ana": 6588,
+ "ana": 1388,
+ "anab": 34742,
+ "anada": 27948,
+ "anag": 12115,
+ "anagh": 40774,
+ "anaheim": 23728,
+ "anak": 34814,
+ "anak": 38658,
+ "anal": 2785,
+ "analo": 34179,
+ "analog": 19963,
+ "analogue": 46031,
+ "analy": 4611,
+ "analyse": 47246,
+ "analyses": 39695,
+ "analysis": 5296,
+ "analyst": 14198,
+ "analysts": 28075,
+ "analytical": 34550,
+ "analytics": 8558,
+ "analyze": 28519,
+ "analyzing": 32107,
+ "anam": 29525,
+ "anan": 37215,
+ "anand": 25073,
+ "anand": 22083,
+ "anap": 41566,
+ "anarch": 46405,
+ "anarchi": 39879,
+ "anarchy": 27707,
+ "anas": 31382,
+ "anas": 12633,
+ "anast": 48902,
+ "anasta": 22915,
+ "anastasi": 36534,
+ "anastasia": 37975,
+ "anat": 10045,
+ "anath": 31277,
+ "anatom": 33759,
+ "anatomy": 15376,
+ "anc": 1124,
+ "anc": 17758,
+ "anca": 14583,
+ "ance": 7165,
+ "ance": 884,
+ "anced": 5071,
+ "ancer": 17415,
+ "ancers": 37296,
+ "ances": 3515,
+ "ancestor": 43904,
+ "ancestors": 24405,
+ "ancestral": 41615,
+ "ancestry": 30922,
+ "anch": 9489,
+ "anche": 34679,
+ "ancho": 26610,
+ "anchor": 20030,
+ "anchor": 13201,
+ "anchorage": 31950,
+ "anchored": 45926,
+ "anchors": 37830,
+ "anci": 4192,
+ "ancient": 31495,
+ "ancient": 5810,
+ "ancies": 21647,
+ "ancing": 7797,
+ "anco": 15459,
+ "ancy": 16282,
+ "ancy": 3633,
+ "and": 672,
+ "and": 537,
+ "anda": 2911,
+ "andalu": 31443,
+ "andco": 36302,
+ "ande": 26889,
+ "ande": 30354,
+ "ander": 3740,
+ "ander": 3935,
+ "anders": 10880,
+ "andersen": 32661,
+ "anderson": 26683,
+ "anderson": 6510,
+ "andes": 24052,
+ "andfriends": 36871,
+ "andhi": 21617,
+ "andhra": 32452,
+ "andi": 28870,
+ "andi": 14354,
+ "andie": 46318,
+ "andme": 42831,
+ "ando": 35950,
+ "ando": 5986,
+ "andolan": 48965,
+ "andon": 36488,
+ "andor": 45243,
+ "andover": 44177,
+ "andr": 22661,
+ "andra": 46795,
+ "andra": 21730,
+ "andre": 2657,
+ "andre": 9400,
+ "andrea": 10895,
+ "andreas": 20444,
+ "andrei": 42137,
+ "andres": 25197,
+ "andretti": 44291,
+ "andrew": 11717,
+ "andrew": 4847,
+ "andrews": 14506,
+ "andri": 37208,
+ "andro": 4417,
+ "andro": 17980,
+ "android": 24284,
+ "android": 5191,
+ "androidgames": 46572,
+ "andromeda": 42942,
+ "andré": 35609,
+ "ands": 32257,
+ "andthe": 22111,
+ "andu": 44200,
+ "andum": 47266,
+ "andy": 9447,
+ "andy": 2888,
+ "ane": 5846,
+ "ane": 3051,
+ "anec": 33965,
+ "anem": 41395,
+ "anemone": 49019,
+ "aneous": 48273,
+ "anes": 15381,
+ "anese": 48778,
+ "anesthe": 30622,
+ "anesthesia": 43353,
+ "anew": 39084,
+ "anew": 47341,
+ "anews": 20919,
+ "aney": 22387,
+ "anfield": 26993,
+ "ang": 883,
+ "ang": 2704,
+ "anga": 11641,
+ "angames": 43178,
+ "angan": 28264,
+ "angas": 46180,
+ "ange": 2960,
+ "ange": 3039,
+ "angel": 5029,
+ "angel": 5130,
+ "angela": 12354,
+ "angeles": 7382,
+ "angeli": 15265,
+ "angelic": 41038,
+ "angelica": 38582,
+ "angelina": 28890,
+ "angelo": 14342,
+ "angelou": 41328,
+ "angels": 7809,
+ "anger": 32737,
+ "anger": 6788,
+ "angerous": 39716,
+ "angers": 29756,
+ "angh": 34030,
+ "angi": 28003,
+ "angi": 24301,
+ "angie": 18859,
+ "angle": 21749,
+ "angle": 6946,
+ "angled": 32322,
+ "angler": 22284,
+ "anglers": 41608,
+ "angles": 18627,
+ "anglesey": 31850,
+ "anglia": 32076,
+ "anglic": 28322,
+ "anglican": 33284,
+ "angling": 36824,
+ "anglo": 39515,
+ "anglo": 30408,
+ "ango": 19090,
+ "angola": 36636,
+ "angor": 41740,
+ "angp": 19992,
+ "angry": 33910,
+ "angry": 9054,
+ "angs": 18441,
+ "angst": 41714,
+ "angu": 11209,
+ "angular": 43584,
+ "angular": 24981,
+ "angularjs": 48608,
+ "angus": 19688,
+ "ani": 1326,
+ "ani": 3624,
+ "ania": 9866,
+ "anian": 9945,
+ "anians": 39393,
+ "anic": 23113,
+ "anie": 26697,
+ "anie": 7671,
+ "anil": 28589,
+ "anil": 34619,
+ "anim": 2190,
+ "animal": 10697,
+ "animal": 4668,
+ "animalrights": 42859,
+ "animals": 4995,
+ "animate": 40076,
+ "animated": 13360,
+ "animation": 10344,
+ "animations": 42870,
+ "animator": 42591,
+ "anime": 23314,
+ "anime": 6469,
+ "anin": 45735,
+ "aning": 30972,
+ "anir": 27089,
+ "anirud": 35278,
+ "anirudhofficial": 45917,
+ "anis": 40986,
+ "anis": 47556,
+ "anism": 20947,
+ "anist": 16729,
+ "anistan": 9727,
+ "aniston": 47344,
+ "anit": 23683,
+ "anita": 18544,
+ "anium": 14794,
+ "anj": 22443,
+ "anja": 43440,
+ "anjali": 38834,
+ "anjo": 47353,
+ "ank": 13339,
+ "ank": 10029,
+ "anka": 45324,
+ "ankara": 34309,
+ "ankle": 14777,
+ "ankles": 48688,
+ "ann": 850,
+ "ann": 5424,
+ "anna": 13821,
+ "anna": 2160,
+ "annab": 22336,
+ "annabelle": 47661,
+ "annah": 39166,
+ "annah": 14327,
+ "annak": 41720,
+ "annan": 32166,
+ "annapolis": 34491,
+ "annas": 48467,
+ "anne": 9139,
+ "anne": 4083,
+ "anned": 27352,
+ "anner": 12642,
+ "annes": 24343,
+ "annette": 36821,
+ "annex": 42958,
+ "annex": 46389,
+ "anni": 2438,
+ "anni": 13728,
+ "annie": 37270,
+ "annie": 12173,
+ "annies": 43184,
+ "annihil": 32734,
+ "annis": 24742,
+ "anniv": 31399,
+ "anniver": 29671,
+ "annivers": 42836,
+ "anniversaire": 30882,
+ "anniversary": 3048,
+ "anno": 9901,
+ "anno": 26871,
+ "annon": 26385,
+ "annot": 30411,
+ "announ": 1806,
+ "announce": 3682,
+ "announced": 4103,
+ "announcement": 6932,
+ "announcements": 23735,
+ "announcer": 33626,
+ "announces": 6500,
+ "announcing": 11593,
+ "annoy": 45138,
+ "annoyed": 29863,
+ "annoying": 15248,
+ "annu": 21698,
+ "annual": 2906,
+ "annually": 23703,
+ "anny": 34313,
+ "anny": 5291,
+ "ano": 5617,
+ "ano": 2658,
+ "anom": 21612,
+ "anomaly": 46811,
+ "anon": 47079,
+ "anon": 13667,
+ "anonym": 38605,
+ "anonymous": 15036,
+ "anoo": 25690,
+ "anor": 13243,
+ "anor": 16596,
+ "anos": 20132,
+ "another": 29274,
+ "another": 1380,
+ "anova": 24116,
+ "ans": 24586,
+ "ans": 885,
+ "ansari": 40748,
+ "ansel": 40356,
+ "answ": 3369,
+ "answe": 14391,
+ "answer": 4518,
+ "answered": 14499,
+ "answering": 18280,
+ "answers": 8692,
+ "ant": 1103,
+ "ant": 773,
+ "anta": 3023,
+ "antag": 41745,
+ "antal": 39355,
+ "antalya": 47440,
+ "antan": 32899,
+ "antarc": 21338,
+ "antarctic": 27077,
+ "antarctica": 22587,
+ "ante": 19311,
+ "ante": 9769,
+ "antebellum": 41683,
+ "antelope": 39177,
+ "anten": 35517,
+ "antenna": 26370,
+ "anter": 46508,
+ "antes": 14927,
+ "antgrasso": 39074,
+ "anth": 3737,
+ "anth": 29741,
+ "antha": 47981,
+ "anthe": 34167,
+ "anthem": 12504,
+ "anthi": 45261,
+ "anthology": 21009,
+ "anthony": 17477,
+ "anthony": 6113,
+ "anthro": 10019,
+ "anthropo": 18538,
+ "anthropology": 32407,
+ "anthus": 37639,
+ "anti": 3120,
+ "anti": 3564,
+ "antibio": 18954,
+ "antibiotic": 34387,
+ "antibiotics": 29499,
+ "antibody": 49018,
+ "antic": 8260,
+ "anticip": 11435,
+ "anticipate": 38280,
+ "anticipated": 18605,
+ "anticipating": 48067,
+ "anticipation": 26983,
+ "antics": 37126,
+ "antidote": 45476,
+ "antifa": 35926,
+ "antigua": 39910,
+ "antine": 17641,
+ "antino": 27818,
+ "antioxid": 23010,
+ "antioxidant": 37452,
+ "antioxidants": 34208,
+ "antiqu": 21745,
+ "antique": 46517,
+ "antique": 9060,
+ "antiques": 17365,
+ "antis": 19748,
+ "antisemitism": 36630,
+ "antit": 37833,
+ "antitrust": 49343,
+ "antlers": 47720,
+ "antly": 5265,
+ "anto": 16826,
+ "anto": 24486,
+ "antoine": 25188,
+ "anton": 5497,
+ "anton": 19644,
+ "antoni": 39958,
+ "antonio": 30497,
+ "antonio": 7842,
+ "antony": 30707,
+ "antrim": 40252,
+ "ants": 1589,
+ "antv": 47520,
+ "antw": 44460,
+ "antwer": 26970,
+ "antwerp": 33797,
+ "antz": 25684,
+ "anu": 8537,
+ "anu": 17152,
+ "anup": 29617,
+ "anus": 27084,
+ "anush": 22765,
+ "anushka": 42080,
+ "anushka": 39822,
+ "anushkasharma": 44203,
+ "anwar": 34261,
+ "anxi": 9021,
+ "anxiety": 11103,
+ "anxious": 27793,
+ "any": 1307,
+ "any": 1504,
+ "anya": 11173,
+ "anybody": 10071,
+ "anyi": 41632,
+ "anymore": 7372,
+ "anyone": 2302,
+ "anything": 3582,
+ "anytime": 13924,
+ "anyway": 8931,
+ "anyways": 19778,
+ "anywhere": 8863,
+ "anz": 14445,
+ "anz": 19425,
+ "anza": 14669,
+ "anzac": 31977,
+ "ao": 7313,
+ "ao": 5703,
+ "aoa": 47119,
+ "aoc": 31918,
+ "aofficial": 30840,
+ "aoki": 33602,
+ "aol": 40643,
+ "aon": 30928,
+ "aon": 48476,
+ "aor": 32044,
+ "aos": 46860,
+ "ap": 688,
+ "ap": 2728,
+ "apa": 36954,
+ "apa": 13537,
+ "apac": 34320,
+ "apache": 23921,
+ "apal": 38017,
+ "apan": 36562,
+ "apar": 9161,
+ "apark": 32528,
+ "apart": 6474,
+ "apart": 7803,
+ "aparthe": 25121,
+ "apartheid": 26597,
+ "apartment": 8285,
+ "apartments": 15791,
+ "aparty": 26767,
+ "apat": 31755,
+ "apathy": 18145,
+ "apc": 20300,
+ "apd": 44563,
+ "ape": 6098,
+ "ape": 2609,
+ "apec": 47530,
+ "aper": 13681,
+ "aper": 5858,
+ "apers": 15846,
+ "apes": 9550,
+ "apeu": 19040,
+ "apex": 41935,
+ "apex": 23712,
+ "aph": 16341,
+ "aph": 29491,
+ "apha": 47104,
+ "apho": 21758,
+ "aphra": 44147,
+ "api": 23342,
+ "api": 14674,
+ "apia": 44259,
+ "apic": 40679,
+ "aping": 18456,
+ "apink": 35725,
+ "apis": 37575,
+ "apk": 27648,
+ "apo": 4089,
+ "apo": 19758,
+ "apocaly": 13932,
+ "apocalypse": 17571,
+ "apocalyptic": 35675,
+ "apol": 5023,
+ "apolice": 45663,
+ "apolis": 9598,
+ "apollo": 48213,
+ "apollo": 11554,
+ "apolo": 31094,
+ "apolog": 25530,
+ "apologe": 42908,
+ "apologi": 14977,
+ "apologies": 21959,
+ "apologise": 39608,
+ "apologize": 22879,
+ "apologizes": 35298,
+ "apology": 20768,
+ "apor": 21871,
+ "apore": 6679,
+ "apost": 20309,
+ "apostle": 33051,
+ "apostles": 48457,
+ "app": 882,
+ "app": 2231,
+ "appa": 4884,
+ "appa": 13110,
+ "appalach": 30523,
+ "appalachian": 36806,
+ "appalling": 44797,
+ "appar": 26698,
+ "apparatus": 37716,
+ "apparel": 13972,
+ "apparent": 23963,
+ "apparently": 5287,
+ "appe": 3748,
+ "appe": 45949,
+ "appeal": 9625,
+ "appealing": 25909,
+ "appeals": 22447,
+ "appear": 5544,
+ "appear": 9308,
+ "appearance": 7238,
+ "appearances": 17214,
+ "appeared": 11561,
+ "appearing": 18759,
+ "appears": 8743,
+ "appell": 43833,
+ "appen": 37201,
+ "appen": 26589,
+ "apper": 18780,
+ "appet": 21686,
+ "appeti": 24179,
+ "appetite": 24481,
+ "appetizer": 36065,
+ "applau": 24713,
+ "applaud": 42152,
+ "applause": 22650,
+ "apple": 8629,
+ "apple": 3055,
+ "applemusic": 21390,
+ "apples": 14032,
+ "appleton": 45250,
+ "appli": 15495,
+ "appliance": 33677,
+ "appliances": 22134,
+ "applic": 4235,
+ "applicable": 37927,
+ "applicants": 28035,
+ "application": 7241,
+ "applications": 7341,
+ "applied": 12636,
+ "applies": 24910,
+ "apply": 4356,
+ "applying": 17965,
+ "appo": 5433,
+ "appoint": 36190,
+ "appointed": 11087,
+ "appointment": 10890,
+ "appointments": 23439,
+ "appoints": 25132,
+ "apprais": 36972,
+ "appraisal": 46108,
+ "appreci": 3474,
+ "appreciate": 6263,
+ "appreciated": 9264,
+ "appreciates": 36573,
+ "appreciating": 39352,
+ "appreciation": 9212,
+ "appreciationday": 37438,
+ "appreciative": 45074,
+ "appren": 10582,
+ "apprentic": 15662,
+ "apprentice": 19122,
+ "apprentice": 17985,
+ "apprentices": 38252,
+ "apprenticeship": 26939,
+ "apprenticeships": 35425,
+ "appro": 2398,
+ "approach": 7781,
+ "approach": 6241,
+ "approached": 36499,
+ "approaches": 14962,
+ "approaching": 12164,
+ "appropri": 8446,
+ "appropriate": 10768,
+ "appropriately": 30383,
+ "appropriation": 49110,
+ "approval": 13549,
+ "approve": 19064,
+ "approved": 9412,
+ "approves": 18107,
+ "approx": 18266,
+ "approxim": 14201,
+ "approximately": 16128,
+ "apps": 7020,
+ "appstore": 31377,
+ "appt": 48112,
+ "appy": 34420,
+ "apr": 39396,
+ "apr": 11177,
+ "apra": 37027,
+ "apric": 25923,
+ "apricot": 30815,
+ "april": 23548,
+ "april": 2484,
+ "apro": 42712,
+ "apro": 49051,
+ "apron": 29502,
+ "aps": 8868,
+ "apse": 31843,
+ "apt": 17921,
+ "aptly": 47313,
+ "apu": 22166,
+ "apur": 36900,
+ "apur": 45193,
+ "aq": 14018,
+ "aq": 26862,
+ "aqu": 4458,
+ "aqua": 18613,
+ "aquaculture": 41885,
+ "aquaman": 35098,
+ "aquari": 37605,
+ "aquarium": 16814,
+ "aquarius": 38879,
+ "aquatic": 22658,
+ "aque": 35927,
+ "aque": 37268,
+ "aqui": 36826,
+ "aquino": 33796,
+ "ar": 516,
+ "ar": 625,
+ "ara": 24161,
+ "ara": 3340,
+ "arab": 5405,
+ "arab": 12028,
+ "arabia": 11746,
+ "arabian": 24663,
+ "arabic": 16709,
+ "arabs": 39155,
+ "arac": 47620,
+ "arach": 37689,
+ "arag": 41502,
+ "araj": 45142,
+ "arak": 23416,
+ "aram": 19223,
+ "aram": 21473,
+ "arama": 49066,
+ "aran": 20839,
+ "aran": 19641,
+ "aras": 36399,
+ "arat": 30856,
+ "arav": 35836,
+ "arbit": 20267,
+ "arbitr": 22702,
+ "arbitration": 34845,
+ "arbor": 33516,
+ "arbor": 24878,
+ "arboretum": 41719,
+ "arc": 4997,
+ "arc": 11592,
+ "arca": 25189,
+ "arca": 37612,
+ "arcade": 13331,
+ "arcadia": 38372,
+ "arch": 2458,
+ "arch": 8557,
+ "archa": 45619,
+ "archae": 10121,
+ "archaeological": 26163,
+ "archaeologists": 45035,
+ "archaeology": 14868,
+ "archan": 33359,
+ "archbishop": 23994,
+ "arche": 22474,
+ "archer": 21824,
+ "archers": 38407,
+ "archery": 23935,
+ "arches": 30771,
+ "archi": 4479,
+ "archie": 20557,
+ "archipel": 39750,
+ "archipelago": 43025,
+ "architec": 3359,
+ "architect": 12192,
+ "architects": 13290,
+ "architectural": 15360,
+ "architecture": 39038,
+ "architecture": 4920,
+ "archival": 39249,
+ "archive": 42257,
+ "archive": 10548,
+ "archived": 42379,
+ "archives": 9411,
+ "archy": 15643,
+ "arctic": 29716,
+ "arctic": 9138,
+ "ard": 3793,
+ "ard": 746,
+ "arden": 44600,
+ "arden": 27057,
+ "ardi": 23932,
+ "ardi": 19837,
+ "ardo": 35735,
+ "ardo": 9394,
+ "ards": 1654,
+ "ardu": 20906,
+ "arduino": 25398,
+ "are": 1076,
+ "are": 631,
+ "area": 2445,
+ "areas": 5429,
+ "arec": 18136,
+ "areclipse": 36030,
+ "ared": 5369,
+ "arel": 12798,
+ "arella": 24784,
+ "arelli": 48619,
+ "aren": 4033,
+ "aren": 4318,
+ "arena": 5463,
+ "arenas": 47860,
+ "arent": 37487,
+ "arer": 14857,
+ "arers": 33159,
+ "ares": 12224,
+ "arest": 11708,
+ "aret": 22247,
+ "areth": 47725,
+ "aretha": 42090,
+ "areyou": 37607,
+ "arez": 13108,
+ "arg": 27285,
+ "argent": 7812,
+ "argentina": 9789,
+ "argentine": 32582,
+ "argon": 40737,
+ "argos": 37443,
+ "argu": 7440,
+ "arguably": 30899,
+ "argue": 19788,
+ "argued": 48153,
+ "argues": 30045,
+ "arguing": 26549,
+ "argument": 16224,
+ "arguments": 24693,
+ "argus": 44300,
+ "argy": 21066,
+ "argyle": 36179,
+ "argyll": 40667,
+ "ari": 1221,
+ "ari": 3681,
+ "aria": 8883,
+ "arial": 42431,
+ "arian": 29980,
+ "arian": 6953,
+ "ariana": 14892,
+ "arianag": 23025,
+ "arianagrande": 23321,
+ "arianism": 44351,
+ "arians": 19104,
+ "arias": 22567,
+ "arie": 18774,
+ "ariel": 47959,
+ "ariel": 21025,
+ "aries": 5213,
+ "arif": 46621,
+ "arily": 12993,
+ "arin": 29564,
+ "arin": 18612,
+ "arina": 29271,
+ "arine": 29586,
+ "aring": 2142,
+ "ario": 8862,
+ "arios": 25392,
+ "aris": 15227,
+ "arise": 26490,
+ "arist": 12110,
+ "aristo": 25666,
+ "aristotle": 49156,
+ "arities": 31069,
+ "arity": 16608,
+ "arium": 11809,
+ "arius": 21482,
+ "ariz": 6516,
+ "arized": 40167,
+ "arizon": 28936,
+ "arizona": 7106,
+ "arjun": 24565,
+ "arjun": 20477,
+ "arjuna": 43835,
+ "ark": 11921,
+ "ark": 12010,
+ "arkansas": 12227,
+ "arkham": 36381,
+ "arl": 48542,
+ "arlington": 44940,
+ "arlington": 17865,
+ "arly": 3637,
+ "arm": 5671,
+ "arm": 4793,
+ "arma": 15887,
+ "arma": 38716,
+ "armad": 37897,
+ "armada": 34938,
+ "armagh": 44313,
+ "armani": 31314,
+ "armb": 37096,
+ "armchair": 45757,
+ "armed": 40471,
+ "armed": 8202,
+ "armen": 13145,
+ "armenia": 22008,
+ "armenian": 24891,
+ "armies": 46686,
+ "armin": 45481,
+ "arming": 19766,
+ "armist": 38150,
+ "armistice": 46765,
+ "armor": 16167,
+ "armored": 28214,
+ "armory": 38610,
+ "armour": 18503,
+ "armoured": 42514,
+ "arms": 5706,
+ "armstrong": 15005,
+ "army": 13541,
+ "army": 3133,
+ "armys": 27311,
+ "arn": 9348,
+ "arn": 37597,
+ "arnau": 45556,
+ "arne": 43509,
+ "arney": 35962,
+ "arnold": 49096,
+ "arnold": 13609,
+ "arns": 46692,
+ "aro": 7514,
+ "aro": 11551,
+ "aroa": 48209,
+ "arom": 16831,
+ "aroma": 40143,
+ "aroma": 26390,
+ "aromas": 47439,
+ "aromatherapy": 42584,
+ "aromatic": 39669,
+ "aron": 30855,
+ "aron": 28926,
+ "aroo": 47581,
+ "arora": 31897,
+ "arosa": 44264,
+ "arose": 44262,
+ "around": 35615,
+ "around": 1630,
+ "arqu": 35654,
+ "arquitec": 41703,
+ "arr": 39106,
+ "arr": 42489,
+ "arra": 32918,
+ "arra": 43827,
+ "arrahman": 44554,
+ "arran": 45722,
+ "arrang": 16711,
+ "arrange": 15410,
+ "arrange": 26311,
+ "arranged": 22451,
+ "arrangement": 23822,
+ "arrangements": 23792,
+ "arranging": 35321,
+ "array": 17293,
+ "arre": 4374,
+ "arrell": 28846,
+ "arrest": 9320,
+ "arrested": 5845,
+ "arresting": 43930,
+ "arrests": 20683,
+ "arri": 2115,
+ "arrival": 9073,
+ "arrivals": 19583,
+ "arrive": 8851,
+ "arrived": 3514,
+ "arrives": 9905,
+ "arriving": 10884,
+ "arro": 15729,
+ "arrog": 26997,
+ "arrogance": 47025,
+ "arrogant": 40582,
+ "arrow": 30920,
+ "arrow": 11149,
+ "arrowhead": 46393,
+ "arrows": 24768,
+ "arroyo": 45237,
+ "ars": 42815,
+ "ars": 864,
+ "arse": 22665,
+ "arsen": 5330,
+ "arsenal": 45234,
+ "arsenal": 6084,
+ "arsene": 32117,
+ "arson": 29937,
+ "art": 1486,
+ "art": 794,
+ "arta": 12031,
+ "arte": 13482,
+ "arte": 12947,
+ "artem": 40387,
+ "artemis": 45256,
+ "arten": 37043,
+ "arter": 29449,
+ "artery": 40062,
+ "artes": 48629,
+ "artforsale": 48239,
+ "artgallery": 31982,
+ "arth": 7146,
+ "arth": 20265,
+ "arthistory": 39313,
+ "arthr": 20807,
+ "arthritis": 22916,
+ "arthro": 43255,
+ "arthur": 35660,
+ "arthur": 8550,
+ "arti": 1635,
+ "arti": 34601,
+ "artic": 3003,
+ "articho": 30937,
+ "artichoke": 39647,
+ "article": 3550,
+ "articles": 11939,
+ "articul": 40343,
+ "articulate": 45444,
+ "artif": 8950,
+ "artifact": 37718,
+ "artifacts": 30249,
+ "artificial": 19357,
+ "artificial": 12040,
+ "artificialintelligence": 20799,
+ "artillery": 24465,
+ "artin": 33168,
+ "artin": 48540,
+ "artis": 41794,
+ "artisan": 36389,
+ "artisan": 21535,
+ "artisans": 40140,
+ "artist": 14326,
+ "artist": 2456,
+ "artiste": 41402,
+ "artistic": 12421,
+ "artiston": 48443,
+ "artistry": 38570,
+ "artists": 4899,
+ "artistson": 32127,
+ "artistsontwitter": 39469,
+ "artlovers": 35617,
+ "arto": 28464,
+ "artof": 31751,
+ "artoftheday": 43990,
+ "arton": 46744,
+ "arts": 22040,
+ "arts": 3812,
+ "artsy": 31588,
+ "arturo": 38591,
+ "artwit": 36713,
+ "artwork": 4188,
+ "artworks": 26215,
+ "arty": 45417,
+ "arty": 25916,
+ "aru": 13757,
+ "aru": 23907,
+ "aruba": 40131,
+ "arugula": 40770,
+ "arum": 48732,
+ "arun": 16105,
+ "arun": 31877,
+ "arunach": 47260,
+ "arunjaitley": 44874,
+ "arus": 22644,
+ "arvin": 16971,
+ "arvind": 21209,
+ "arvind": 41079,
+ "arvindkejriwal": 22971,
+ "arvo": 45726,
+ "arwx": 29824,
+ "ary": 4617,
+ "ary": 856,
+ "arya": 23594,
+ "aryan": 34966,
+ "as": 587,
+ "as": 601,
+ "asa": 39676,
+ "asa": 11914,
+ "asad": 42376,
+ "asaki": 22455,
+ "asam": 40603,
+ "asan": 22379,
+ "asan": 17841,
+ "asana": 42363,
+ "asant": 25536,
+ "asants": 37766,
+ "asap": 24199,
+ "asap": 10822,
+ "asar": 24733,
+ "asar": 49299,
+ "asb": 31186,
+ "asbe": 32113,
+ "asbestos": 33765,
+ "asc": 22720,
+ "asc": 23305,
+ "ascen": 20767,
+ "ascension": 35499,
+ "ascent": 36625,
+ "asci": 12753,
+ "asco": 25578,
+ "asco": 17488,
+ "ascot": 23723,
+ "ascri": 15506,
+ "asd": 36988,
+ "asda": 29391,
+ "asdf": 36857,
+ "asdfghj": 42758,
+ "asdfghjkl": 47660,
+ "ase": 8083,
+ "ase": 894,
+ "asean": 24472,
+ "aseball": 46903,
+ "ased": 2134,
+ "asen": 41085,
+ "aser": 39615,
+ "aser": 7209,
+ "ases": 3762,
+ "asf": 25863,
+ "asg": 34813,
+ "ash": 2067,
+ "ash": 2612,
+ "asha": 40572,
+ "asha": 13472,
+ "ashamed": 20633,
+ "ashby": 46531,
+ "ashe": 48523,
+ "ashe": 31752,
+ "asher": 37585,
+ "ashes": 12587,
+ "asheville": 28897,
+ "ashford": 37796,
+ "ashi": 15563,
+ "ashi": 15934,
+ "ashish": 33145,
+ "ashland": 39938,
+ "ashleigh": 49356,
+ "ashley": 17825,
+ "ashley": 8957,
+ "asho": 20273,
+ "ashok": 38141,
+ "ashore": 31194,
+ "ashram": 43445,
+ "ashton": 43264,
+ "ashton": 12228,
+ "ashtra": 18118,
+ "asi": 3596,
+ "asi": 12562,
+ "asia": 5741,
+ "asian": 21737,
+ "asian": 7128,
+ "asiangames": 49108,
+ "asians": 36771,
+ "asics": 31097,
+ "aside": 13676,
+ "asif": 37302,
+ "asim": 46050,
+ "asin": 48432,
+ "asin": 44347,
+ "asing": 4194,
+ "asingly": 15803,
+ "asion": 31753,
+ "asis": 12398,
+ "ask": 11027,
+ "ask": 2765,
+ "asked": 3993,
+ "asking": 5914,
+ "asks": 7953,
+ "asl": 41650,
+ "asleep": 10749,
+ "asley": 28206,
+ "asli": 44290,
+ "asm": 13851,
+ "asma": 38497,
+ "asmsg": 19839,
+ "aso": 30343,
+ "aso": 27932,
+ "asober": 43749,
+ "asocial": 48557,
+ "ason": 1163,
+ "asone": 31249,
+ "asons": 4249,
+ "asos": 37924,
+ "asot": 47968,
+ "asp": 17814,
+ "asp": 36666,
+ "asparag": 20301,
+ "asparagus": 20604,
+ "aspe": 10894,
+ "aspect": 19681,
+ "aspects": 18203,
+ "aspen": 35695,
+ "aspen": 25712,
+ "asper": 32991,
+ "asph": 28019,
+ "asphalt": 30574,
+ "aspir": 12669,
+ "aspirations": 36127,
+ "aspire": 24836,
+ "aspiring": 21862,
+ "asports": 43695,
+ "asr": 48052,
+ "asroma": 41000,
+ "ass": 12664,
+ "ass": 5301,
+ "assa": 47715,
+ "assad": 18699,
+ "assam": 19930,
+ "assan": 26352,
+ "assange": 27565,
+ "assas": 9603,
+ "assassin": 14366,
+ "assassin": 20029,
+ "assassinated": 40488,
+ "assassination": 24907,
+ "assassins": 34918,
+ "assassinscre": 36428,
+ "assassinscreed": 46082,
+ "assau": 7908,
+ "assaul": 19596,
+ "assault": 9679,
+ "assaulted": 30785,
+ "assaulting": 44143,
+ "asse": 3166,
+ "asse": 38600,
+ "assel": 37582,
+ "assemb": 5531,
+ "assemble": 26169,
+ "assembled": 22627,
+ "assemblies": 47406,
+ "assembling": 38670,
+ "assembly": 34542,
+ "assembly": 7059,
+ "assen": 38651,
+ "asser": 25665,
+ "asses": 21596,
+ "assess": 9209,
+ "assess": 23211,
+ "assessed": 44160,
+ "assessing": 31364,
+ "assessment": 10590,
+ "assessments": 32753,
+ "asset": 48463,
+ "asset": 13039,
+ "assets": 13170,
+ "assi": 2907,
+ "assi": 39540,
+ "assie": 31624,
+ "assign": 14190,
+ "assigned": 25767,
+ "assignment": 17342,
+ "assignments": 34257,
+ "assim": 36394,
+ "assimil": 43467,
+ "assist": 26558,
+ "assist": 10286,
+ "assistance": 11685,
+ "assistant": 6799,
+ "assistants": 31054,
+ "assisted": 18095,
+ "assisting": 24243,
+ "assists": 12675,
+ "assn": 44208,
+ "asso": 17617,
+ "assoc": 18891,
+ "associ": 3566,
+ "associate": 11777,
+ "associated": 11164,
+ "associates": 17358,
+ "association": 5578,
+ "associations": 33209,
+ "assor": 38604,
+ "assorted": 36701,
+ "assortment": 43112,
+ "asst": 24767,
+ "assu": 8328,
+ "assume": 19294,
+ "assumed": 37661,
+ "assuming": 29422,
+ "assump": 41182,
+ "assumption": 40773,
+ "assumptions": 45948,
+ "assurance": 28408,
+ "assure": 39161,
+ "assured": 25591,
+ "assures": 41988,
+ "assy": 29940,
+ "assy": 12963,
+ "ast": 1761,
+ "ast": 1242,
+ "asta": 43269,
+ "aste": 25033,
+ "aste": 25579,
+ "aster": 11013,
+ "aster": 9526,
+ "asteroid": 32253,
+ "asters": 33139,
+ "asth": 16684,
+ "asthma": 24610,
+ "asthour": 41238,
+ "astic": 15876,
+ "asting": 29984,
+ "astle": 46141,
+ "asto": 47275,
+ "aston": 24760,
+ "aston": 13879,
+ "astoni": 21962,
+ "astonishing": 27110,
+ "astonmartin": 40760,
+ "astor": 26391,
+ "astor": 47086,
+ "astoria": 34798,
+ "astounding": 37748,
+ "astr": 37609,
+ "astra": 47205,
+ "astra": 36079,
+ "astral": 45889,
+ "astri": 31243,
+ "astrid": 46499,
+ "astro": 8563,
+ "astro": 15318,
+ "astrology": 28526,
+ "astron": 7982,
+ "astronaut": 18376,
+ "astronauts": 29733,
+ "astronom": 23264,
+ "astronomer": 40036,
+ "astronomers": 44268,
+ "astronomical": 39775,
+ "astronomy": 17472,
+ "astrophotography": 38559,
+ "astros": 17598,
+ "asts": 10452,
+ "astu": 43137,
+ "astur": 45795,
+ "asu": 13157,
+ "asu": 16001,
+ "asun": 36044,
+ "asure": 3813,
+ "asus": 27269,
+ "aswell": 42978,
+ "asx": 38906,
+ "asy": 8524,
+ "asy": 2333,
+ "asylum": 15638,
+ "asym": 32539,
+ "at": 527,
+ "at": 536,
+ "ata": 4236,
+ "atable": 23909,
+ "atal": 24877,
+ "atal": 24797,
+ "atan": 33446,
+ "atar": 20128,
+ "atar": 7995,
+ "atari": 21549,
+ "atas": 30057,
+ "atay": 39518,
+ "atc": 28383,
+ "atch": 15938,
+ "atd": 33890,
+ "ate": 992,
+ "ate": 671,
+ "ateam": 42784,
+ "ateau": 16359,
+ "atec": 37352,
+ "atech": 31306,
+ "ated": 14589,
+ "ated": 943,
+ "atedly": 24698,
+ "atee": 32839,
+ "ateful": 5419,
+ "atelier": 29932,
+ "ately": 3862,
+ "atem": 17116,
+ "aten": 47984,
+ "atene": 30405,
+ "ateneo": 33904,
+ "ater": 18597,
+ "ater": 5877,
+ "ateral": 18819,
+ "aters": 22364,
+ "ates": 20370,
+ "ates": 1150,
+ "atest": 1705,
+ "ateur": 43677,
+ "atf": 28013,
+ "ath": 1374,
+ "ath": 1649,
+ "atha": 22530,
+ "atham": 23383,
+ "athan": 41260,
+ "athan": 26701,
+ "athe": 8963,
+ "athed": 47402,
+ "atheism": 25823,
+ "atheist": 22571,
+ "atheists": 47155,
+ "athen": 29112,
+ "athena": 30705,
+ "athens": 13524,
+ "ather": 6171,
+ "ather": 1817,
+ "athered": 34091,
+ "athers": 17266,
+ "athi": 28918,
+ "athing": 36069,
+ "athle": 3310,
+ "athlete": 7388,
+ "athletes": 7125,
+ "athletic": 33182,
+ "athletic": 9028,
+ "athletics": 7019,
+ "athlon": 14670,
+ "athome": 38217,
+ "athon": 4951,
+ "aths": 28835,
+ "athy": 34488,
+ "athy": 13183,
+ "ati": 591,
+ "ati": 6751,
+ "atia": 10908,
+ "atic": 20248,
+ "atic": 2647,
+ "atically": 13558,
+ "atics": 15666,
+ "atie": 30137,
+ "aties": 40060,
+ "atif": 41592,
+ "atiku": 37912,
+ "atile": 15474,
+ "atility": 23373,
+ "atime": 20158,
+ "atin": 36903,
+ "atin": 23047,
+ "atine": 39741,
+ "ating": 25653,
+ "ating": 1074,
+ "atio": 35401,
+ "ation": 2265,
+ "ation": 656,
+ "ational": 14205,
+ "ational": 3108,
+ "ationals": 44593,
+ "ationday": 20082,
+ "ations": 986,
+ "atis": 45456,
+ "atis": 41142,
+ "atism": 45638,
+ "ative": 18422,
+ "ative": 1648,
+ "atively": 11929,
+ "atives": 5629,
+ "ativity": 25166,
+ "atkins": 27734,
+ "atkinson": 28908,
+ "atl": 5411,
+ "atl": 10629,
+ "atla": 36043,
+ "atlan": 6818,
+ "atlanta": 39964,
+ "atlanta": 6839,
+ "atlantic": 28804,
+ "atlantic": 8189,
+ "atlantis": 27790,
+ "atlas": 15775,
+ "atle": 21170,
+ "atleast": 33231,
+ "atleti": 46067,
+ "atletico": 27501,
+ "atm": 14127,
+ "atmo": 8271,
+ "atmosphere": 10506,
+ "atmospheric": 24223,
+ "ato": 7987,
+ "ato": 4364,
+ "atoday": 26799,
+ "atom": 22418,
+ "atom": 24031,
+ "atomic": 18996,
+ "atoms": 41434,
+ "aton": 31525,
+ "aton": 10012,
+ "atop": 17455,
+ "ator": 10748,
+ "ator": 1962,
+ "atore": 28314,
+ "atorial": 32040,
+ "atories": 35678,
+ "atorium": 41306,
+ "ators": 3389,
+ "atory": 5920,
+ "atos": 41643,
+ "atour": 42967,
+ "atown": 24000,
+ "atp": 38105,
+ "atp": 19817,
+ "atr": 43247,
+ "atra": 20227,
+ "atra": 14401,
+ "atravel": 36981,
+ "atre": 46057,
+ "atri": 13882,
+ "atri": 38889,
+ "atric": 32238,
+ "atric": 13652,
+ "atrics": 36253,
+ "atrist": 41879,
+ "atrium": 29725,
+ "atrix": 43003,
+ "atro": 18724,
+ "atroc": 36197,
+ "atrocities": 37551,
+ "atry": 28334,
+ "ats": 46890,
+ "ats": 1032,
+ "atsu": 26531,
+ "att": 1017,
+ "att": 7103,
+ "atta": 7282,
+ "atta": 9146,
+ "attach": 43676,
+ "attach": 35653,
+ "attached": 11038,
+ "attachment": 28638,
+ "attack": 24971,
+ "attack": 3815,
+ "attacked": 12366,
+ "attacker": 39288,
+ "attackers": 47701,
+ "attacking": 16813,
+ "attacks": 7321,
+ "attain": 46459,
+ "attar": 37110,
+ "attemp": 4933,
+ "attempt": 7409,
+ "attempted": 17408,
+ "attempting": 18195,
+ "attempts": 15610,
+ "atten": 4084,
+ "atten": 32408,
+ "attenborough": 45860,
+ "attend": 9841,
+ "attend": 5802,
+ "attendance": 11928,
+ "attendant": 35424,
+ "attended": 8140,
+ "attendees": 14648,
+ "attending": 6696,
+ "attends": 22248,
+ "attention": 4936,
+ "atters": 30675,
+ "atthe": 21489,
+ "atti": 49265,
+ "atti": 16235,
+ "attic": 26766,
+ "attire": 21222,
+ "attitude": 10648,
+ "attitudes": 27611,
+ "attle": 14685,
+ "attle": 5030,
+ "attn": 25677,
+ "attor": 8856,
+ "attorney": 10372,
+ "attorneys": 29113,
+ "attrac": 7154,
+ "attract": 17010,
+ "attracted": 28493,
+ "attracting": 31909,
+ "attraction": 16807,
+ "attractions": 22307,
+ "attractive": 12231,
+ "attracts": 31024,
+ "attribu": 24624,
+ "attributed": 37520,
+ "attributes": 40763,
+ "attu": 43173,
+ "atty": 36705,
+ "atu": 15191,
+ "atu": 24295,
+ "atuesday": 34841,
+ "atul": 1744,
+ "atul": 43948,
+ "atum": 48295,
+ "atur": 14986,
+ "aturday": 29027,
+ "ature": 25305,
+ "ature": 4490,
+ "atures": 7358,
+ "atus": 14795,
+ "atv": 19598,
+ "atwood": 45680,
+ "atwork": 39680,
+ "atx": 34849,
+ "atx": 20136,
+ "aty": 40974,
+ "aty": 33107,
+ "atz": 30432,
+ "au": 627,
+ "au": 2566,
+ "aua": 45906,
+ "aub": 45938,
+ "auberg": 49382,
+ "aubre": 25899,
+ "aubrey": 34110,
+ "auburn": 42269,
+ "auburn": 14534,
+ "auc": 24489,
+ "auch": 43024,
+ "auck": 14588,
+ "auckland": 16072,
+ "auction": 48160,
+ "auction": 6462,
+ "auctioned": 41073,
+ "auctions": 24876,
+ "aucus": 47374,
+ "aud": 16107,
+ "aud": 19711,
+ "audi": 5091,
+ "audi": 10277,
+ "audible": 33227,
+ "audience": 6863,
+ "audiences": 22328,
+ "audio": 13792,
+ "audio": 5766,
+ "audiobook": 26282,
+ "audit": 12505,
+ "audit": 17625,
+ "auditi": 37377,
+ "audition": 18673,
+ "auditions": 21134,
+ "auditor": 38050,
+ "auditorium": 15063,
+ "audre": 16075,
+ "audrey": 18812,
+ "audu": 27934,
+ "audubon": 40275,
+ "auer": 33460,
+ "auf": 28924,
+ "aug": 15397,
+ "aug": 5720,
+ "auga": 22797,
+ "augh": 28310,
+ "augh": 14005,
+ "augmente": 48356,
+ "augmented": 32708,
+ "augu": 2610,
+ "august": 24353,
+ "august": 3171,
+ "augusta": 26144,
+ "augustine": 27397,
+ "augustus": 36835,
+ "auk": 19058,
+ "aul": 20695,
+ "aul": 34391,
+ "ault": 47253,
+ "ault": 10219,
+ "aun": 10608,
+ "aun": 38721,
+ "aunt": 12685,
+ "auntie": 23783,
+ "aunty": 29528,
+ "aur": 8156,
+ "aur": 17282,
+ "aura": 27728,
+ "aure": 36010,
+ "aureli": 35980,
+ "auror": 30067,
+ "aurora": 13500,
+ "aus": 10624,
+ "aus": 7630,
+ "ausa": 37384,
+ "ausbiz": 46543,
+ "ausch": 33926,
+ "auschwitz": 36523,
+ "ausopen": 27831,
+ "ausp": 35039,
+ "auspicious": 38806,
+ "auspol": 8241,
+ "aussi": 19762,
+ "aussie": 40230,
+ "aussie": 14424,
+ "aussies": 35727,
+ "aust": 26301,
+ "aust": 25418,
+ "austen": 29885,
+ "auster": 25030,
+ "austerity": 26982,
+ "austin": 12845,
+ "austin": 5125,
+ "austinmahone": 34678,
+ "austr": 2518,
+ "australi": 13798,
+ "australia": 3444,
+ "australian": 23630,
+ "australian": 6258,
+ "australians": 31488,
+ "austri": 8946,
+ "austria": 11960,
+ "austrian": 20638,
+ "ausv": 35206,
+ "ausvotes": 34661,
+ "aut": 12343,
+ "auth": 2381,
+ "auth": 38247,
+ "authent": 18158,
+ "authentic": 41266,
+ "authentic": 10369,
+ "authentication": 39746,
+ "authenticity": 35734,
+ "autho": 34552,
+ "author": 14447,
+ "author": 4358,
+ "authored": 37928,
+ "authori": 19207,
+ "authorities": 12729,
+ "authority": 10524,
+ "authorization": 48854,
+ "authorized": 28463,
+ "authors": 10765,
+ "auti": 8200,
+ "autism": 36256,
+ "autism": 11244,
+ "autisma": 43324,
+ "autistic": 29360,
+ "auto": 3917,
+ "auto": 5668,
+ "autobiography": 31509,
+ "autodesk": 40415,
+ "autograph": 10657,
+ "autograph": 13722,
+ "autographed": 16309,
+ "autographs": 17376,
+ "autoimmune": 45509,
+ "autom": 4114,
+ "automate": 43203,
+ "automated": 19022,
+ "automatic": 12126,
+ "automatically": 20725,
+ "automation": 12328,
+ "automobi": 44813,
+ "automobile": 25258,
+ "automotive": 12607,
+ "auton": 13100,
+ "autonews": 43975,
+ "autonom": 17870,
+ "autonomous": 20722,
+ "autonomy": 39223,
+ "autopsy": 44436,
+ "autos": 31118,
+ "autoshow": 46788,
+ "auts": 21140,
+ "autu": 5445,
+ "autum": 31783,
+ "autumn": 28940,
+ "autumn": 6110,
+ "autumnal": 35481,
+ "aux": 18154,
+ "aux": 8909,
+ "auxiliary": 37778,
+ "av": 722,
+ "av": 8484,
+ "ava": 12385,
+ "avage": 31505,
+ "avail": 1651,
+ "avail": 16686,
+ "availability": 17551,
+ "available": 1685,
+ "aval": 18012,
+ "avalan": 23970,
+ "avalanche": 25815,
+ "avalley": 45082,
+ "avalon": 30436,
+ "avan": 27971,
+ "avan": 33351,
+ "avant": 24305,
+ "avar": 33423,
+ "avatar": 18219,
+ "ave": 10062,
+ "ave": 4860,
+ "avec": 25828,
+ "aved": 47918,
+ "avel": 46817,
+ "avel": 48088,
+ "aven": 5963,
+ "aven": 32971,
+ "aveng": 21935,
+ "avenger": 24799,
+ "avengers": 39413,
+ "avengers": 12016,
+ "avengersendgame": 49342,
+ "avent": 22700,
+ "avenue": 7042,
+ "aver": 8788,
+ "aver": 11403,
+ "average": 6254,
+ "averaged": 37310,
+ "averages": 48982,
+ "averaging": 35266,
+ "avery": 20313,
+ "aves": 14023,
+ "avfc": 21304,
+ "avg": 19452,
+ "avgeek": 11114,
+ "avi": 3324,
+ "avi": 11297,
+ "avia": 38710,
+ "avian": 24115,
+ "aviation": 27717,
+ "aviation": 7617,
+ "aviator": 38921,
+ "aviators": 48011,
+ "avici": 46192,
+ "avicii": 49158,
+ "avid": 19118,
+ "avier": 14598,
+ "avila": 45339,
+ "aville": 40689,
+ "avin": 46204,
+ "avis": 45163,
+ "avis": 19765,
+ "aviv": 22130,
+ "aviva": 47122,
+ "aviz": 27607,
+ "avl": 44749,
+ "avo": 4496,
+ "avo": 32400,
+ "avoc": 12291,
+ "avocado": 14135,
+ "avocados": 48911,
+ "avoi": 16797,
+ "avoid": 30448,
+ "avoid": 5983,
+ "avoidance": 47983,
+ "avoided": 32103,
+ "avoiding": 22086,
+ "avoids": 48220,
+ "avon": 22790,
+ "avon": 17348,
+ "avril": 37763,
+ "avs": 31896,
+ "avut": 44472,
+ "avy": 29973,
+ "aw": 808,
+ "aw": 5557,
+ "awa": 4820,
+ "awa": 6872,
+ "await": 20769,
+ "awaited": 20092,
+ "awaiting": 14872,
+ "awaits": 15635,
+ "awak": 9776,
+ "awak": 41387,
+ "awake": 14695,
+ "awaken": 35412,
+ "awakening": 17017,
+ "awakens": 23191,
+ "awal": 42447,
+ "awal": 35090,
+ "awan": 48869,
+ "awan": 20420,
+ "awar": 5745,
+ "award": 36310,
+ "award": 2047,
+ "awarded": 7368,
+ "awarding": 37089,
+ "awards": 34528,
+ "awards": 2320,
+ "aware": 4427,
+ "aware": 7196,
+ "awareness": 19217,
+ "awareness": 4823,
+ "awarenessmonth": 34278,
+ "awarenessweek": 35294,
+ "away": 21088,
+ "away": 1520,
+ "aways": 12782,
+ "awaz": 18586,
+ "awd": 34846,
+ "awe": 1693,
+ "awe": 14106,
+ "aweather": 42142,
+ "aweather": 28681,
+ "awec": 38916,
+ "aweed": 29724,
+ "awesom": 16727,
+ "awesome": 30390,
+ "awesome": 1848,
+ "awesomeness": 22430,
+ "awful": 13617,
+ "awg": 46350,
+ "awgs": 35275,
+ "awh": 39566,
+ "awhile": 19171,
+ "awi": 15167,
+ "awil": 47271,
+ "awilliams": 42163,
+ "awk": 8888,
+ "awk": 40943,
+ "awkward": 42337,
+ "awkward": 10304,
+ "awn": 46222,
+ "awp": 43300,
+ "aws": 19658,
+ "awsome": 47196,
+ "awson": 36286,
+ "aww": 11568,
+ "awww": 15634,
+ "awwww": 26460,
+ "awx": 28385,
+ "ax": 3165,
+ "ax": 9203,
+ "axe": 19861,
+ "axel": 47889,
+ "axel": 32131,
+ "axes": 45970,
+ "axi": 30672,
+ "axial": 46550,
+ "axis": 19614,
+ "axle": 39003,
+ "axx": 47411,
+ "ay": 658,
+ "ay": 551,
+ "aya": 5917,
+ "ayala": 39827,
+ "ayama": 41194,
+ "ayan": 37781,
+ "ayan": 16269,
+ "ayana": 37400,
+ "ayas": 40904,
+ "ayat": 44902,
+ "ayat": 35720,
+ "aye": 21661,
+ "aye": 12446,
+ "ayer": 24852,
+ "ayers": 42783,
+ "ayesha": 46570,
+ "ayi": 33025,
+ "ayles": 44706,
+ "ayne": 35669,
+ "ayo": 21929,
+ "ayo": 18708,
+ "ayr": 23002,
+ "ayr": 36473,
+ "ayrshire": 32687,
+ "ays": 785,
+ "ayu": 40769,
+ "ayurve": 27185,
+ "ayurveda": 38986,
+ "ayush": 44831,
+ "ayy": 32514,
+ "ayyy": 41052,
+ "az": 854,
+ "az": 5468,
+ "aza": 22883,
+ "azad": 37838,
+ "azalea": 34087,
+ "azam": 34727,
+ "azar": 27911,
+ "azcardinals": 48846,
+ "aze": 41157,
+ "aze": 28485,
+ "azer": 19169,
+ "azerbai": 20649,
+ "azerbaijan": 23888,
+ "azhar": 47019,
+ "azi": 23914,
+ "azi": 18452,
+ "azine": 29140,
+ "azione": 48335,
+ "aziz": 41205,
+ "aziz": 29630,
+ "azo": 41227,
+ "azon": 36854,
+ "azores": 42826,
+ "azte": 33270,
+ "aztec": 34749,
+ "aztecs": 49387,
+ "azu": 27701,
+ "azu": 46963,
+ "azul": 39807,
+ "azure": 18514,
+ "azwx": 30262,
+ "azy": 24783,
+ "azz": 9817,
+ "azz": 26453,
+ "azza": 22255,
+ "azzi": 18758,
+ "azzle": 39974,
+ "azzo": 26779,
+ "azzur": 37055,
+ "azzy": 44534,
+ "añ": 23716,
+ "años": 41634,
+ "b": 65,
+ "b": 321,
+ "ba": 932,
+ "ba": 1792,
+ "baa": 33004,
+ "baahu": 34145,
+ "baahubali": 38663,
+ "bab": 1202,
+ "bab": 19039,
+ "baba": 12631,
+ "babe": 31177,
+ "babe": 7716,
+ "babes": 14253,
+ "babies": 6635,
+ "babs": 36217,
+ "babu": 21623,
+ "baby": 7268,
+ "baby": 1794,
+ "babygirl": 39554,
+ "babylon": 31928,
+ "babymetal": 45013,
+ "babys": 22266,
+ "babysitting": 34186,
+ "bac": 2791,
+ "bac": 25867,
+ "bacca": 40708,
+ "bach": 11773,
+ "bach": 8758,
+ "bachchan": 17690,
+ "bachel": 11283,
+ "bachelor": 45508,
+ "bachelor": 16766,
+ "bachelore": 26009,
+ "bachelorette": 29093,
+ "bacher": 49211,
+ "back": 1663,
+ "back": 893,
+ "backbone": 35635,
+ "backdrop": 20802,
+ "backed": 12721,
+ "backer": 22183,
+ "backers": 32934,
+ "background": 5994,
+ "backgrounds": 28215,
+ "backing": 14935,
+ "backlash": 31519,
+ "backpack": 14894,
+ "backpacking": 29524,
+ "backpacks": 37063,
+ "backs": 7562,
+ "backseat": 48812,
+ "backstage": 9236,
+ "backstreet": 46337,
+ "backthe": 26127,
+ "backto": 18703,
+ "backtoschool": 28730,
+ "backtothe": 43059,
+ "backup": 14415,
+ "backward": 37964,
+ "backwards": 21283,
+ "backyard": 12608,
+ "bacon": 48666,
+ "bacon": 7104,
+ "bacter": 11814,
+ "bacteria": 16556,
+ "bacterial": 26101,
+ "bad": 2564,
+ "bad": 2103,
+ "bada": 37475,
+ "badan": 39149,
+ "badass": 11616,
+ "baddest": 38112,
+ "baden": 36690,
+ "bader": 42254,
+ "badge": 11301,
+ "badger": 32686,
+ "badger": 22363,
+ "badgers": 22521,
+ "badges": 20084,
+ "badlands": 43192,
+ "badly": 13684,
+ "badminton": 21412,
+ "badoo": 33192,
+ "bados": 25755,
+ "bae": 32834,
+ "bae": 6855,
+ "baek": 18557,
+ "baek": 32702,
+ "baekhyun": 21572,
+ "baes": 46332,
+ "baf": 13616,
+ "baff": 35693,
+ "bafta": 29199,
+ "bag": 3408,
+ "bag": 3365,
+ "bage": 9698,
+ "bagel": 28777,
+ "bagels": 37489,
+ "baggage": 31402,
+ "bagged": 34047,
+ "bagh": 21659,
+ "bagh": 37271,
+ "baghdad": 30763,
+ "bago": 25105,
+ "bags": 6136,
+ "bagu": 27749,
+ "baguette": 45334,
+ "bah": 8372,
+ "bah": 16685,
+ "baha": 29592,
+ "baham": 43718,
+ "bahamas": 21224,
+ "bahan": 28704,
+ "bahn": 33452,
+ "bahrain": 12503,
+ "bai": 6232,
+ "bai": 23339,
+ "bail": 22933,
+ "bail": 16986,
+ "bailey": 27535,
+ "bailey": 10180,
+ "bain": 40784,
+ "bain": 21593,
+ "bair": 29059,
+ "baird": 40474,
+ "bait": 18010,
+ "baj": 20713,
+ "baja": 40418,
+ "baja": 28374,
+ "bajo": 32619,
+ "bak": 4059,
+ "bak": 23742,
+ "bakar": 41414,
+ "bake": 20736,
+ "bake": 11878,
+ "baked": 10364,
+ "baker": 27303,
+ "baker": 7743,
+ "bakers": 35293,
+ "bakers": 40231,
+ "bakersfield": 40149,
+ "bakery": 13377,
+ "bakes": 43057,
+ "bakhta": 44912,
+ "bakhtawar": 46937,
+ "bakhtawarbz": 47118,
+ "baking": 11467,
+ "baku": 46417,
+ "baku": 31852,
+ "bal": 1398,
+ "bal": 2282,
+ "bala": 20291,
+ "balaji": 48694,
+ "balance": 42894,
+ "balance": 6827,
+ "balanced": 15273,
+ "balances": 37733,
+ "balancing": 23541,
+ "balboa": 45098,
+ "balcony": 16169,
+ "bald": 11153,
+ "bald": 14875,
+ "baldhead": 29191,
+ "baldwin": 16242,
+ "bale": 48573,
+ "bale": 18873,
+ "bales": 42879,
+ "bali": 16432,
+ "bali": 10900,
+ "balkan": 48499,
+ "balkans": 42987,
+ "ball": 3807,
+ "ball": 1069,
+ "balla": 42246,
+ "ballad": 33472,
+ "ballarat": 46645,
+ "ballard": 31750,
+ "baller": 49194,
+ "baller": 25655,
+ "ballerina": 34962,
+ "ballers": 34173,
+ "ballet": 10703,
+ "balli": 29406,
+ "ballin": 47444,
+ "ballin": 33057,
+ "balling": 47588,
+ "ballis": 46675,
+ "ballistic": 36667,
+ "ballo": 8871,
+ "ballon": 36469,
+ "balloon": 13634,
+ "balloons": 18130,
+ "ballot": 14185,
+ "ballots": 35051,
+ "ballpark": 26080,
+ "ballroom": 15493,
+ "balls": 6927,
+ "bally": 17275,
+ "bally": 29451,
+ "balm": 24962,
+ "balmain": 45929,
+ "balo": 12395,
+ "baloch": 23173,
+ "balochistan": 21918,
+ "balot": 44615,
+ "balotelli": 45721,
+ "bals": 44154,
+ "balsam": 29121,
+ "balsamic": 32654,
+ "balt": 24441,
+ "balti": 8400,
+ "baltic": 23817,
+ "baltimore": 38502,
+ "baltimore": 9582,
+ "balu": 38093,
+ "bam": 6383,
+ "bam": 12686,
+ "bama": 20021,
+ "bambam": 34538,
+ "bambi": 46596,
+ "bamboo": 49322,
+ "bamboo": 16748,
+ "ban": 1159,
+ "ban": 2777,
+ "bana": 18428,
+ "banan": 38410,
+ "banana": 8922,
+ "bananas": 19121,
+ "banc": 39252,
+ "band": 4613,
+ "band": 1963,
+ "banda": 31865,
+ "bandai": 42054,
+ "bandana": 39265,
+ "bandcamp": 32229,
+ "banded": 37804,
+ "bandic": 44400,
+ "bandit": 27639,
+ "bandits": 33940,
+ "bandra": 41393,
+ "bands": 7858,
+ "bandung": 29512,
+ "bandwagon": 36432,
+ "bandwidth": 48859,
+ "bane": 9597,
+ "banerjee": 48102,
+ "banff": 29565,
+ "bang": 3524,
+ "bang": 6907,
+ "bangalore": 14697,
+ "banger": 24872,
+ "bangers": 38311,
+ "banging": 33033,
+ "bangkok": 12351,
+ "bangla": 10339,
+ "bangla": 45928,
+ "bangladesh": 11245,
+ "bangle": 37634,
+ "bangor": 31190,
+ "bangs": 27992,
+ "bangtan": 39131,
+ "bani": 19732,
+ "banjo": 27014,
+ "bank": 7061,
+ "bank": 2723,
+ "banker": 27316,
+ "bankers": 30599,
+ "bankholiday": 48868,
+ "banking": 9566,
+ "bankno": 49201,
+ "bankof": 39120,
+ "bankrup": 21904,
+ "bankrupt": 23077,
+ "bankrupt": 37288,
+ "bankruptcy": 23978,
+ "banks": 6367,
+ "banksy": 33350,
+ "bann": 5304,
+ "banned": 12012,
+ "banner": 9185,
+ "banners": 23145,
+ "banning": 26246,
+ "bannon": 29710,
+ "bano": 42947,
+ "banquet": 14254,
+ "bans": 15146,
+ "bant": 23301,
+ "bant": 46657,
+ "banter": 25535,
+ "bao": 39487,
+ "bao": 20408,
+ "bap": 7415,
+ "bap": 23754,
+ "bapti": 15477,
+ "baptism": 36765,
+ "baptist": 13274,
+ "baptiste": 45770,
+ "baptized": 45400,
+ "bar": 1040,
+ "bar": 2411,
+ "bara": 19345,
+ "barack": 18670,
+ "barack": 22481,
+ "barackobama": 18885,
+ "barak": 47419,
+ "barak": 16260,
+ "barang": 38446,
+ "barb": 24173,
+ "barb": 20913,
+ "barbados": 26992,
+ "barbar": 7906,
+ "barbara": 10937,
+ "barbarian": 42530,
+ "barbe": 18372,
+ "barbecue": 23501,
+ "barber": 19517,
+ "barber": 12296,
+ "barbershop": 37707,
+ "barbican": 47668,
+ "barbie": 16923,
+ "barca": 22942,
+ "barcel": 6134,
+ "barcelon": 47820,
+ "barcelona": 6412,
+ "barclay": 48877,
+ "barclay": 45276,
+ "barclays": 29538,
+ "bard": 39812,
+ "bard": 17514,
+ "bare": 16023,
+ "bare": 14318,
+ "barefoot": 30327,
+ "barely": 12684,
+ "bargain": 15076,
+ "bargaining": 41282,
+ "bargains": 34126,
+ "barge": 28272,
+ "bari": 21428,
+ "bari": 28016,
+ "barista": 31078,
+ "barit": 46300,
+ "bark": 32333,
+ "bark": 16560,
+ "barker": 20618,
+ "barking": 32676,
+ "barkley": 30266,
+ "barley": 22607,
+ "barlow": 25483,
+ "barn": 10490,
+ "barn": 10942,
+ "barnab": 43272,
+ "barnard": 44332,
+ "barne": 42527,
+ "barnes": 13102,
+ "barnet": 41943,
+ "barnett": 27650,
+ "barney": 24563,
+ "barns": 43759,
+ "barnsley": 37109,
+ "barnsley": 32153,
+ "baro": 17422,
+ "baro": 30817,
+ "baron": 48371,
+ "baron": 19349,
+ "baroness": 45056,
+ "barons": 45596,
+ "baroque": 25065,
+ "barr": 39473,
+ "barr": 22492,
+ "barra": 28442,
+ "barra": 33542,
+ "barrabest": 41376,
+ "barrac": 40835,
+ "barracks": 35822,
+ "barre": 13840,
+ "barre": 38257,
+ "barred": 33261,
+ "barrel": 11703,
+ "barrels": 22059,
+ "barren": 46743,
+ "barrett": 18701,
+ "barri": 8660,
+ "barric": 29189,
+ "barrie": 27090,
+ "barrier": 15706,
+ "barriers": 16321,
+ "barrington": 48954,
+ "barron": 34881,
+ "barrow": 42568,
+ "barrow": 24983,
+ "barry": 18028,
+ "barry": 8461,
+ "barrymore": 49310,
+ "bars": 8616,
+ "barstool": 44826,
+ "bart": 14838,
+ "bart": 12870,
+ "bartender": 33498,
+ "barthol": 48989,
+ "bartlett": 37130,
+ "bartol": 38209,
+ "barton": 48853,
+ "barton": 20345,
+ "baru": 16356,
+ "barun": 38278,
+ "barunsob": 41398,
+ "barça": 32788,
+ "bas": 1244,
+ "bas": 11420,
+ "basa": 26142,
+ "base": 2776,
+ "base": 4579,
+ "baseball": 23479,
+ "baseball": 3470,
+ "based": 35196,
+ "based": 2812,
+ "basel": 42803,
+ "basel": 20903,
+ "baseline": 40648,
+ "baseman": 45910,
+ "basement": 14792,
+ "bases": 20496,
+ "bash": 20462,
+ "bash": 10972,
+ "bashing": 37545,
+ "bashir": 42799,
+ "basic": 40452,
+ "basic": 7696,
+ "basically": 9125,
+ "basics": 15825,
+ "basil": 19225,
+ "basil": 14936,
+ "basilica": 27879,
+ "basin": 16117,
+ "basing": 47321,
+ "basis": 12278,
+ "baske": 3713,
+ "basket": 10338,
+ "basketball": 40023,
+ "basketball": 3835,
+ "baskets": 27787,
+ "basking": 39769,
+ "basque": 37175,
+ "bass": 22831,
+ "bass": 5992,
+ "bassett": 45992,
+ "bassist": 26496,
+ "bast": 28092,
+ "basti": 8559,
+ "bastille": 41874,
+ "bat": 2121,
+ "bat": 6575,
+ "bata": 39277,
+ "batb": 33962,
+ "batch": 9413,
+ "bate": 25034,
+ "bate": 28277,
+ "bateman": 41635,
+ "bates": 21727,
+ "batgirl": 46460,
+ "bath": 6064,
+ "bath": 5713,
+ "bathing": 20144,
+ "bathro": 21201,
+ "bathroom": 8470,
+ "bathrooms": 26434,
+ "baths": 19442,
+ "bathtub": 39942,
+ "bathurst": 36365,
+ "bati": 23362,
+ "bati": 37589,
+ "batman": 27811,
+ "batman": 7223,
+ "baton": 24331,
+ "bats": 14984,
+ "batsman": 35432,
+ "batt": 2407,
+ "batt": 48595,
+ "battalion": 20820,
+ "batter": 12654,
+ "batter": 31855,
+ "battered": 34375,
+ "batteries": 16666,
+ "battersea": 35839,
+ "battery": 7870,
+ "batting": 17401,
+ "battle": 7344,
+ "battle": 3528,
+ "battled": 37837,
+ "battlefield": 16055,
+ "battlefront": 42214,
+ "battleof": 47560,
+ "battles": 14213,
+ "battleship": 35165,
+ "battling": 17268,
+ "bau": 6055,
+ "bau": 34840,
+ "bauer": 22903,
+ "baugh": 41301,
+ "baum": 19840,
+ "bautista": 31881,
+ "bav": 21075,
+ "bavaria": 39977,
+ "bavarian": 44458,
+ "baw": 19808,
+ "bax": 21216,
+ "baxter": 26168,
+ "bay": 3631,
+ "bay": 2174,
+ "baya": 31573,
+ "bayan": 43895,
+ "bayarea": 28260,
+ "bayer": 48548,
+ "bayer": 29183,
+ "bayern": 14666,
+ "baylor": 21721,
+ "bayou": 33955,
+ "bays": 40156,
+ "baz": 10430,
+ "baz": 25268,
+ "bazaar": 20070,
+ "bazar": 49298,
+ "bb": 1174,
+ "bb": 3529,
+ "bba": 27762,
+ "bball": 15664,
+ "bbb": 33535,
+ "bbc": 5123,
+ "bbc": 5188,
+ "bbcc": 39052,
+ "bbce": 33818,
+ "bbcnews": 29370,
+ "bbcone": 28259,
+ "bbcqt": 37343,
+ "bbcr": 35802,
+ "bbcra": 17115,
+ "bbcradi": 49213,
+ "bbcradio": 22876,
+ "bbcsport": 49321,
+ "bbcspringwatch": 37358,
+ "bbctwo": 40395,
+ "bbcworld": 47340,
+ "bbe": 37559,
+ "bbed": 9077,
+ "bber": 7933,
+ "bbers": 36494,
+ "bbhutto": 28085,
+ "bbhuttozardari": 28135,
+ "bbi": 37047,
+ "bbin": 38553,
+ "bbing": 9787,
+ "bbins": 42504,
+ "bbl": 21961,
+ "bble": 26570,
+ "bble": 5924,
+ "bbled": 37626,
+ "bbles": 18093,
+ "bblo": 21231,
+ "bbloggers": 26614,
+ "bbly": 43031,
+ "bbm": 25382,
+ "bbmas": 22145,
+ "bbn": 28427,
+ "bbnaija": 20984,
+ "bbo": 21892,
+ "bbq": 41270,
+ "bbq": 6726,
+ "bbs": 10002,
+ "bbuk": 45978,
+ "bby": 11166,
+ "bby": 3810,
+ "bc": 3116,
+ "bc": 2162,
+ "bcc": 41509,
+ "bcci": 36138,
+ "bce": 36510,
+ "bcfc": 34359,
+ "bch": 36684,
+ "bcn": 25766,
+ "bcoz": 46373,
+ "bcpoli": 24389,
+ "bcs": 24909,
+ "bcu": 28299,
+ "bd": 24358,
+ "bd": 11165,
+ "bday": 33022,
+ "bday": 5781,
+ "bdg": 48418,
+ "bds": 26732,
+ "be": 571,
+ "be": 655,
+ "bea": 21886,
+ "bea": 20925,
+ "beach": 6068,
+ "beach": 2117,
+ "beaches": 12183,
+ "beachlife": 43824,
+ "beacon": 36883,
+ "beacon": 18858,
+ "beacons": 39395,
+ "bead": 31621,
+ "bead": 23557,
+ "beaded": 26661,
+ "beads": 14099,
+ "beagle": 30044,
+ "beak": 36498,
+ "beal": 45769,
+ "beale": 39717,
+ "beam": 35339,
+ "beam": 13663,
+ "beams": 23993,
+ "bean": 16471,
+ "bean": 5328,
+ "beanie": 21534,
+ "beans": 8302,
+ "bear": 6375,
+ "bear": 4298,
+ "bearable": 38608,
+ "bearcats": 33242,
+ "beard": 26157,
+ "beard": 9052,
+ "bearded": 28459,
+ "beardown": 43687,
+ "beards": 33020,
+ "bearer": 30686,
+ "bearers": 47986,
+ "bearing": 18370,
+ "bearings": 42083,
+ "bearish": 34829,
+ "bears": 6182,
+ "beasley": 43349,
+ "beast": 20847,
+ "beast": 6957,
+ "beastmode": 43076,
+ "beasts": 21771,
+ "beat": 3774,
+ "beat": 3018,
+ "beaten": 10864,
+ "beater": 41974,
+ "beati": 44386,
+ "beating": 10078,
+ "beatles": 11961,
+ "beatport": 31421,
+ "beatrice": 36922,
+ "beats": 6289,
+ "beatthe": 40550,
+ "beatty": 39903,
+ "beatz": 33363,
+ "beau": 1016,
+ "beau": 14298,
+ "beaufort": 45423,
+ "beaumont": 32857,
+ "beaut": 24559,
+ "beauti": 1154,
+ "beauties": 14874,
+ "beautiful": 13662,
+ "beautiful": 1215,
+ "beautifully": 10627,
+ "beauty": 12881,
+ "beauty": 2488,
+ "beav": 23260,
+ "beaver": 26432,
+ "beaver": 22874,
+ "beavers": 34513,
+ "beavs": 43909,
+ "bebe": 23331,
+ "bec": 6899,
+ "bec": 10773,
+ "became": 5464,
+ "because": 32714,
+ "because": 1631,
+ "becca": 27088,
+ "bech": 44055,
+ "beck": 8256,
+ "beck": 10396,
+ "becker": 26918,
+ "beckett": 27249,
+ "beckham": 18764,
+ "becky": 32406,
+ "becky": 18921,
+ "become": 2989,
+ "becomes": 6766,
+ "becoming": 6208,
+ "bed": 4152,
+ "bed": 2722,
+ "bedding": 31761,
+ "bedford": 20779,
+ "bedi": 39181,
+ "bedro": 18415,
+ "bedroom": 8411,
+ "bedrooms": 23996,
+ "beds": 13914,
+ "bedside": 47473,
+ "bedtime": 22115,
+ "bee": 6097,
+ "bee": 5028,
+ "beech": 32733,
+ "beech": 27596,
+ "beef": 21703,
+ "beef": 6529,
+ "beek": 37915,
+ "been": 33986,
+ "been": 1025,
+ "beep": 33432,
+ "beer": 8885,
+ "beer": 2544,
+ "beers": 10907,
+ "bees": 36249,
+ "bees": 9100,
+ "beet": 12582,
+ "beet": 28621,
+ "beethoven": 23656,
+ "beetle": 16534,
+ "beetles": 36317,
+ "beetro": 29251,
+ "beetroot": 31638,
+ "beets": 36087,
+ "before": 20898,
+ "before": 1348,
+ "beg": 2219,
+ "beg": 22401,
+ "began": 8636,
+ "begg": 36769,
+ "begging": 25371,
+ "begin": 19197,
+ "begin": 4947,
+ "beginner": 24351,
+ "beginners": 21930,
+ "beginning": 5791,
+ "beginnings": 22581,
+ "begins": 4635,
+ "begs": 43531,
+ "begun": 10514,
+ "beh": 21971,
+ "beh": 41612,
+ "beha": 5737,
+ "behalf": 11470,
+ "behave": 28825,
+ "behaved": 41617,
+ "behavi": 6149,
+ "behaving": 40745,
+ "behavior": 10461,
+ "behavioral": 25135,
+ "behaviors": 37741,
+ "behaviour": 14655,
+ "behavioural": 46019,
+ "behe": 42329,
+ "behin": 2335,
+ "behind": 2403,
+ "behindthe": 21104,
+ "behindthescenes": 26253,
+ "behold": 15929,
+ "bei": 38991,
+ "bei": 23227,
+ "beige": 26677,
+ "beij": 11547,
+ "beijing": 11796,
+ "bein": 39117,
+ "bein": 24168,
+ "being": 13481,
+ "being": 1265,
+ "beings": 17998,
+ "beingsalmankhan": 19637,
+ "beir": 20176,
+ "beirut": 22352,
+ "beit": 26963,
+ "bek": 46846,
+ "bek": 26135,
+ "bekind": 46691,
+ "bel": 1308,
+ "bel": 3543,
+ "bela": 30555,
+ "belarus": 30849,
+ "belated": 20256,
+ "belfast": 35100,
+ "belfast": 10015,
+ "belgi": 7001,
+ "belgian": 15008,
+ "belgium": 10239,
+ "belgrade": 30502,
+ "beli": 1859,
+ "beli": 45842,
+ "belichick": 46132,
+ "belie": 20854,
+ "beliebers": 27714,
+ "belief": 14802,
+ "beliefs": 20575,
+ "believ": 4972,
+ "believe": 15819,
+ "believe": 2649,
+ "believed": 13380,
+ "believein": 24294,
+ "believeinfilm": 37375,
+ "believer": 26057,
+ "believers": 28434,
+ "believes": 12017,
+ "believing": 19551,
+ "belinda": 44415,
+ "belize": 27990,
+ "bell": 5417,
+ "bell": 3718,
+ "bella": 18282,
+ "bella": 10418,
+ "bellamy": 34461,
+ "bellator": 31985,
+ "belle": 13587,
+ "belle": 11496,
+ "belles": 40678,
+ "bellevue": 32715,
+ "belli": 43335,
+ "bellletstalk": 42695,
+ "bello": 21954,
+ "bells": 12811,
+ "bellum": 35493,
+ "belly": 25901,
+ "belly": 10404,
+ "belmont": 25612,
+ "belo": 8379,
+ "belo": 41649,
+ "belong": 16453,
+ "belong": 13596,
+ "belonged": 39893,
+ "belonging": 28193,
+ "belongs": 14395,
+ "beloved": 9363,
+ "below": 3788,
+ "bels": 43127,
+ "belt": 36416,
+ "belt": 7373,
+ "belts": 21888,
+ "belvedere": 48003,
+ "ben": 1465,
+ "ben": 3518,
+ "bena": 46249,
+ "bench": 17770,
+ "bench": 8771,
+ "benches": 36349,
+ "benchmark": 31775,
+ "bend": 22100,
+ "bend": 13332,
+ "bender": 22551,
+ "bendigo": 48197,
+ "bending": 33897,
+ "bene": 12091,
+ "bene": 47151,
+ "beneath": 16850,
+ "bened": 13216,
+ "benedic": 24402,
+ "benedict": 47896,
+ "benedict": 18027,
+ "benef": 3260,
+ "benefici": 38593,
+ "beneficial": 24660,
+ "beneficiaries": 42160,
+ "benefit": 6399,
+ "benefited": 48266,
+ "benefiting": 29474,
+ "benefits": 5465,
+ "benefitting": 47222,
+ "benevol": 47060,
+ "benfica": 33873,
+ "beng": 6962,
+ "bengal": 17404,
+ "bengal": 16374,
+ "bengali": 33774,
+ "bengals": 23737,
+ "bengaluru": 21707,
+ "benghazi": 25967,
+ "benin": 40296,
+ "benitez": 46711,
+ "benjam": 10550,
+ "benjamin": 38647,
+ "benjamin": 12131,
+ "benji": 43548,
+ "benn": 39097,
+ "bennet": 48536,
+ "bennett": 12186,
+ "benny": 42369,
+ "benny": 20595,
+ "beno": 35268,
+ "benoit": 44373,
+ "benson": 19578,
+ "bent": 9809,
+ "bent": 18369,
+ "bentley": 16859,
+ "benton": 30812,
+ "benz": 27937,
+ "benz": 13470,
+ "ber": 867,
+ "ber": 1516,
+ "bera": 32802,
+ "bere": 17458,
+ "bered": 9193,
+ "beren": 33654,
+ "beret": 41658,
+ "berg": 12022,
+ "berg": 3294,
+ "bergen": 22918,
+ "berger": 35933,
+ "berger": 13873,
+ "bergh": 35120,
+ "bergman": 42597,
+ "bergs": 43592,
+ "berk": 15633,
+ "berke": 14639,
+ "berkeley": 46049,
+ "berkeley": 16667,
+ "berkshire": 27300,
+ "berlin": 23532,
+ "berlin": 5891,
+ "berman": 21514,
+ "bermu": 21032,
+ "bermuda": 24644,
+ "bern": 9195,
+ "bern": 18382,
+ "bernade": 46242,
+ "bernar": 11962,
+ "bernard": 14579,
+ "bernardino": 35328,
+ "bernardo": 27137,
+ "bernardo": 28696,
+ "bernardokath": 29081,
+ "bernat": 40578,
+ "berni": 18798,
+ "bernie": 40093,
+ "bernie": 10503,
+ "berniesanders": 23745,
+ "bernstein": 33936,
+ "berra": 15089,
+ "berries": 8319,
+ "berry": 15334,
+ "berry": 3488,
+ "bers": 6408,
+ "berser": 39037,
+ "bert": 17340,
+ "bert": 2358,
+ "berta": 45187,
+ "berth": 28317,
+ "bertie": 47182,
+ "berto": 34073,
+ "bertr": 36962,
+ "bertrand": 41594,
+ "berts": 30205,
+ "berty": 35973,
+ "berwick": 40407,
+ "bery": 11411,
+ "bes": 26911,
+ "bes": 3635,
+ "beside": 13519,
+ "besides": 17596,
+ "bespoke": 15612,
+ "bess": 43791,
+ "best": 3419,
+ "best": 949,
+ "bestbuy": 29749,
+ "bestest": 31199,
+ "bestfan": 23880,
+ "bestfanarmy": 24590,
+ "bestfriend": 29832,
+ "bestfriend": 11856,
+ "bestfriends": 23555,
+ "besti": 35210,
+ "bestie": 17188,
+ "besties": 27346,
+ "besto": 28615,
+ "bestof": 27892,
+ "bestof": 39533,
+ "bestseller": 25841,
+ "bestselling": 28632,
+ "bet": 1051,
+ "bet": 4430,
+ "beta": 43188,
+ "beta": 9505,
+ "betes": 10255,
+ "beth": 9993,
+ "beth": 4892,
+ "bethan": 18781,
+ "bethany": 39130,
+ "bethany": 27952,
+ "bethe": 12624,
+ "bethel": 33410,
+ "bethesda": 32527,
+ "bethle": 30760,
+ "bethlehem": 31827,
+ "betis": 45590,
+ "beto": 33721,
+ "betra": 18436,
+ "betrayal": 33171,
+ "betrayed": 35692,
+ "bets": 17107,
+ "betsy": 28946,
+ "bett": 17715,
+ "bett": 20489,
+ "betta": 36387,
+ "bette": 35855,
+ "better": 10320,
+ "better": 1539,
+ "bettertogether": 47392,
+ "betting": 14319,
+ "betts": 38637,
+ "betty": 36175,
+ "betty": 14350,
+ "between": 1957,
+ "beu": 38660,
+ "bev": 40324,
+ "bev": 30968,
+ "bever": 9924,
+ "beverage": 18694,
+ "beverages": 28521,
+ "beverley": 39165,
+ "beverly": 30906,
+ "beverly": 16728,
+ "beverlyhills": 45363,
+ "beware": 14532,
+ "bewithyou": 36787,
+ "bex": 18676,
+ "bex": 24748,
+ "bexhill": 49200,
+ "bey": 3234,
+ "bey": 6767,
+ "beyon": 11447,
+ "beyonce": 16632,
+ "beyoncé": 19219,
+ "beyond": 22246,
+ "beyond": 4432,
+ "bez": 28592,
+ "bez": 46764,
+ "bezos": 45000,
+ "bf": 19858,
+ "bf": 7990,
+ "bfc": 37183,
+ "bff": 11984,
+ "bffs": 31462,
+ "bfi": 34244,
+ "bg": 16674,
+ "bg": 11295,
+ "bgc": 47598,
+ "bgs": 47963,
+ "bgt": 40665,
+ "bh": 9930,
+ "bh": 13603,
+ "bha": 6144,
+ "bha": 33068,
+ "bhafc": 30779,
+ "bhagat": 49136,
+ "bhai": 48370,
+ "bhai": 20508,
+ "bhak": 34501,
+ "bham": 31874,
+ "bham": 23491,
+ "bhan": 27356,
+ "bhand": 48679,
+ "bhar": 9108,
+ "bharat": 27454,
+ "bharat": 17430,
+ "bharti": 46803,
+ "bhat": 23784,
+ "bhatt": 36143,
+ "bhav": 44950,
+ "bhi": 28943,
+ "bhi": 21955,
+ "bhk": 45070,
+ "bhm": 38741,
+ "bho": 19721,
+ "bhopal": 44573,
+ "bhp": 29776,
+ "bhs": 29195,
+ "bhu": 9172,
+ "bhuban": 38729,
+ "bhubanes": 41213,
+ "bhubaneswar": 45888,
+ "bhushan": 40884,
+ "bhutan": 32391,
+ "bhutto": 30153,
+ "bi": 717,
+ "bi": 3035,
+ "bia": 3841,
+ "biaf": 26961,
+ "biafra": 36355,
+ "bian": 19531,
+ "bian": 9027,
+ "bianca": 25854,
+ "bianchi": 45720,
+ "bians": 28141,
+ "bias": 11268,
+ "biased": 22178,
+ "bib": 44607,
+ "bib": 21022,
+ "bibi": 31182,
+ "bibl": 20912,
+ "bible": 26738,
+ "bible": 7583,
+ "bibli": 23465,
+ "biblical": 22841,
+ "biblio": 49131,
+ "bic": 5960,
+ "bic": 10675,
+ "bice": 35589,
+ "biceps": 46735,
+ "bick": 27238,
+ "bicy": 9247,
+ "bicycle": 11652,
+ "bicycles": 31326,
+ "bid": 21035,
+ "bid": 5553,
+ "bidding": 23237,
+ "bide": 45178,
+ "biden": 19451,
+ "bids": 16148,
+ "bie": 5561,
+ "bie": 4173,
+ "bieber": 48725,
+ "bieber": 7535,
+ "bien": 19176,
+ "bien": 25742,
+ "biennale": 33776,
+ "biennial": 36609,
+ "bier": 27226,
+ "bier": 23508,
+ "bies": 7867,
+ "big": 1915,
+ "big": 1205,
+ "bigbaldhead": 30325,
+ "bigbang": 41680,
+ "bigbang": 23734,
+ "bigdata": 9440,
+ "bige": 37762,
+ "bigfoot": 37095,
+ "bigg": 15312,
+ "bigg": 35399,
+ "biggboss": 27056,
+ "bigger": 6806,
+ "biggest": 19483,
+ "biggest": 3505,
+ "biggie": 28392,
+ "biggs": 46507,
+ "bigh": 18106,
+ "bighit": 35508,
+ "bigo": 14278,
+ "bigolive": 20735,
+ "bigotry": 37269,
+ "bigre": 36330,
+ "bih": 33471,
+ "bihar": 22849,
+ "bij": 42478,
+ "bik": 30306,
+ "bike": 11686,
+ "bike": 3701,
+ "biker": 36100,
+ "biker": 23449,
+ "bikers": 29468,
+ "bikes": 9227,
+ "bikin": 12638,
+ "biking": 19157,
+ "bikini": 14531,
+ "bil": 3092,
+ "bil": 20506,
+ "bilateral": 25599,
+ "bilbao": 34802,
+ "bild": 35512,
+ "bile": 25943,
+ "bilingual": 29623,
+ "bilities": 13582,
+ "bility": 4694,
+ "bill": 4444,
+ "bill": 2886,
+ "billboard": 10856,
+ "billboards": 34741,
+ "billed": 37558,
+ "billi": 7693,
+ "billie": 23990,
+ "billing": 31797,
+ "billings": 43615,
+ "billion": 14520,
+ "billion": 5729,
+ "billionaire": 19475,
+ "billionaires": 41590,
+ "billions": 20742,
+ "bills": 9810,
+ "billsmafia": 48845,
+ "billy": 15626,
+ "billy": 6814,
+ "bilt": 44770,
+ "bilt": 26654,
+ "bim": 46737,
+ "bim": 24775,
+ "bin": 4849,
+ "bin": 5346,
+ "binance": 43520,
+ "binary": 23497,
+ "bind": 44513,
+ "binder": 30541,
+ "binding": 21287,
+ "bine": 34848,
+ "bing": 24818,
+ "bing": 5665,
+ "binge": 22600,
+ "bingham": 43785,
+ "bingham": 47296,
+ "bingo": 18418,
+ "bino": 29172,
+ "bino": 24313,
+ "bins": 26934,
+ "bint": 43647,
+ "bio": 2830,
+ "bio": 5162,
+ "biode": 43502,
+ "biodegradable": 47740,
+ "biodiversity": 17428,
+ "biof": 45158,
+ "biographical": 49232,
+ "biography": 15423,
+ "biological": 18821,
+ "biologist": 35149,
+ "biology": 9796,
+ "biom": 13010,
+ "biomar": 44549,
+ "biomass": 36746,
+ "biome": 26218,
+ "biomed": 29280,
+ "biomedical": 33117,
+ "bionic": 46201,
+ "biop": 15009,
+ "biopic": 27942,
+ "bios": 48505,
+ "biotech": 22514,
+ "biotechnology": 40375,
+ "biotic": 33773,
+ "biotics": 41371,
+ "bious": 31845,
+ "bipartisan": 32266,
+ "bipolar": 37097,
+ "bique": 27809,
+ "bir": 921,
+ "bir": 16284,
+ "birch": 31569,
+ "birch": 22907,
+ "bird": 6908,
+ "bird": 3329,
+ "birdie": 29612,
+ "birdies": 45618,
+ "birding": 15851,
+ "birdman": 41915,
+ "birdphotography": 47999,
+ "birds": 41951,
+ "birds": 4337,
+ "birdwatching": 33497,
+ "birk": 48289,
+ "birken": 40661,
+ "birmin": 37482,
+ "birmingham": 38580,
+ "birmingham": 7720,
+ "birth": 1128,
+ "birth": 5397,
+ "birthday": 7381,
+ "birthday": 1166,
+ "birthdays": 17954,
+ "birthplace": 31429,
+ "biryani": 46489,
+ "bis": 5064,
+ "bis": 14461,
+ "biscu": 11532,
+ "biscuit": 18731,
+ "biscuits": 18248,
+ "bisexual": 36829,
+ "bish": 33690,
+ "bish": 31461,
+ "bishop": 20625,
+ "bishop": 8024,
+ "bishops": 31579,
+ "bison": 19741,
+ "bistro": 21770,
+ "bit": 3010,
+ "bit": 2010,
+ "bitcoin": 30848,
+ "bitcoin": 6366,
+ "bite": 41613,
+ "biting": 23016,
+ "bits": 7747,
+ "bitt": 39251,
+ "bius": 45525,
+ "bix": 46579,
+ "biz": 8212,
+ "biz": 5431,
+ "biza": 47013,
+ "bizar": 14886,
+ "bizarre": 16965,
+ "bizhour": 39462,
+ "bizitalk": 34929,
+ "bj": 4592,
+ "bj": 18229,
+ "bjj": 27437,
+ "bjor": 26525,
+ "bjp": 37264,
+ "bjp": 6178,
+ "bk": 15099,
+ "bk": 14083,
+ "bkk": 36433,
+ "bl": 833,
+ "bl": 9467,
+ "bla": 2205,
+ "bla": 19630,
+ "blac": 21008,
+ "black": 2025,
+ "black": 1449,
+ "blackand": 12809,
+ "blackandwhite": 23688,
+ "blackandwhite": 19506,
+ "blackandwhitephotography": 27544,
+ "blackberry": 16470,
+ "blackbird": 38526,
+ "blackburn": 23789,
+ "blackfish": 42193,
+ "blackfriday": 16445,
+ "blackgirl": 43591,
+ "blackhawks": 19203,
+ "blackhistory": 46982,
+ "blackhistorymonth": 20135,
+ "blacklist": 30295,
+ "blacklivesmatter": 23467,
+ "blackmail": 47295,
+ "blackops": 43519,
+ "blackout": 21733,
+ "blackpanther": 36592,
+ "blackpink": 20339,
+ "blackpool": 21031,
+ "blacks": 16351,
+ "blackwell": 42642,
+ "blad": 36635,
+ "bladder": 33593,
+ "blade": 10264,
+ "blades": 16893,
+ "blah": 29212,
+ "blaine": 32457,
+ "blair": 31824,
+ "blair": 14749,
+ "blake": 20229,
+ "blake": 9579,
+ "blame": 10695,
+ "blamed": 32906,
+ "blames": 27841,
+ "blaming": 29287,
+ "blan": 4609,
+ "blanc": 30936,
+ "blanc": 13301,
+ "blanca": 40670,
+ "blanchard": 40177,
+ "blanche": 34875,
+ "blanchett": 49378,
+ "blanco": 26801,
+ "bland": 44372,
+ "bland": 30799,
+ "blank": 15134,
+ "blanket": 12878,
+ "blankets": 24042,
+ "blanks": 48599,
+ "blasio": 35553,
+ "blasphe": 36622,
+ "blast": 46349,
+ "blast": 5964,
+ "blasted": 38976,
+ "blaster": 36341,
+ "blasting": 26178,
+ "blasts": 23067,
+ "blat": 22048,
+ "blatant": 41391,
+ "blatt": 39138,
+ "blau": 45307,
+ "blaz": 43413,
+ "blaze": 15497,
+ "blazer": 17606,
+ "blazers": 16984,
+ "blazing": 25267,
+ "bldg": 22981,
+ "ble": 1447,
+ "ble": 1059,
+ "bleach": 27034,
+ "bleak": 40355,
+ "bled": 12006,
+ "bleed": 23027,
+ "bleed": 24791,
+ "bleedblue": 39160,
+ "bleeding": 20311,
+ "bleeds": 47339,
+ "blen": 25651,
+ "blend": 10780,
+ "blended": 25813,
+ "blender": 25066,
+ "blending": 34307,
+ "blends": 28572,
+ "bler": 31305,
+ "bler": 11979,
+ "blers": 26930,
+ "bles": 5763,
+ "bless": 9640,
+ "bless": 5387,
+ "blessed": 4411,
+ "blessing": 10729,
+ "blessings": 11185,
+ "bleu": 30114,
+ "blew": 18176,
+ "bley": 43176,
+ "bli": 1450,
+ "bli": 28051,
+ "blin": 9678,
+ "blin": 5406,
+ "blind": 17248,
+ "blind": 8351,
+ "blinded": 49149,
+ "blindness": 38812,
+ "blinds": 32449,
+ "bling": 39764,
+ "bling": 7097,
+ "blink": 18976,
+ "bliss": 28531,
+ "bliss": 12893,
+ "blissful": 42145,
+ "blit": 39327,
+ "blitz": 42151,
+ "blitz": 17548,
+ "blizz": 13075,
+ "blizzard": 16111,
+ "blk": 42950,
+ "blk": 22872,
+ "blm": 30957,
+ "bln": 47348,
+ "blo": 1204,
+ "blo": 25505,
+ "blob": 49312,
+ "bloc": 30961,
+ "block": 4638,
+ "block": 4593,
+ "blockade": 33489,
+ "blockbuster": 19939,
+ "blockchain": 6653,
+ "blocked": 9106,
+ "blocker": 44767,
+ "blocking": 12652,
+ "blocks": 10113,
+ "blog": 16376,
+ "blog": 2589,
+ "blogg": 33282,
+ "blogged": 41380,
+ "blogger": 21352,
+ "blogger": 7806,
+ "bloggerrt": 48898,
+ "bloggers": 11627,
+ "blogging": 18090,
+ "blogpost": 41842,
+ "blogs": 16682,
+ "bloke": 24384,
+ "blom": 48996,
+ "blon": 7958,
+ "blond": 32426,
+ "blonde": 10711,
+ "blondes": 45130,
+ "blondie": 39236,
+ "bloo": 2373,
+ "blood": 9231,
+ "blood": 3590,
+ "blooded": 41946,
+ "bloodh": 48480,
+ "bloods": 39539,
+ "bloody": 38568,
+ "bloody": 9468,
+ "bloom": 7311,
+ "bloom": 10257,
+ "bloomberg": 43109,
+ "bloomberg": 21238,
+ "bloomfield": 40342,
+ "blooming": 45175,
+ "blooming": 19266,
+ "bloomington": 34731,
+ "blooms": 21439,
+ "bloss": 10017,
+ "blossom": 14472,
+ "blossoms": 21916,
+ "blot": 41710,
+ "blou": 44506,
+ "blouse": 23525,
+ "blow": 15230,
+ "blow": 10211,
+ "blower": 25832,
+ "blowing": 12087,
+ "blown": 11848,
+ "blowout": 34857,
+ "blows": 21063,
+ "blr": 47250,
+ "bls": 39458,
+ "blu": 1263,
+ "blu": 10273,
+ "blue": 3829,
+ "blue": 1746,
+ "bluebells": 47150,
+ "blueberries": 29551,
+ "blueberry": 18251,
+ "bluebird": 40747,
+ "bluec": 43194,
+ "bluef": 41174,
+ "bluegrass": 26241,
+ "bluejays": 18684,
+ "blueprint": 30594,
+ "blues": 17566,
+ "blues": 5159,
+ "blueslyrix": 47068,
+ "bluet": 13469,
+ "bluetooth": 14052,
+ "bluewave": 40025,
+ "bluff": 27232,
+ "bluffs": 48844,
+ "blum": 34818,
+ "blumen": 38714,
+ "blun": 34472,
+ "blunt": 19305,
+ "blur": 12102,
+ "blur": 27976,
+ "bluray": 36818,
+ "blurred": 38013,
+ "blurry": 21977,
+ "blush": 22889,
+ "blvd": 12578,
+ "bly": 20930,
+ "bly": 4426,
+ "bm": 4773,
+ "bm": 15916,
+ "bma": 42573,
+ "bmc": 27807,
+ "bmi": 40642,
+ "bmo": 39083,
+ "bms": 34074,
+ "bmw": 26637,
+ "bmw": 7869,
+ "bmx": 22535,
+ "bn": 10496,
+ "bn": 7992,
+ "bnb": 20010,
+ "bnha": 49336,
+ "bnp": 47910,
+ "bnw": 35903,
+ "bo": 647,
+ "bo": 2525,
+ "boa": 14732,
+ "boar": 7837,
+ "boar": 35473,
+ "board": 10419,
+ "board": 1972,
+ "boarded": 43052,
+ "boarder": 37414,
+ "boardgame": 47829,
+ "boardgames": 32646,
+ "boarding": 10086,
+ "boardroom": 47937,
+ "boards": 7963,
+ "boardwalk": 29043,
+ "boast": 44467,
+ "boasts": 30309,
+ "boat": 12426,
+ "boat": 4440,
+ "boath": 45461,
+ "boating": 21951,
+ "boats": 10080,
+ "boatsales": 46244,
+ "bob": 8444,
+ "bob": 4423,
+ "boba": 39948,
+ "bobb": 16891,
+ "bobble": 38796,
+ "bobblehead": 33451,
+ "bobby": 17847,
+ "bobby": 7816,
+ "bobc": 26153,
+ "bobcat": 37896,
+ "bobcats": 27568,
+ "bobo": 38939,
+ "bobs": 45533,
+ "boc": 27307,
+ "boc": 39042,
+ "boca": 26094,
+ "bock": 24961,
+ "bod": 17904,
+ "bod": 26340,
+ "boda": 42030,
+ "bode": 28452,
+ "bode": 40429,
+ "bodega": 47350,
+ "bodied": 36892,
+ "bodies": 9799,
+ "bodily": 49119,
+ "body": 7132,
+ "body": 1774,
+ "bodybuilding": 24538,
+ "bodyguard": 35565,
+ "boe": 23476,
+ "boe": 21773,
+ "boeh": 38002,
+ "boehner": 44599,
+ "boeing": 48135,
+ "boeing": 11857,
+ "boer": 44889,
+ "boer": 40768,
+ "bog": 23426,
+ "bog": 28318,
+ "bogo": 35769,
+ "bogota": 47059,
+ "bogus": 42907,
+ "boh": 43238,
+ "bohe": 40541,
+ "bohemi": 21552,
+ "bohemian": 25753,
+ "boho": 25444,
+ "boi": 37129,
+ "boi": 12673,
+ "boil": 31332,
+ "boiled": 23886,
+ "boiler": 28212,
+ "boiler": 25615,
+ "boiling": 32019,
+ "bois": 47742,
+ "bois": 21640,
+ "boise": 23304,
+ "bok": 26671,
+ "bok": 15289,
+ "boko": 30929,
+ "boks": 40216,
+ "bol": 2860,
+ "bol": 8413,
+ "bola": 12840,
+ "bold": 26975,
+ "bold": 8911,
+ "boldand": 48413,
+ "boldly": 44778,
+ "boli": 12722,
+ "bolic": 27343,
+ "bolivia": 28628,
+ "bollah": 36336,
+ "bolly": 25302,
+ "bollywood": 32448,
+ "bollywood": 9604,
+ "bolo": 40236,
+ "bolog": 22818,
+ "bologna": 27513,
+ "bolster": 47304,
+ "bolt": 13131,
+ "bolton": 48757,
+ "bolton": 16598,
+ "bolts": 26028,
+ "bom": 3012,
+ "bom": 19469,
+ "bomb": 18091,
+ "bomb": 6331,
+ "bombar": 25544,
+ "bombardier": 42700,
+ "bombay": 48602,
+ "bombay": 23890,
+ "bombed": 24542,
+ "bomber": 15436,
+ "bombers": 21786,
+ "bombing": 14475,
+ "bombings": 43236,
+ "bombs": 14410,
+ "bombshell": 36340,
+ "bon": 1871,
+ "bon": 4216,
+ "bona": 33342,
+ "bonanza": 40304,
+ "bond": 37022,
+ "bond": 6826,
+ "bonded": 37390,
+ "bondi": 40092,
+ "bonding": 19609,
+ "bonds": 15786,
+ "bone": 22502,
+ "bone": 6195,
+ "bones": 9476,
+ "bonfire": 23151,
+ "bongo": 47519,
+ "boni": 32269,
+ "boni": 46356,
+ "bonita": 42896,
+ "bonjour": 33176,
+ "bonkers": 39865,
+ "bonn": 38969,
+ "bonnar": 47191,
+ "bonnaroo": 48777,
+ "bonne": 25844,
+ "bonnet": 30636,
+ "bonnie": 18555,
+ "bono": 24476,
+ "bons": 42883,
+ "bonsai": 44129,
+ "bonus": 8164,
+ "bonuses": 35144,
+ "boo": 824,
+ "boo": 7317,
+ "boogie": 22639,
+ "book": 2828,
+ "book": 1116,
+ "bookboost": 31257,
+ "bookclub": 34438,
+ "bookday": 26327,
+ "booked": 12584,
+ "booker": 21302,
+ "bookfest": 39381,
+ "booking": 10145,
+ "bookings": 18345,
+ "booklet": 27405,
+ "bookmark": 33596,
+ "bookof": 45629,
+ "bookreview": 27362,
+ "books": 44382,
+ "books": 2161,
+ "bookshelf": 34821,
+ "bookshop": 24705,
+ "bookstore": 17999,
+ "bookstores": 46416,
+ "bookworm": 20743,
+ "boom": 9609,
+ "boom": 7121,
+ "boomer": 33819,
+ "boomer": 31766,
+ "boomers": 37988,
+ "booming": 33487,
+ "boon": 24979,
+ "boon": 35821,
+ "boone": 23453,
+ "boop": 45047,
+ "boost": 44639,
+ "boost": 6260,
+ "boosted": 37631,
+ "booster": 20877,
+ "boosters": 46859,
+ "boosting": 28480,
+ "boosts": 29247,
+ "boot": 10843,
+ "boot": 8087,
+ "bootcamp": 22051,
+ "booted": 42564,
+ "booth": 47895,
+ "booth": 3971,
+ "booths": 32653,
+ "booties": 46188,
+ "bootleg": 38139,
+ "boots": 7319,
+ "booze": 24341,
+ "bop": 19720,
+ "bor": 1141,
+ "bor": 15093,
+ "bora": 24736,
+ "bord": 36891,
+ "bordeaux": 22009,
+ "border": 16304,
+ "border": 6177,
+ "borderlands": 38676,
+ "borders": 13900,
+ "bore": 14084,
+ "bore": 24638,
+ "bored": 8933,
+ "boredom": 31460,
+ "boretum": 38902,
+ "borg": 14770,
+ "borgh": 17180,
+ "boring": 12519,
+ "boris": 31212,
+ "boris": 15704,
+ "borisjohnson": 44481,
+ "born": 17695,
+ "born": 2683,
+ "borne": 42910,
+ "borne": 9328,
+ "borneo": 33332,
+ "bornon": 41811,
+ "bornonthisday": 42757,
+ "boro": 26796,
+ "boro": 7974,
+ "borough": 22761,
+ "borough": 6203,
+ "borrow": 22293,
+ "borrowed": 28224,
+ "borrowing": 41045,
+ "borussia": 36764,
+ "bos": 14885,
+ "bos": 9644,
+ "bosa": 46946,
+ "bosch": 42009,
+ "bosch": 19466,
+ "bosco": 36960,
+ "bose": 23142,
+ "bosh": 42244,
+ "bosni": 42924,
+ "bosnia": 31396,
+ "boss": 17935,
+ "boss": 4206,
+ "bosses": 23906,
+ "boston": 11540,
+ "boston": 4399,
+ "bostonmarathon": 44533,
+ "bot": 4136,
+ "bot": 6947,
+ "botan": 12554,
+ "botanic": 32560,
+ "botanical": 21026,
+ "botany": 22612,
+ "botd": 34451,
+ "both": 36575,
+ "both": 2212,
+ "bother": 21125,
+ "bothered": 27997,
+ "botox": 43449,
+ "bots": 13721,
+ "botswana": 27584,
+ "bott": 3520,
+ "bott": 37225,
+ "bottle": 37306,
+ "bottle": 5392,
+ "bottled": 29331,
+ "bottlen": 46439,
+ "bottles": 9754,
+ "bottling": 42006,
+ "bottom": 32314,
+ "bottom": 5931,
+ "bottoms": 31524,
+ "bou": 3728,
+ "bou": 23165,
+ "bouchard": 47930,
+ "boudo": 48827,
+ "bought": 4142,
+ "boul": 24830,
+ "boulder": 18260,
+ "boule": 17652,
+ "boulevard": 19504,
+ "boun": 5993,
+ "bounce": 14316,
+ "bouncing": 32060,
+ "bouncy": 43415,
+ "bound": 15140,
+ "bound": 4567,
+ "boundaries": 18690,
+ "boundary": 21344,
+ "bounds": 37469,
+ "bounty": 21142,
+ "bouquet": 20961,
+ "bour": 2934,
+ "bour": 35486,
+ "bourbon": 48118,
+ "bourbon": 14652,
+ "bourdain": 48095,
+ "bourg": 20690,
+ "bourgeo": 45672,
+ "bourn": 39143,
+ "bourne": 13789,
+ "bourne": 5192,
+ "bournemouth": 20911,
+ "bout": 19982,
+ "bout": 8123,
+ "bouti": 10926,
+ "boutique": 12179,
+ "bow": 2297,
+ "bow": 4040,
+ "bowden": 48538,
+ "bowed": 49130,
+ "bowel": 36880,
+ "bowen": 25368,
+ "bower": 40414,
+ "bowers": 42238,
+ "bowie": 13036,
+ "bowing": 46398,
+ "bowl": 26719,
+ "bowl": 3814,
+ "bowled": 39987,
+ "bowler": 25528,
+ "bowlers": 42632,
+ "bowles": 41611,
+ "bowling": 10390,
+ "bowls": 17787,
+ "bowman": 22052,
+ "bows": 17000,
+ "bowser": 38234,
+ "bowski": 48311,
+ "box": 2774,
+ "box": 2063,
+ "boxed": 24190,
+ "boxer": 40394,
+ "boxer": 15363,
+ "boxers": 31019,
+ "boxes": 8350,
+ "boxing": 33669,
+ "boxing": 5554,
+ "boy": 2927,
+ "boy": 1876,
+ "boyband": 31568,
+ "boyce": 44480,
+ "boycot": 46208,
+ "boycott": 31615,
+ "boycott": 19559,
+ "boyd": 18295,
+ "boyfriend": 7328,
+ "boyfriends": 36541,
+ "boyle": 22802,
+ "boys": 25223,
+ "boys": 2034,
+ "boyz": 16152,
+ "bp": 23410,
+ "bp": 11558,
+ "bpa": 43855,
+ "bpd": 48587,
+ "bpl": 28901,
+ "bpm": 40338,
+ "bps": 37794,
+ "br": 711,
+ "br": 7532,
+ "bra": 1195,
+ "bra": 5860,
+ "brac": 6663,
+ "brace": 8376,
+ "brace": 9183,
+ "bracelet": 8969,
+ "bracelets": 20027,
+ "braces": 19249,
+ "brack": 25676,
+ "bracket": 14780,
+ "brackets": 36183,
+ "brad": 4848,
+ "brad": 9405,
+ "bradbury": 45097,
+ "braden": 46842,
+ "bradford": 15062,
+ "bradley": 31905,
+ "bradley": 10952,
+ "brador": 24062,
+ "bradshaw": 37556,
+ "brady": 42494,
+ "brady": 11117,
+ "brae": 42874,
+ "brae": 40040,
+ "brag": 30110,
+ "bragg": 38545,
+ "bragging": 38199,
+ "brah": 20276,
+ "brahms": 45114,
+ "brai": 25048,
+ "braid": 31067,
+ "braided": 39997,
+ "braids": 34221,
+ "brain": 9454,
+ "brain": 4812,
+ "brains": 17129,
+ "brainstorming": 36607,
+ "braised": 28363,
+ "brake": 14937,
+ "brakes": 23456,
+ "bral": 31309,
+ "bram": 14815,
+ "bram": 39456,
+ "brampton": 35124,
+ "bran": 3684,
+ "bran": 28348,
+ "brance": 36072,
+ "brance": 15413,
+ "branch": 7998,
+ "branches": 15843,
+ "brand": 3910,
+ "brand": 2896,
+ "branded": 18097,
+ "brandi": 41003,
+ "branding": 10841,
+ "brando": 41892,
+ "brandon": 20423,
+ "brandon": 9166,
+ "brands": 8681,
+ "brandt": 22552,
+ "brandy": 26232,
+ "brane": 32340,
+ "branson": 28280,
+ "brant": 28951,
+ "brant": 47592,
+ "braries": 46377,
+ "brary": 24520,
+ "bras": 22611,
+ "brasil": 18991,
+ "brass": 24348,
+ "brass": 11655,
+ "brat": 26717,
+ "brat": 26631,
+ "brate": 41864,
+ "braun": 39129,
+ "braun": 29309,
+ "brave": 25461,
+ "brave": 7769,
+ "braved": 47663,
+ "bravely": 42303,
+ "bravery": 25831,
+ "braves": 14422,
+ "braving": 43258,
+ "bravo": 38613,
+ "bravo": 13006,
+ "braw": 37871,
+ "brawl": 26066,
+ "braxton": 37451,
+ "bray": 26256,
+ "bray": 22993,
+ "braz": 4625,
+ "brazil": 47459,
+ "brazil": 6305,
+ "brazili": 45697,
+ "brazilian": 12111,
+ "brb": 25316,
+ "brc": 40393,
+ "bre": 887,
+ "bre": 7782,
+ "brea": 7318,
+ "brea": 46538,
+ "breach": 21363,
+ "breaches": 45173,
+ "bread": 18886,
+ "bread": 5066,
+ "breads": 43064,
+ "break": 2206,
+ "break": 2568,
+ "breakable": 30691,
+ "breakaway": 42732,
+ "breakdown": 14519,
+ "breaker": 14814,
+ "breakers": 22270,
+ "breakfa": 45931,
+ "breakfast": 30210,
+ "breakfast": 3290,
+ "breaking": 14698,
+ "breaking": 2755,
+ "breakingbad": 38032,
+ "breakingnews": 23837,
+ "breakout": 16752,
+ "breaks": 7263,
+ "breakthrough": 18802,
+ "breakup": 38931,
+ "breast": 12930,
+ "breast": 9475,
+ "breastcancer": 40813,
+ "breastcancer": 30065,
+ "breastfeeding": 29033,
+ "breasts": 37637,
+ "breath": 9508,
+ "breath": 9576,
+ "breathe": 11364,
+ "breathing": 14959,
+ "breathtaking": 14709,
+ "brecht": 34622,
+ "breck": 44598,
+ "bred": 46929,
+ "bred": 16008,
+ "bree": 7892,
+ "bree": 37138,
+ "breed": 28030,
+ "breed": 13791,
+ "breeders": 37472,
+ "breeding": 16544,
+ "breeds": 29021,
+ "breen": 48013,
+ "brees": 46721,
+ "breeze": 13125,
+ "breezy": 21451,
+ "breit": 23864,
+ "breitbart": 37926,
+ "brek": 35494,
+ "bremen": 39861,
+ "bren": 5209,
+ "brenda": 23786,
+ "brendan": 35134,
+ "brendan": 15414,
+ "brendon": 36756,
+ "brennan": 22372,
+ "brenner": 42941,
+ "brent": 31439,
+ "brent": 16355,
+ "brentwood": 33108,
+ "brero": 47781,
+ "bres": 32561,
+ "bret": 38020,
+ "bret": 32548,
+ "brethren": 43134,
+ "breton": 32290,
+ "brett": 22591,
+ "brett": 12394,
+ "brev": 42882,
+ "brevi": 39475,
+ "brew": 5048,
+ "brew": 7253,
+ "brewco": 33582,
+ "brewed": 23238,
+ "brewer": 20756,
+ "breweries": 35277,
+ "brewers": 17618,
+ "brewery": 8850,
+ "brewing": 8275,
+ "brewingco": 45155,
+ "brews": 21663,
+ "brewster": 40274,
+ "brex": 22726,
+ "brexit": 27666,
+ "brexit": 5801,
+ "brgy": 35983,
+ "bri": 1036,
+ "bri": 18636,
+ "bria": 35890,
+ "brian": 9824,
+ "brian": 4989,
+ "brianna": 32308,
+ "briar": 46119,
+ "bribe": 40042,
+ "bribery": 41792,
+ "bric": 27055,
+ "brice": 40190,
+ "brick": 13937,
+ "brick": 9518,
+ "bricks": 21029,
+ "brics": 48196,
+ "brid": 16995,
+ "bridal": 36875,
+ "bridal": 14284,
+ "bride": 18342,
+ "bride": 8964,
+ "brides": 18067,
+ "bridesma": 28356,
+ "bridesmaid": 43399,
+ "bridesmaids": 47754,
+ "bridg": 20623,
+ "bridge": 8647,
+ "bridge": 2465,
+ "bridgeport": 45201,
+ "bridges": 11811,
+ "bridget": 27073,
+ "bridgewater": 38732,
+ "bridging": 38109,
+ "brie": 26622,
+ "brief": 9435,
+ "brief": 8954,
+ "briefed": 47326,
+ "briefing": 12991,
+ "briefly": 26980,
+ "briefs": 29557,
+ "brien": 13504,
+ "brier": 43995,
+ "brig": 11081,
+ "briga": 46448,
+ "brigade": 16032,
+ "briggs": 28108,
+ "brigh": 6710,
+ "bright": 10383,
+ "bright": 4852,
+ "brighten": 18208,
+ "brightening": 43929,
+ "brighter": 18507,
+ "brightest": 26159,
+ "brightly": 36298,
+ "brightness": 42280,
+ "brighton": 28416,
+ "brighton": 9470,
+ "brigitte": 44421,
+ "brill": 27342,
+ "brill": 28601,
+ "brilli": 3821,
+ "brilliance": 28146,
+ "brilliant": 4106,
+ "brilliantly": 26803,
+ "brin": 25620,
+ "bring": 11596,
+ "bring": 2430,
+ "bringback": 28969,
+ "bringbackour": 45403,
+ "bringing": 4777,
+ "brings": 5138,
+ "brink": 39296,
+ "brink": 28796,
+ "brioche": 45818,
+ "bris": 9385,
+ "bris": 15783,
+ "brisban": 30431,
+ "brisbane": 42932,
+ "brisbane": 12407,
+ "brisk": 43646,
+ "brisket": 31920,
+ "bristol": 18159,
+ "bristol": 8010,
+ "brit": 2318,
+ "brit": 20066,
+ "britain": 40802,
+ "britain": 6272,
+ "britanni": 31373,
+ "britannia": 36188,
+ "brite": 33827,
+ "briti": 8155,
+ "british": 8651,
+ "british": 3504,
+ "britishmuseum": 41858,
+ "britney": 37192,
+ "britney": 21853,
+ "britneyspears": 42990,
+ "brits": 21832,
+ "britt": 10811,
+ "britt": 25976,
+ "brittany": 38187,
+ "brittany": 18818,
+ "britton": 37422,
+ "brium": 46079,
+ "brixton": 30056,
+ "bro": 927,
+ "bro": 4410,
+ "broad": 3491,
+ "broad": 12623,
+ "broadband": 21050,
+ "broadcast": 8967,
+ "broadcaster": 29005,
+ "broadcasting": 14403,
+ "broadcasts": 46742,
+ "broader": 36029,
+ "broadway": 34599,
+ "broadway": 9092,
+ "broc": 15587,
+ "broccoli": 19094,
+ "broch": 21419,
+ "brochure": 25275,
+ "brock": 14841,
+ "brock": 16745,
+ "brodie": 42150,
+ "brody": 29608,
+ "broke": 42165,
+ "broke": 6509,
+ "broken": 26126,
+ "broken": 5107,
+ "broker": 34032,
+ "broker": 20449,
+ "brokerage": 41327,
+ "brokers": 28271,
+ "brom": 18972,
+ "brom": 33296,
+ "bromance": 35353,
+ "bromley": 35715,
+ "bron": 4011,
+ "bron": 10243,
+ "bronco": 43488,
+ "bronco": 34370,
+ "broncos": 12516,
+ "bronson": 37042,
+ "bronte": 48936,
+ "bronx": 48310,
+ "bronx": 17183,
+ "brony": 21084,
+ "bronze": 8459,
+ "broo": 5204,
+ "brooch": 21207,
+ "brook": 4782,
+ "brook": 7322,
+ "brooke": 28576,
+ "brooke": 12549,
+ "brookes": 39707,
+ "brooklyn": 23253,
+ "brooklyn": 6983,
+ "brooks": 42779,
+ "brooks": 9991,
+ "broom": 32046,
+ "broom": 28008,
+ "broome": 49335,
+ "bros": 7776,
+ "broth": 29994,
+ "brotha": 33974,
+ "brother": 12697,
+ "brother": 3157,
+ "brotherhood": 19059,
+ "brothers": 4548,
+ "brou": 27874,
+ "brough": 21033,
+ "brought": 4222,
+ "brov": 42881,
+ "brow": 6547,
+ "brow": 15895,
+ "broward": 34719,
+ "brown": 6315,
+ "brown": 2866,
+ "browne": 28440,
+ "brownie": 23045,
+ "brownies": 22312,
+ "browning": 32241,
+ "browns": 14051,
+ "brows": 14998,
+ "browse": 19060,
+ "browser": 19768,
+ "browsing": 29318,
+ "brox": 43539,
+ "brs": 47485,
+ "brt": 46936,
+ "bru": 1698,
+ "bru": 31028,
+ "bruce": 21223,
+ "bruce": 7085,
+ "bruh": 17575,
+ "bruins": 14736,
+ "bruise": 48048,
+ "bruised": 46502,
+ "brum": 23862,
+ "brum": 28078,
+ "brun": 6870,
+ "brunch": 9113,
+ "brune": 29057,
+ "brunei": 41898,
+ "brunette": 35528,
+ "bruno": 14568,
+ "brunomars": 41156,
+ "brunswick": 24012,
+ "brush": 27969,
+ "brush": 8594,
+ "brushed": 30298,
+ "brushes": 21550,
+ "brushing": 35072,
+ "brussels": 11020,
+ "brut": 39499,
+ "brutal": 42144,
+ "brutal": 14556,
+ "brutality": 31348,
+ "brutally": 28132,
+ "brute": 47552,
+ "brux": 49093,
+ "bry": 6587,
+ "bry": 28228,
+ "bryan": 16134,
+ "bryan": 10412,
+ "bryant": 12256,
+ "bryce": 19895,
+ "bryn": 36569,
+ "bryn": 42877,
+ "bryson": 38990,
+ "bs": 11783,
+ "bs": 1329,
+ "bsa": 46619,
+ "bsb": 23070,
+ "bsbi": 41728,
+ "bsbibotany": 42086,
+ "bsc": 32031,
+ "bsd": 41848,
+ "bse": 46341,
+ "bsf": 48314,
+ "bsgo": 48474,
+ "bsp": 47977,
+ "bst": 19698,
+ "bsu": 46385,
+ "bt": 3317,
+ "bt": 4205,
+ "btc": 10315,
+ "btcc": 30759,
+ "btn": 44681,
+ "bto": 35516,
+ "btob": 29379,
+ "btr": 39767,
+ "bts": 15154,
+ "bts": 4007,
+ "btsarmy": 30302,
+ "btsbbmas": 35297,
+ "btsx": 44971,
+ "btv": 38541,
+ "btw": 9520,
+ "btwn": 28284,
+ "bu": 609,
+ "bu": 5831,
+ "bub": 27704,
+ "bub": 33158,
+ "bubb": 9739,
+ "bubba": 28149,
+ "bubble": 28687,
+ "bubble": 10799,
+ "bubblegum": 48078,
+ "bubbles": 17648,
+ "bubbly": 31034,
+ "buc": 8207,
+ "buccane": 32830,
+ "buccaneers": 38058,
+ "buch": 22623,
+ "bucha": 43582,
+ "buchan": 27237,
+ "buchanan": 28975,
+ "bucharest": 37013,
+ "buck": 6061,
+ "buck": 11433,
+ "bucket": 22596,
+ "bucket": 10498,
+ "bucketlist": 30778,
+ "buckets": 27168,
+ "buckeye": 34549,
+ "buckeyes": 30741,
+ "buckingham": 28736,
+ "buckle": 21948,
+ "buckley": 25905,
+ "bucks": 6103,
+ "bucky": 35916,
+ "bucs": 20011,
+ "bud": 2942,
+ "bud": 10737,
+ "buda": 18520,
+ "buda": 49012,
+ "budapest": 19202,
+ "budd": 7296,
+ "buddha": 13981,
+ "buddhism": 23744,
+ "buddhist": 18697,
+ "buddies": 14543,
+ "budding": 31992,
+ "buddy": 40948,
+ "buddy": 6557,
+ "budge": 32005,
+ "budget": 46758,
+ "budget": 5639,
+ "budgeting": 43789,
+ "budgets": 36419,
+ "buds": 14665,
+ "budweiser": 40900,
+ "buen": 15640,
+ "buena": 30876,
+ "buenas": 48529,
+ "bueno": 46202,
+ "buenos": 26055,
+ "buf": 44417,
+ "buff": 5456,
+ "buff": 21416,
+ "buffal": 25836,
+ "buffalo": 31231,
+ "buffalo": 8054,
+ "buffalob": 38831,
+ "buffalobills": 44352,
+ "buffe": 13724,
+ "buffer": 33050,
+ "buffet": 17829,
+ "buffett": 34081,
+ "buffs": 28906,
+ "buffy": 33356,
+ "bug": 14453,
+ "bug": 8162,
+ "bugatti": 35451,
+ "buggy": 28963,
+ "bugs": 13850,
+ "buh": 31406,
+ "buhari": 14661,
+ "buick": 22000,
+ "buil": 1354,
+ "build": 22739,
+ "build": 3289,
+ "builder": 14474,
+ "builders": 17694,
+ "building": 21206,
+ "building": 2307,
+ "buildings": 8866,
+ "builds": 16449,
+ "buildthe": 41497,
+ "built": 45824,
+ "built": 3874,
+ "buk": 28084,
+ "buk": 24317,
+ "buka": 47778,
+ "bukit": 39888,
+ "bul": 2572,
+ "bul": 10200,
+ "bula": 18726,
+ "bulaga": 41575,
+ "bular": 32187,
+ "bulb": 22373,
+ "bulbs": 24808,
+ "bulgar": 15424,
+ "bulgaria": 20295,
+ "bulgarian": 38693,
+ "bulge": 47603,
+ "bulk": 19643,
+ "bull": 4537,
+ "bull": 6029,
+ "bulldo": 37675,
+ "bulldog": 34828,
+ "bulldog": 15611,
+ "bulldogs": 13916,
+ "bullet": 14340,
+ "bullet": 12465,
+ "bulletin": 19638,
+ "bulletproof": 43212,
+ "bullets": 22117,
+ "bullied": 34689,
+ "bullies": 39050,
+ "bullion": 49114,
+ "bullish": 22142,
+ "bullock": 33198,
+ "bullpen": 38081,
+ "bulls": 10313,
+ "bully": 43111,
+ "bully": 20190,
+ "bullying": 13548,
+ "bum": 27683,
+ "bum": 14226,
+ "bumble": 25585,
+ "bumble": 39303,
+ "bumblebee": 36911,
+ "bummed": 48456,
+ "bump": 9783,
+ "bump": 15877,
+ "bumped": 22495,
+ "bumper": 17881,
+ "bumping": 40196,
+ "bumps": 21115,
+ "bun": 2591,
+ "bun": 13665,
+ "bunch": 7796,
+ "bund": 41905,
+ "bunde": 18841,
+ "bundesliga": 21582,
+ "bundle": 11793,
+ "bundled": 47228,
+ "bundles": 29834,
+ "bundy": 37332,
+ "bung": 44748,
+ "bungal": 29549,
+ "bungalow": 33696,
+ "bunk": 41236,
+ "bunker": 23615,
+ "bunnies": 28998,
+ "bunny": 34198,
+ "bunny": 9258,
+ "buns": 22235,
+ "bunting": 30695,
+ "buon": 31350,
+ "buon": 48498,
+ "bur": 1039,
+ "bur": 17362,
+ "burbank": 34862,
+ "burberry": 30412,
+ "burch": 44588,
+ "burden": 18687,
+ "bure": 11902,
+ "bureau": 32098,
+ "bureau": 15400,
+ "burg": 19505,
+ "burg": 3499,
+ "burge": 20522,
+ "burger": 22356,
+ "burger": 6548,
+ "burgers": 13007,
+ "burgess": 26211,
+ "burgh": 18141,
+ "burgh": 4965,
+ "burgl": 25554,
+ "burglar": 43365,
+ "burglary": 32573,
+ "burgring": 40823,
+ "burgundy": 23650,
+ "buri": 46348,
+ "buri": 42614,
+ "burial": 22012,
+ "buried": 14233,
+ "burk": 48822,
+ "burke": 15340,
+ "burle": 27891,
+ "burlesque": 33732,
+ "burlington": 23370,
+ "burma": 30305,
+ "burmese": 47906,
+ "burn": 7934,
+ "burn": 4285,
+ "burnaby": 47541,
+ "burne": 27246,
+ "burned": 15022,
+ "burner": 23243,
+ "burnett": 28558,
+ "burnham": 36111,
+ "burning": 46107,
+ "burning": 8405,
+ "burnley": 24653,
+ "burnout": 36078,
+ "burns": 10234,
+ "burnt": 15185,
+ "burr": 30879,
+ "burrell": 49045,
+ "burrito": 23473,
+ "burritos": 47245,
+ "burroughs": 41337,
+ "burrows": 44846,
+ "burst": 13005,
+ "bursting": 32566,
+ "bursts": 37026,
+ "burt": 27162,
+ "burton": 42354,
+ "burton": 12704,
+ "burundi": 33595,
+ "bury": 12276,
+ "bury": 3899,
+ "burys": 32362,
+ "bus": 1319,
+ "bus": 2840,
+ "busan": 40172,
+ "busc": 35000,
+ "busch": 20475,
+ "buses": 12879,
+ "bush": 11191,
+ "bush": 6867,
+ "bushes": 37578,
+ "busiest": 32764,
+ "busine": 4598,
+ "busines": 25364,
+ "business": 8346,
+ "business": 1716,
+ "businesses": 7287,
+ "businessman": 25635,
+ "buss": 47764,
+ "bust": 31299,
+ "bust": 9959,
+ "busted": 18643,
+ "buster": 37219,
+ "buster": 12094,
+ "busters": 16362,
+ "busting": 29622,
+ "busy": 39332,
+ "busy": 4354,
+ "but": 2201,
+ "but": 767,
+ "butch": 35102,
+ "butcher": 18732,
+ "butchers": 42334,
+ "bute": 39240,
+ "butes": 14630,
+ "butler": 35867,
+ "butler": 10702,
+ "butt": 12500,
+ "butt": 31523,
+ "butte": 31678,
+ "butter": 5427,
+ "butter": 6952,
+ "butterflies": 16232,
+ "butterfly": 9738,
+ "buttermilk": 40180,
+ "butternut": 36867,
+ "buttery": 45535,
+ "button": 45480,
+ "button": 8007,
+ "buttons": 16188,
+ "butts": 25309,
+ "buu": 42313,
+ "buuren": 47752,
+ "buxton": 41370,
+ "buy": 11632,
+ "buy": 2131,
+ "buyer": 14682,
+ "buyers": 14663,
+ "buying": 6566,
+ "buys": 15560,
+ "buzz": 7866,
+ "buzz": 8706,
+ "buzzard": 47434,
+ "buzzer": 38064,
+ "buzzfeed": 26613,
+ "buzzing": 18511,
+ "bv": 18958,
+ "bv": 35861,
+ "bvb": 22454,
+ "bw": 17672,
+ "bw": 15120,
+ "bway": 26652,
+ "bwfc": 40918,
+ "bwo": 45902,
+ "bx": 33633,
+ "by": 1713,
+ "by": 638,
+ "bye": 20076,
+ "bye": 4460,
+ "byes": 47958,
+ "byl": 34994,
+ "byn": 46917,
+ "byn": 11890,
+ "byo": 28039,
+ "bypass": 26530,
+ "byr": 15534,
+ "byrd": 30369,
+ "byrne": 19676,
+ "byron": 43504,
+ "byron": 19775,
+ "bys": 26740,
+ "bystand": 46138,
+ "byte": 42798,
+ "bytes": 39538,
+ "bythe": 36621,
+ "byu": 41072,
+ "byu": 23770,
+ "byz": 35406,
+ "byzantine": 44081,
+ "bz": 13631,
+ "bé": 40365,
+ "bü": 38706,
+ "c": 66,
+ "c": 322,
+ "ca": 772,
+ "ca": 1684,
+ "caa": 19316,
+ "cab": 3033,
+ "cab": 11912,
+ "cabaret": 26263,
+ "cabbage": 18407,
+ "cabe": 32731,
+ "cabello": 34371,
+ "caber": 29062,
+ "cabernet": 33730,
+ "cabin": 14178,
+ "cabine": 23354,
+ "cabinet": 9937,
+ "cabinets": 33083,
+ "cabins": 48455,
+ "cable": 7925,
+ "cables": 22408,
+ "cabo": 37318,
+ "cabo": 28370,
+ "cabrera": 42338,
+ "cabs": 42048,
+ "cac": 8298,
+ "cac": 23872,
+ "cacao": 38022,
+ "cache": 28993,
+ "caching": 40655,
+ "cactus": 19794,
+ "cad": 6297,
+ "cad": 20166,
+ "caday": 34187,
+ "cadbury": 44698,
+ "caddy": 41521,
+ "cade": 10497,
+ "cade": 17306,
+ "cadet": 22764,
+ "cadets": 19160,
+ "cadillac": 18156,
+ "cae": 49264,
+ "caer": 28298,
+ "caes": 15740,
+ "caesar": 21642,
+ "caesars": 42162,
+ "caf": 3471,
+ "caf": 20867,
+ "cafc": 30748,
+ "cafe": 15201,
+ "cafe": 4979,
+ "cafes": 40166,
+ "cafeteria": 32817,
+ "caffe": 18258,
+ "caffe": 45416,
+ "caffeine": 22487,
+ "café": 15304,
+ "cag": 15714,
+ "cage": 11838,
+ "cages": 37939,
+ "cah": 40519,
+ "cahill": 33185,
+ "cai": 38971,
+ "cai": 36116,
+ "cain": 13747,
+ "caine": 16799,
+ "cair": 15804,
+ "cair": 46659,
+ "cairn": 31264,
+ "cairn": 42467,
+ "cairngor": 44067,
+ "cairns": 32941,
+ "cairo": 19615,
+ "cait": 14116,
+ "caitlin": 47768,
+ "caitlin": 26809,
+ "caitlyn": 35763,
+ "cajun": 43425,
+ "cajun": 33044,
+ "cak": 42986,
+ "cake": 15295,
+ "cake": 2972,
+ "cakeday": 46207,
+ "cakes": 5950,
+ "cal": 1198,
+ "cal": 6372,
+ "cala": 32133,
+ "calab": 31795,
+ "calais": 39886,
+ "calam": 28841,
+ "calc": 45055,
+ "calci": 22824,
+ "calcium": 27815,
+ "calcu": 15328,
+ "calcul": 15734,
+ "calculate": 37656,
+ "calculated": 40688,
+ "calculations": 44605,
+ "calculator": 26093,
+ "calculus": 35104,
+ "calcutta": 42901,
+ "calder": 29372,
+ "calder": 36817,
+ "caldwell": 30484,
+ "cale": 32674,
+ "caleb": 19619,
+ "caled": 28421,
+ "calend": 6057,
+ "calendar": 7122,
+ "calendars": 17229,
+ "calf": 17508,
+ "calgary": 27415,
+ "calgary": 10797,
+ "calhoun": 38929,
+ "cali": 2857,
+ "cali": 16337,
+ "caliber": 32820,
+ "calibr": 32597,
+ "calico": 45379,
+ "calif": 30839,
+ "califor": 3526,
+ "californi": 21303,
+ "california": 3729,
+ "call": 7950,
+ "call": 1620,
+ "calla": 20658,
+ "callahan": 43313,
+ "callaway": 42596,
+ "callback": 44764,
+ "calle": 47699,
+ "calle": 38144,
+ "called": 2726,
+ "caller": 30666,
+ "calli": 16338,
+ "callie": 36512,
+ "calligraphy": 27775,
+ "calling": 4597,
+ "callister": 49026,
+ "callme": 42449,
+ "callof": 41280,
+ "calls": 4572,
+ "callum": 23224,
+ "calm": 34990,
+ "calm": 7011,
+ "calming": 30690,
+ "calorie": 32679,
+ "calories": 18029,
+ "cals": 47714,
+ "calum": 16405,
+ "calvary": 40169,
+ "calvert": 47134,
+ "calves": 31857,
+ "calvin": 27642,
+ "calvin": 17345,
+ "caly": 10244,
+ "calyp": 29851,
+ "cam": 1004,
+ "cam": 5982,
+ "camar": 31991,
+ "camber": 44362,
+ "cambo": 14662,
+ "cambodia": 17347,
+ "cambridge": 24651,
+ "cambridge": 9334,
+ "cambridgeshire": 46139,
+ "camden": 38735,
+ "camden": 17984,
+ "came": 1986,
+ "camel": 27005,
+ "camel": 21914,
+ "camels": 41357,
+ "cameo": 19492,
+ "camer": 4961,
+ "camera": 3934,
+ "cameraman": 43347,
+ "cameras": 12172,
+ "camero": 20320,
+ "cameron": 19634,
+ "cameron": 8057,
+ "camerondallas": 40587,
+ "cameroon": 24061,
+ "camil": 37745,
+ "camila": 19919,
+ "camilla": 38897,
+ "camille": 26741,
+ "camino": 28529,
+ "camo": 28702,
+ "camo": 19716,
+ "camogie": 39547,
+ "camou": 23588,
+ "camoufla": 23667,
+ "camouflage": 29049,
+ "camp": 2854,
+ "camp": 2877,
+ "campa": 2793,
+ "campaig": 9448,
+ "campaign": 44524,
+ "campaign": 3193,
+ "campaigner": 46364,
+ "campaigners": 40272,
+ "campaigning": 19594,
+ "campaigns": 15669,
+ "campan": 31765,
+ "campbell": 29094,
+ "campbell": 8806,
+ "campe": 16672,
+ "campeon": 49109,
+ "campeones": 30105,
+ "camper": 41914,
+ "camper": 24522,
+ "campers": 26619,
+ "campfire": 32530,
+ "campground": 46969,
+ "camping": 9982,
+ "campo": 27600,
+ "campos": 48077,
+ "camps": 12806,
+ "campsite": 44243,
+ "campu": 19687,
+ "campus": 4560,
+ "campuses": 31895,
+ "camra": 46155,
+ "camry": 46472,
+ "cams": 32590,
+ "can": 950,
+ "can": 753,
+ "cana": 28341,
+ "canad": 13193,
+ "canada": 2698,
+ "canadaday": 39800,
+ "canadi": 4329,
+ "canadian": 22160,
+ "canadian": 5255,
+ "canadians": 18989,
+ "canadiens": 40932,
+ "canal": 28585,
+ "canal": 9535,
+ "canals": 38483,
+ "canaria": 47117,
+ "canary": 40409,
+ "canary": 24523,
+ "canberra": 16719,
+ "canc": 43189,
+ "cancel": 12026,
+ "cancel": 21546,
+ "canceled": 25874,
+ "cancell": 28027,
+ "cancellation": 38765,
+ "cancelled": 13270,
+ "cancels": 34089,
+ "cancer": 12690,
+ "cancer": 3148,
+ "cancers": 33201,
+ "cancun": 34721,
+ "cand": 4986,
+ "candace": 45623,
+ "candel": 47834,
+ "candi": 6034,
+ "candice": 30024,
+ "candid": 7884,
+ "candid": 19206,
+ "candidacy": 46248,
+ "candidate": 6475,
+ "candidates": 8619,
+ "candied": 43982,
+ "candies": 46305,
+ "candle": 18995,
+ "candle": 12674,
+ "candlelight": 34724,
+ "candles": 15472,
+ "candy": 20741,
+ "candy": 6417,
+ "cane": 23644,
+ "cane": 14716,
+ "canelo": 43210,
+ "canes": 21902,
+ "cani": 35592,
+ "canine": 27380,
+ "cann": 4139,
+ "cann": 23709,
+ "cannab": 7577,
+ "cannabis": 31837,
+ "cannabis": 8861,
+ "canne": 44252,
+ "canned": 27290,
+ "cannes": 13773,
+ "canni": 26389,
+ "canning": 38621,
+ "cannon": 28771,
+ "cannon": 15661,
+ "cannons": 46269,
+ "cannot": 4785,
+ "canny": 26986,
+ "cano": 31668,
+ "cano": 25937,
+ "canoe": 23503,
+ "canola": 40389,
+ "canon": 17749,
+ "canon": 9310,
+ "canopy": 26061,
+ "cans": 13707,
+ "cant": 13395,
+ "cant": 5784,
+ "canteen": 39230,
+ "canter": 19301,
+ "canterbury": 22271,
+ "canti": 42845,
+ "cantina": 47472,
+ "canton": 37735,
+ "canton": 25363,
+ "cantore": 41769,
+ "cantwait": 33760,
+ "canu": 20171,
+ "canucks": 24321,
+ "canv": 30714,
+ "canvas": 22441,
+ "canvas": 7483,
+ "canvass": 40054,
+ "canvassing": 33783,
+ "cany": 47674,
+ "canyon": 41246,
+ "canyon": 9755,
+ "cao": 29207,
+ "cap": 1289,
+ "cap": 3938,
+ "capabilities": 19512,
+ "capability": 25885,
+ "capable": 14742,
+ "capac": 24665,
+ "capacity": 8970,
+ "capcom": 28342,
+ "cape": 10288,
+ "cape": 6631,
+ "capecod": 41339,
+ "capes": 38785,
+ "capetown": 20059,
+ "capit": 6889,
+ "capita": 41833,
+ "capital": 11198,
+ "capital": 5439,
+ "capitalism": 20068,
+ "capitalist": 37015,
+ "capitals": 29579,
+ "capitol": 43880,
+ "capitol": 11375,
+ "capo": 45477,
+ "capp": 16718,
+ "capped": 24659,
+ "capping": 42656,
+ "cappuccino": 37402,
+ "capri": 48699,
+ "capri": 30982,
+ "capric": 28667,
+ "capricorn": 46314,
+ "caps": 23185,
+ "capsu": 15608,
+ "capsul": 40341,
+ "capsule": 20627,
+ "capsules": 32870,
+ "capt": 45815,
+ "capt": 17369,
+ "captain": 14958,
+ "captain": 4621,
+ "captainamerica": 46229,
+ "captainmarvel": 48492,
+ "captains": 18706,
+ "caption": 11327,
+ "captions": 41878,
+ "captiv": 19776,
+ "captivating": 30580,
+ "captive": 29038,
+ "captivity": 41141,
+ "capture": 8818,
+ "captured": 8020,
+ "captures": 15305,
+ "capturing": 19548,
+ "capu": 44241,
+ "car": 811,
+ "car": 1615,
+ "cara": 20016,
+ "carab": 32251,
+ "carac": 30029,
+ "caracas": 45854,
+ "caramel": 14788,
+ "carameli": 41739,
+ "caramelized": 43854,
+ "carat": 32981,
+ "carav": 13814,
+ "caravan": 18566,
+ "carb": 21379,
+ "carbo": 43235,
+ "carbon": 14038,
+ "carbon": 7549,
+ "carbs": 29313,
+ "carcin": 31587,
+ "carcinoma": 46810,
+ "card": 10793,
+ "card": 2601,
+ "cardam": 49008,
+ "cardboard": 19845,
+ "cardi": 6211,
+ "cardi": 29677,
+ "cardiac": 21256,
+ "cardiff": 22488,
+ "cardiff": 9781,
+ "cardigan": 30501,
+ "cardin": 8457,
+ "cardinal": 46310,
+ "cardinal": 16472,
+ "cardinals": 12837,
+ "cardio": 15003,
+ "cardio": 23455,
+ "cardiology": 37276,
+ "cardiovascular": 29291,
+ "cardo": 40625,
+ "cards": 4094,
+ "care": 2050,
+ "care": 1776,
+ "cared": 27675,
+ "career": 20609,
+ "career": 3061,
+ "careers": 10090,
+ "careful": 11999,
+ "carefully": 15789,
+ "caregi": 22042,
+ "caregiver": 46372,
+ "caregivers": 35909,
+ "careless": 47325,
+ "carers": 26484,
+ "cares": 10968,
+ "caretaker": 48037,
+ "carey": 14895,
+ "cargo": 12490,
+ "cari": 18497,
+ "cari": 37273,
+ "carib": 9757,
+ "caribbean": 10368,
+ "caribou": 42135,
+ "caric": 25337,
+ "caricature": 38857,
+ "carina": 44357,
+ "caring": 13083,
+ "carl": 8273,
+ "carl": 9482,
+ "carla": 25552,
+ "carleton": 46496,
+ "carlin": 47559,
+ "carlisle": 23276,
+ "carlo": 17861,
+ "carlo": 15266,
+ "carlos": 9538,
+ "carlow": 44745,
+ "carls": 39635,
+ "carlson": 24114,
+ "carlton": 18934,
+ "carly": 23166,
+ "carly": 22689,
+ "carlyle": 46555,
+ "carmel": 30757,
+ "carmel": 25601,
+ "carmen": 41427,
+ "carmen": 18834,
+ "carmichael": 41657,
+ "carn": 21597,
+ "carnage": 31385,
+ "carnation": 44577,
+ "carnaval": 47238,
+ "carne": 17053,
+ "carne": 42885,
+ "carnegie": 25287,
+ "carney": 34194,
+ "carni": 8438,
+ "carnival": 36708,
+ "carnival": 10577,
+ "caro": 30317,
+ "caro": 29344,
+ "carol": 4242,
+ "carol": 11489,
+ "carole": 31955,
+ "carolin": 26418,
+ "carolina": 7027,
+ "caroline": 31064,
+ "caroline": 12641,
+ "carols": 33269,
+ "carolyn": 25825,
+ "carou": 32224,
+ "carousel": 36665,
+ "carp": 26085,
+ "carpen": 15584,
+ "carpenter": 18475,
+ "carpet": 6922,
+ "carpets": 34612,
+ "carr": 26951,
+ "carr": 17136,
+ "carra": 32332,
+ "carre": 31114,
+ "carrera": 32952,
+ "carri": 4739,
+ "carriage": 47885,
+ "carriage": 21087,
+ "carrick": 44052,
+ "carrie": 30334,
+ "carrie": 15848,
+ "carried": 12960,
+ "carrier": 12308,
+ "carriers": 26865,
+ "carries": 17982,
+ "carrieunderwood": 47338,
+ "carrington": 48759,
+ "carroll": 41911,
+ "carroll": 14893,
+ "carrot": 15435,
+ "carrots": 19299,
+ "carry": 31863,
+ "carry": 6998,
+ "carrying": 9920,
+ "cars": 3346,
+ "carsforsale": 45222,
+ "carson": 41766,
+ "carson": 13171,
+ "cart": 27705,
+ "cart": 13065,
+ "cartag": 45042,
+ "cartagena": 47157,
+ "carte": 44949,
+ "cartel": 30529,
+ "carter": 27330,
+ "carter": 7260,
+ "cartier": 32951,
+ "carto": 5487,
+ "carton": 41812,
+ "cartoon": 33082,
+ "cartoon": 7651,
+ "cartoonist": 30793,
+ "cartoons": 17673,
+ "cartri": 47084,
+ "cartridge": 29432,
+ "cartridges": 49249,
+ "carts": 27581,
+ "cartunesapp": 32888,
+ "caruso": 45192,
+ "carve": 40152,
+ "carved": 15127,
+ "carver": 28850,
+ "carving": 19428,
+ "carvings": 48123,
+ "cary": 22844,
+ "cas": 1671,
+ "cas": 13831,
+ "casa": 14643,
+ "casablanc": 36572,
+ "casablanca": 41950,
+ "casc": 36714,
+ "casca": 43296,
+ "cascade": 29065,
+ "cascades": 46454,
+ "case": 17698,
+ "case": 2068,
+ "cases": 6888,
+ "casey": 24899,
+ "casey": 12836,
+ "cash": 11050,
+ "cash": 5131,
+ "cashback": 36368,
+ "cashe": 32233,
+ "cashew": 39531,
+ "cashi": 29517,
+ "cashier": 34547,
+ "cashmere": 34566,
+ "casi": 38350,
+ "casino": 10473,
+ "casio": 32261,
+ "cask": 26299,
+ "casm": 35198,
+ "casper": 35892,
+ "cass": 22556,
+ "cassandra": 35289,
+ "casser": 31093,
+ "casserole": 36045,
+ "cassette": 19717,
+ "cassi": 14942,
+ "cassidy": 21757,
+ "cassie": 29323,
+ "cassini": 46554,
+ "cast": 2509,
+ "cast": 1970,
+ "caste": 32693,
+ "casted": 33838,
+ "castel": 43306,
+ "castell": 31792,
+ "caster": 32101,
+ "caster": 8449,
+ "casters": 29721,
+ "castic": 47737,
+ "castillo": 30813,
+ "casting": 7087,
+ "castle": 12496,
+ "castle": 3540,
+ "castles": 24766,
+ "castro": 16950,
+ "casts": 10595,
+ "casu": 15345,
+ "casual": 10129,
+ "casually": 18840,
+ "casualties": 30244,
+ "casualty": 31222,
+ "cat": 1481,
+ "cat": 2368,
+ "cata": 42279,
+ "catal": 12792,
+ "catalan": 30532,
+ "catalina": 36576,
+ "catalo": 34740,
+ "catalog": 20036,
+ "catalogue": 20985,
+ "catalonia": 27039,
+ "catalunya": 44132,
+ "cataly": 15894,
+ "catalyst": 25387,
+ "catan": 45893,
+ "catap": 39514,
+ "catar": 35801,
+ "catastro": 22736,
+ "catastrophe": 41422,
+ "catastrophic": 34448,
+ "catch": 18901,
+ "catch": 3042,
+ "catcher": 15965,
+ "catchers": 39060,
+ "catches": 17213,
+ "catching": 8617,
+ "catchy": 37114,
+ "catday": 32243,
+ "cate": 6357,
+ "cate": 24510,
+ "cated": 31823,
+ "categor": 17006,
+ "categori": 40117,
+ "categories": 19971,
+ "category": 9432,
+ "cater": 16634,
+ "cater": 38101,
+ "catering": 16697,
+ "caterpillar": 27111,
+ "catfish": 26077,
+ "cath": 9196,
+ "cath": 30811,
+ "cathar": 43784,
+ "cathe": 7174,
+ "cathedr": 46370,
+ "cathedral": 7865,
+ "catherine": 35035,
+ "catherine": 12339,
+ "catho": 7595,
+ "cathol": 16315,
+ "catholic": 20382,
+ "catholic": 7757,
+ "catholics": 36808,
+ "cathy": 40326,
+ "cathy": 22731,
+ "cation": 21367,
+ "cato": 33558,
+ "cats": 38800,
+ "cats": 3989,
+ "catsofinstagram": 39901,
+ "catsoftwitter": 17273,
+ "catt": 37339,
+ "cattle": 48799,
+ "cattle": 13644,
+ "caturday": 20892,
+ "catwalk": 36565,
+ "catwoman": 47251,
+ "cau": 1121,
+ "cau": 45529,
+ "caucus": 18847,
+ "caught": 4520,
+ "caul": 23460,
+ "cauley": 41682,
+ "caulfield": 44906,
+ "cauli": 20123,
+ "cauliflower": 23802,
+ "cause": 18982,
+ "cause": 1394,
+ "caused": 8940,
+ "causes": 9775,
+ "causeway": 35034,
+ "causing": 10779,
+ "caution": 15656,
+ "cautious": 36579,
+ "cav": 4942,
+ "cav": 45935,
+ "cava": 48682,
+ "caval": 24537,
+ "cavali": 20783,
+ "cavalier": 44488,
+ "cavaliers": 30194,
+ "cavalry": 32467,
+ "cave": 25441,
+ "cave": 9654,
+ "cavendish": 42945,
+ "caver": 41487,
+ "caves": 22096,
+ "cavi": 27360,
+ "caviar": 31228,
+ "cavill": 40492,
+ "cavity": 43156,
+ "cavs": 16800,
+ "caw": 38405,
+ "caw": 43804,
+ "cawx": 26739,
+ "cay": 11876,
+ "cay": 37399,
+ "cayenne": 43650,
+ "cayman": 33737,
+ "caz": 48451,
+ "cb": 4034,
+ "cb": 8830,
+ "cba": 38472,
+ "cbb": 31487,
+ "cbc": 14096,
+ "cbc": 14523,
+ "cbd": 13176,
+ "cbe": 43639,
+ "cbi": 30875,
+ "cbj": 35608,
+ "cbn": 26579,
+ "cbp": 46723,
+ "cbr": 28762,
+ "cbs": 16788,
+ "cbs": 8009,
+ "cc": 2976,
+ "cc": 2021,
+ "cca": 17987,
+ "ccc": 21856,
+ "ccd": 48556,
+ "ccg": 37755,
+ "cch": 21789,
+ "cchini": 28467,
+ "cci": 32942,
+ "cci": 8196,
+ "ccl": 43773,
+ "ccm": 40435,
+ "cco": 28786,
+ "ccot": 24950,
+ "ccp": 43045,
+ "ccs": 30400,
+ "cctv": 23097,
+ "ccu": 49023,
+ "cd": 4308,
+ "cd": 4480,
+ "cda": 45565,
+ "cdc": 41098,
+ "cdc": 25779,
+ "cdn": 8886,
+ "cdn": 26802,
+ "cdnpoli": 11645,
+ "cdo": 47187,
+ "cdp": 39624,
+ "cds": 20784,
+ "cdt": 18455,
+ "ce": 685,
+ "ce": 629,
+ "cea": 28355,
+ "cean": 34409,
+ "cean": 37295,
+ "cease": 32856,
+ "cease": 25499,
+ "ceasefire": 38291,
+ "cebu": 20146,
+ "cec": 29694,
+ "cec": 40029,
+ "cecil": 26987,
+ "cecil": 27169,
+ "cecilia": 35440,
+ "ced": 25634,
+ "ced": 2323,
+ "cedar": 24167,
+ "cedar": 13799,
+ "cedric": 36608,
+ "cee": 45966,
+ "cee": 15015,
+ "cees": 47914,
+ "ceil": 27275,
+ "ceiling": 12374,
+ "ceilings": 33770,
+ "cek": 45544,
+ "cel": 2269,
+ "cel": 7597,
+ "cele": 1314,
+ "celeb": 38862,
+ "celeb": 19393,
+ "celebr": 1372,
+ "celebrate": 31414,
+ "celebrate": 2694,
+ "celebrated": 9184,
+ "celebrates": 7564,
+ "celebrating": 3382,
+ "celebration": 4615,
+ "celebrations": 10825,
+ "celebratory": 34115,
+ "celebrities": 17071,
+ "celebrity": 23981,
+ "celebrity": 7320,
+ "celebs": 19803,
+ "celed": 25741,
+ "celer": 9621,
+ "celery": 30990,
+ "celeste": 29364,
+ "celesti": 29497,
+ "celestial": 32669,
+ "celi": 25567,
+ "celia": 44489,
+ "celine": 33644,
+ "cell": 9316,
+ "cell": 5533,
+ "cellar": 24282,
+ "cellars": 44976,
+ "cellence": 34687,
+ "cello": 23013,
+ "cellphone": 39029,
+ "cells": 8890,
+ "cellu": 16791,
+ "cellular": 23268,
+ "cels": 24021,
+ "celsius": 47057,
+ "celtic": 21897,
+ "celtic": 10523,
+ "celticfc": 38612,
+ "celtics": 16226,
+ "cem": 41435,
+ "ceme": 10517,
+ "cement": 4369,
+ "cements": 19448,
+ "cemetery": 11660,
+ "cen": 1306,
+ "cen": 30106,
+ "cena": 21591,
+ "cence": 24410,
+ "cency": 41259,
+ "cene": 30038,
+ "censor": 24230,
+ "censor": 44709,
+ "censored": 30951,
+ "censorship": 27284,
+ "census": 23677,
+ "cent": 1784,
+ "cent": 3662,
+ "centenary": 22422,
+ "centennial": 20895,
+ "center": 16651,
+ "center": 2119,
+ "centered": 24584,
+ "centers": 14494,
+ "centi": 48889,
+ "centime": 48687,
+ "centr": 2370,
+ "central": 13448,
+ "central": 3339,
+ "centre": 26310,
+ "centre": 2916,
+ "centred": 47925,
+ "centres": 19354,
+ "centri": 30872,
+ "centric": 19297,
+ "centro": 37178,
+ "cents": 11934,
+ "centu": 16818,
+ "centuri": 36816,
+ "centuries": 19014,
+ "century": 26134,
+ "century": 4275,
+ "ceo": 46340,
+ "ceo": 3559,
+ "ceos": 28332,
+ "cep": 2632,
+ "cep": 48714,
+ "ceph": 44343,
+ "cept": 3678,
+ "ception": 12346,
+ "cer": 1364,
+ "cer": 1925,
+ "cera": 34608,
+ "ceram": 10677,
+ "ceramic": 15112,
+ "ceramics": 22438,
+ "cere": 3984,
+ "cere": 22085,
+ "cereal": 17581,
+ "cereals": 48618,
+ "cerebral": 39073,
+ "ceremon": 15796,
+ "ceremonial": 33281,
+ "ceremonies": 21547,
+ "ceremony": 5193,
+ "cern": 44851,
+ "cers": 13638,
+ "cert": 27522,
+ "certain": 8526,
+ "certain": 7883,
+ "certainly": 10883,
+ "certainty": 20054,
+ "certi": 4888,
+ "certific": 9443,
+ "certificate": 11786,
+ "certificates": 25281,
+ "certification": 14735,
+ "certified": 9288,
+ "cerv": 25738,
+ "cervical": 35953,
+ "ces": 28715,
+ "ces": 1604,
+ "cesar": 37025,
+ "cesar": 28603,
+ "cess": 2314,
+ "cess": 1554,
+ "cessna": 36596,
+ "cest": 27245,
+ "cester": 15769,
+ "cester": 12718,
+ "cet": 14960,
+ "cett": 46708,
+ "ceu": 37457,
+ "cevic": 48369,
+ "cey": 20971,
+ "cf": 10189,
+ "cf": 11171,
+ "cfa": 34521,
+ "cfb": 32931,
+ "cfc": 11577,
+ "cfd": 46171,
+ "cfl": 46320,
+ "cfl": 22332,
+ "cfo": 26937,
+ "cfp": 40756,
+ "cfr": 44033,
+ "cfs": 32835,
+ "cg": 27118,
+ "cg": 14740,
+ "cgc": 38775,
+ "cgi": 30520,
+ "ch": 540,
+ "ch": 634,
+ "cha": 1587,
+ "cha": 4541,
+ "chab": 26670,
+ "chad": 13095,
+ "chad": 12923,
+ "chae": 9460,
+ "chaf": 38123,
+ "chag": 27989,
+ "chai": 31590,
+ "chai": 18919,
+ "chain": 13898,
+ "chain": 3946,
+ "chained": 34402,
+ "chains": 14438,
+ "chainsaw": 37617,
+ "chainz": 39687,
+ "chair": 4728,
+ "chair": 4269,
+ "chaired": 31664,
+ "chairing": 42205,
+ "chairman": 6901,
+ "chairperson": 31584,
+ "chairs": 12033,
+ "chak": 13702,
+ "chak": 41713,
+ "chakra": 38304,
+ "chakra": 33241,
+ "chal": 7397,
+ "chal": 30809,
+ "chale": 38099,
+ "chalet": 37907,
+ "chalk": 31362,
+ "chalk": 17846,
+ "chall": 2073,
+ "challeng": 4138,
+ "challenge": 29462,
+ "challenge": 2836,
+ "challenged": 17380,
+ "challenger": 18228,
+ "challengers": 46404,
+ "challenges": 6280,
+ "challenging": 11754,
+ "chalmers": 47955,
+ "cham": 1290,
+ "cham": 19951,
+ "chamber": 18983,
+ "chamber": 7642,
+ "chamberlain": 32756,
+ "chambers": 16501,
+ "chamele": 34759,
+ "chameleon": 41317,
+ "champ": 36813,
+ "champ": 6602,
+ "champag": 10283,
+ "champagne": 11007,
+ "champi": 1680,
+ "champion": 2643,
+ "champion": 3950,
+ "champions": 4227,
+ "championship": 3429,
+ "championships": 7047,
+ "championsleague": 27638,
+ "champs": 6240,
+ "chan": 1255,
+ "chan": 6704,
+ "chana": 48752,
+ "chanc": 13931,
+ "chance": 32940,
+ "chance": 2594,
+ "chancellor": 15886,
+ "chances": 10870,
+ "chand": 7126,
+ "chand": 41508,
+ "chandelier": 30570,
+ "chandi": 12482,
+ "chandigarh": 34106,
+ "chandler": 17595,
+ "chandra": 27082,
+ "chandra": 25348,
+ "chanel": 16951,
+ "chang": 2233,
+ "chang": 16461,
+ "change": 11608,
+ "change": 1799,
+ "changeable": 41335,
+ "changed": 4907,
+ "changer": 18406,
+ "changers": 35185,
+ "changes": 4938,
+ "changing": 40384,
+ "changing": 5621,
+ "changmin": 47410,
+ "chann": 8804,
+ "channel": 25837,
+ "channel": 3847,
+ "channeling": 28197,
+ "channels": 13961,
+ "channing": 37417,
+ "chant": 18165,
+ "chant": 13521,
+ "chanting": 32111,
+ "chants": 22723,
+ "chanyeol": 18805,
+ "chao": 31815,
+ "chaos": 10853,
+ "chaotic": 33501,
+ "chap": 3825,
+ "chap": 21939,
+ "chapel": 40859,
+ "chapel": 10137,
+ "chaplain": 38348,
+ "chaplin": 32545,
+ "chapman": 17968,
+ "chapp": 20634,
+ "chaps": 36823,
+ "chapter": 6014,
+ "chapters": 22936,
+ "char": 1054,
+ "char": 16017,
+ "chara": 35668,
+ "charac": 2792,
+ "character": 10997,
+ "character": 4009,
+ "characterdesign": 38149,
+ "characteri": 20920,
+ "characteristic": 44747,
+ "characteristics": 26037,
+ "characters": 6564,
+ "charan": 31851,
+ "charcoal": 19268,
+ "chard": 17524,
+ "chardon": 26599,
+ "chardonnay": 28161,
+ "charge": 25032,
+ "charge": 5948,
+ "chargeable": 35664,
+ "charged": 7916,
+ "charger": 13090,
+ "chargers": 17352,
+ "charges": 8962,
+ "charging": 12514,
+ "chariot": 38811,
+ "charis": 24449,
+ "charisma": 45041,
+ "charismatic": 37205,
+ "charitable": 23256,
+ "charities": 18493,
+ "charity": 20008,
+ "charity": 4607,
+ "charitytuesday": 42794,
+ "charl": 47736,
+ "charle": 10217,
+ "charles": 27983,
+ "charles": 5127,
+ "charleston": 15478,
+ "charley": 38027,
+ "charli": 21784,
+ "charli": 49392,
+ "charlie": 16764,
+ "charlie": 6393,
+ "charlotte": 18445,
+ "charlotte": 7871,
+ "charlottesville": 32027,
+ "charlton": 27048,
+ "charm": 10876,
+ "charmed": 39790,
+ "charming": 12177,
+ "charms": 21944,
+ "charred": 44085,
+ "chart": 42685,
+ "chart": 5053,
+ "charted": 27939,
+ "charter": 42345,
+ "charter": 13569,
+ "chartered": 31298,
+ "charters": 46626,
+ "charting": 39841,
+ "charts": 10728,
+ "chas": 10717,
+ "chas": 29838,
+ "chase": 21503,
+ "chase": 3859,
+ "chased": 30342,
+ "chaser": 29560,
+ "chasers": 34158,
+ "chases": 45011,
+ "chasing": 46909,
+ "chasing": 13376,
+ "chassis": 29188,
+ "chast": 42176,
+ "chasu": 41352,
+ "chat": 5355,
+ "chat": 2402,
+ "chatbots": 43994,
+ "chate": 30377,
+ "chateau": 44582,
+ "chateau": 23520,
+ "chath": 46849,
+ "chatham": 32030,
+ "chats": 13263,
+ "chatt": 21618,
+ "chattanoo": 28009,
+ "chattanooga": 29866,
+ "chatted": 34124,
+ "chatter": 33473,
+ "chatter": 41103,
+ "chatting": 12401,
+ "chatur": 33839,
+ "chau": 11263,
+ "chau": 37536,
+ "chauffe": 45440,
+ "chauhan": 46663,
+ "chav": 28997,
+ "chavez": 27480,
+ "chaw": 39639,
+ "chay": 45317,
+ "chaz": 47815,
+ "chc": 36233,
+ "chd": 41645,
+ "che": 983,
+ "che": 3842,
+ "chea": 39580,
+ "chead": 48358,
+ "cheap": 27036,
+ "cheap": 8678,
+ "cheape": 26164,
+ "cheaper": 17776,
+ "cheapest": 26640,
+ "cheat": 18180,
+ "cheated": 34285,
+ "cheating": 19722,
+ "chec": 1113,
+ "check": 7672,
+ "check": 1217,
+ "checked": 10387,
+ "checker": 45883,
+ "checkers": 48181,
+ "checking": 7441,
+ "checklist": 26989,
+ "checkout": 13101,
+ "checkpoint": 27531,
+ "checks": 13737,
+ "ched": 11341,
+ "ched": 2146,
+ "cheddar": 20551,
+ "chee": 5326,
+ "chee": 20944,
+ "cheek": 40000,
+ "cheek": 21227,
+ "cheeks": 23019,
+ "cheeky": 15068,
+ "cheer": 9733,
+ "cheer": 6918,
+ "cheered": 38111,
+ "cheerful": 28882,
+ "cheering": 14289,
+ "cheerleader": 29072,
+ "cheerleaders": 22343,
+ "cheerleading": 36366,
+ "cheers": 6562,
+ "chees": 15182,
+ "cheese": 10738,
+ "cheese": 4108,
+ "cheeseburger": 41200,
+ "cheesecake": 17803,
+ "cheeses": 36076,
+ "cheesy": 22093,
+ "cheetah": 27431,
+ "chef": 12137,
+ "chef": 4895,
+ "chefs": 14486,
+ "chek": 43745,
+ "chel": 3084,
+ "chel": 25970,
+ "chell": 46854,
+ "chelle": 30141,
+ "chelms": 34936,
+ "chelmsford": 39890,
+ "chelse": 19071,
+ "chelsea": 6031,
+ "chelseafc": 25927,
+ "chelten": 18889,
+ "cheltenham": 21589,
+ "chem": 5667,
+ "chem": 13698,
+ "chemi": 7179,
+ "chemical": 39376,
+ "chemical": 9208,
+ "chemicals": 17426,
+ "chemist": 23138,
+ "chemistry": 8841,
+ "chemo": 33095,
+ "chemo": 36348,
+ "chemotherapy": 41412,
+ "chemtrails": 46015,
+ "chen": 5907,
+ "chen": 8983,
+ "cheney": 43522,
+ "cheng": 32512,
+ "cheng": 30190,
+ "chenko": 29073,
+ "chennai": 28948,
+ "chennai": 12791,
+ "cheon": 11498,
+ "cheque": 28168,
+ "cher": 3597,
+ "cher": 3466,
+ "cheri": 26471,
+ "cherish": 20053,
+ "cherished": 42325,
+ "cherno": 35376,
+ "chernobyl": 40554,
+ "chero": 19844,
+ "cherokee": 22860,
+ "cherries": 27248,
+ "cherry": 21470,
+ "cherry": 7325,
+ "chers": 5789,
+ "chery": 38478,
+ "cheryl": 37784,
+ "cheryl": 20600,
+ "ches": 18346,
+ "ches": 1910,
+ "chesa": 28349,
+ "chesapeake": 32909,
+ "cheshire": 17130,
+ "chesney": 48747,
+ "chess": 27170,
+ "chess": 8397,
+ "chest": 18217,
+ "chest": 10563,
+ "chester": 10466,
+ "chester": 3343,
+ "chesterfield": 32975,
+ "chestnut": 21834,
+ "chet": 9663,
+ "chett": 24695,
+ "chev": 7152,
+ "chev": 41145,
+ "chevro": 12850,
+ "chevrolet": 13240,
+ "chevron": 33792,
+ "chevy": 16581,
+ "chew": 32645,
+ "chew": 22642,
+ "chewan": 23689,
+ "chewbacca": 49355,
+ "chewing": 31486,
+ "chewy": 42940,
+ "chey": 26968,
+ "chey": 31208,
+ "cheyenne": 34805,
+ "chez": 49183,
+ "chez": 10556,
+ "chf": 33021,
+ "chfield": 41619,
+ "chhat": 34127,
+ "chhattisgarh": 44246,
+ "chi": 1337,
+ "chi": 4039,
+ "chia": 19147,
+ "chiang": 33764,
+ "chibi": 22306,
+ "chic": 2627,
+ "chic": 9091,
+ "chica": 44190,
+ "chicag": 16778,
+ "chicago": 15038,
+ "chicago": 3530,
+ "chicagof": 40638,
+ "chicagofire": 46576,
+ "chicas": 40664,
+ "chichester": 43823,
+ "chick": 3170,
+ "chick": 11238,
+ "chicken": 26322,
+ "chicken": 3717,
+ "chickens": 21658,
+ "chickpea": 48109,
+ "chicks": 17810,
+ "chico": 30379,
+ "chie": 40046,
+ "chie": 12388,
+ "chief": 16830,
+ "chief": 3455,
+ "chiefs": 11419,
+ "chiev": 47761,
+ "chiff": 27407,
+ "chiffon": 31817,
+ "chig": 42952,
+ "chihu": 22857,
+ "chihuahu": 25437,
+ "chihuahua": 30181,
+ "chik": 45455,
+ "chil": 1333,
+ "child": 4392,
+ "child": 2913,
+ "childcare": 31133,
+ "childhood": 34772,
+ "childhood": 7551,
+ "childish": 31939,
+ "childre": 2135,
+ "children": 11101,
+ "children": 2153,
+ "childrens": 31551,
+ "childrens": 21553,
+ "childs": 39521,
+ "chile": 10022,
+ "chilean": 33186,
+ "chili": 13033,
+ "chill": 6498,
+ "chill": 6382,
+ "chilled": 23540,
+ "chillen": 45160,
+ "chilli": 26787,
+ "chilli": 17067,
+ "chillin": 10347,
+ "chilling": 10179,
+ "chillout": 39842,
+ "chills": 25460,
+ "chilly": 14450,
+ "chim": 10543,
+ "chimney": 26821,
+ "chimp": 44374,
+ "chin": 6555,
+ "chin": 8979,
+ "china": 38943,
+ "china": 2817,
+ "chinatown": 28582,
+ "chine": 4013,
+ "chinese": 30568,
+ "chinese": 4271,
+ "ching": 34621,
+ "ching": 1439,
+ "chino": 47181,
+ "chino": 27440,
+ "chinook": 41577,
+ "chinson": 33786,
+ "chio": 19650,
+ "chip": 19271,
+ "chip": 8730,
+ "chipmun": 46384,
+ "chipot": 17702,
+ "chipotle": 19284,
+ "chipp": 39854,
+ "chippe": 46541,
+ "chipped": 39892,
+ "chipping": 40323,
+ "chips": 8855,
+ "chir": 15564,
+ "chiro": 23413,
+ "chiroprac": 25987,
+ "chiropractic": 34437,
+ "chis": 19920,
+ "chistan": 20523,
+ "chiswick": 47290,
+ "chit": 13515,
+ "chit": 45626,
+ "chita": 49184,
+ "chitec": 39862,
+ "chive": 29222,
+ "chives": 34921,
+ "chk": 47424,
+ "chl": 38592,
+ "chley": 47748,
+ "chlo": 10374,
+ "chloe": 39966,
+ "chloe": 13992,
+ "chlor": 23135,
+ "chman": 35835,
+ "chment": 20848,
+ "chner": 48277,
+ "cho": 1327,
+ "cho": 5150,
+ "choa": 43077,
+ "choc": 32772,
+ "choc": 21983,
+ "choco": 46285,
+ "choco": 32692,
+ "chocol": 3443,
+ "chocolat": 44631,
+ "chocolate": 29389,
+ "chocolate": 3820,
+ "chocolates": 24120,
+ "choi": 23749,
+ "choic": 35606,
+ "choice": 23857,
+ "choice": 4051,
+ "choices": 11016,
+ "choir": 9214,
+ "choirs": 43277,
+ "choke": 30231,
+ "choked": 43521,
+ "choker": 39642,
+ "choking": 39993,
+ "chol": 19802,
+ "cholera": 45999,
+ "cholester": 26861,
+ "cholesterol": 27982,
+ "chom": 25151,
+ "chon": 20416,
+ "chon": 21601,
+ "chondri": 37379,
+ "chong": 26220,
+ "choo": 3869,
+ "choo": 24437,
+ "chool": 29578,
+ "chools": 41958,
+ "choose": 22756,
+ "choose": 5073,
+ "chooses": 29923,
+ "choosing": 13475,
+ "chop": 10458,
+ "chop": 16663,
+ "chopin": 42256,
+ "chopped": 22580,
+ "chopper": 24011,
+ "chopping": 35375,
+ "chopra": 24258,
+ "chops": 26321,
+ "chor": 7567,
+ "chor": 47795,
+ "choral": 26684,
+ "chord": 33005,
+ "chords": 36152,
+ "choreo": 17443,
+ "choreographer": 35952,
+ "choreography": 32749,
+ "chores": 40483,
+ "chori": 25718,
+ "chorizo": 30802,
+ "chorus": 20869,
+ "chos": 26559,
+ "chose": 11090,
+ "chosen": 10044,
+ "chou": 16960,
+ "chou": 42917,
+ "choudhary": 45503,
+ "chow": 20257,
+ "chow": 21657,
+ "chowder": 37886,
+ "chp": 35896,
+ "chr": 36918,
+ "chri": 1135,
+ "chris": 9907,
+ "chris": 2978,
+ "chrisbrown": 41035,
+ "chriss": 46745,
+ "chrissy": 44762,
+ "chrissy": 40485,
+ "christ": 1403,
+ "christ": 6703,
+ "christchurch": 27100,
+ "christen": 31956,
+ "christensen": 42226,
+ "christi": 3328,
+ "christi": 33213,
+ "christian": 11792,
+ "christian": 4729,
+ "christianity": 20000,
+ "christians": 14842,
+ "christie": 16084,
+ "christin": 30189,
+ "christina": 15925,
+ "christine": 42610,
+ "christine": 14712,
+ "christma": 12039,
+ "christmas": 18174,
+ "christmas": 1677,
+ "christmaseve": 44381,
+ "christmass": 44873,
+ "christop": 7917,
+ "christoph": 47844,
+ "christophe": 45486,
+ "christopher": 33349,
+ "christopher": 9630,
+ "christy": 28331,
+ "chro": 13207,
+ "chromatic": 44207,
+ "chrome": 24843,
+ "chrome": 9529,
+ "chromo": 35809,
+ "chron": 5577,
+ "chron": 39781,
+ "chronic": 10115,
+ "chronic": 13677,
+ "chronicle": 20034,
+ "chronicles": 18905,
+ "chrono": 29387,
+ "chronograph": 38397,
+ "chry": 13508,
+ "chrysler": 20078,
+ "chs": 40277,
+ "chs": 8391,
+ "chsnews": 44919,
+ "cht": 11384,
+ "chter": 47811,
+ "chu": 3799,
+ "chu": 13622,
+ "chubby": 29109,
+ "chuck": 13211,
+ "chuck": 9894,
+ "chuckle": 35733,
+ "chucky": 42026,
+ "chuffed": 27233,
+ "chuk": 25878,
+ "chuk": 27221,
+ "chul": 33001,
+ "chum": 46869,
+ "chum": 41767,
+ "chun": 14693,
+ "chun": 25391,
+ "chung": 28418,
+ "chunk": 30275,
+ "chunks": 45538,
+ "chunky": 27978,
+ "chups": 46331,
+ "chur": 2309,
+ "church": 14956,
+ "church": 2735,
+ "churches": 15539,
+ "churchill": 17527,
+ "chus": 36246,
+ "chut": 28788,
+ "chutney": 36261,
+ "chy": 15131,
+ "chy": 8096,
+ "chyna": 43398,
+ "châ": 48669,
+ "ci": 698,
+ "ci": 5798,
+ "cia": 4019,
+ "cial": 1143,
+ "cian": 32323,
+ "ciao": 37677,
+ "ciara": 31369,
+ "cible": 28873,
+ "cic": 14539,
+ "cic": 21517,
+ "cid": 27359,
+ "cide": 34178,
+ "cider": 13547,
+ "cides": 41326,
+ "cie": 19730,
+ "cier": 24067,
+ "cies": 6785,
+ "cif": 35698,
+ "cigar": 26031,
+ "cigar": 16525,
+ "cigare": 13044,
+ "cigarette": 18548,
+ "cigarettes": 22750,
+ "cigars": 20750,
+ "cii": 42408,
+ "cil": 9217,
+ "cil": 2998,
+ "cilan": 33998,
+ "cilantro": 34568,
+ "cili": 18977,
+ "ciliation": 25294,
+ "cim": 30021,
+ "cin": 2396,
+ "cin": 25367,
+ "cina": 39467,
+ "cincin": 13291,
+ "cincinnati": 14197,
+ "cinco": 25131,
+ "cincode": 40930,
+ "cincodemayo": 42542,
+ "cincy": 30015,
+ "cincy": 30286,
+ "cinde": 20660,
+ "cinderella": 21515,
+ "cindy": 34439,
+ "cindy": 18532,
+ "cine": 4015,
+ "cine": 27451,
+ "cinema": 38251,
+ "cinema": 6443,
+ "cinemas": 14845,
+ "cinematic": 25602,
+ "cinemato": 21919,
+ "cinematographer": 39059,
+ "cinematography": 33802,
+ "ciner": 39882,
+ "cing": 4014,
+ "cini": 25699,
+ "cinnam": 12768,
+ "cinnamon": 13460,
+ "cino": 18616,
+ "cio": 44584,
+ "cio": 9954,
+ "cion": 22024,
+ "ciones": 37155,
+ "cious": 38466,
+ "cip": 32884,
+ "cir": 2459,
+ "cir": 41135,
+ "circa": 10411,
+ "circle": 33574,
+ "circle": 7117,
+ "circles": 19411,
+ "circling": 46036,
+ "circu": 5143,
+ "circuit": 35583,
+ "circuit": 9801,
+ "circuits": 33260,
+ "circul": 16618,
+ "circular": 19733,
+ "circulare": 39525,
+ "circulareconomy": 39878,
+ "circulated": 46258,
+ "circulating": 42980,
+ "circulation": 27880,
+ "circum": 13406,
+ "circumstances": 18786,
+ "circus": 11833,
+ "cirque": 36049,
+ "cis": 9459,
+ "cis": 23513,
+ "cisco": 36689,
+ "cisco": 19290,
+ "cise": 19657,
+ "cisely": 33434,
+ "cision": 41957,
+ "cism": 24166,
+ "cist": 40906,
+ "cit": 4420,
+ "cit": 31294,
+ "citadel": 38036,
+ "citation": 33581,
+ "cite": 32641,
+ "cited": 25069,
+ "cites": 34490,
+ "citi": 4280,
+ "citi": 30270,
+ "cities": 5441,
+ "citing": 29088,
+ "citiz": 5816,
+ "citizen": 11720,
+ "citizen": 9814,
+ "citizens": 7949,
+ "citizenship": 17386,
+ "cito": 42636,
+ "citro": 27941,
+ "citroen": 35805,
+ "citrus": 17379,
+ "city": 5002,
+ "city": 1305,
+ "cityfc": 28751,
+ "cityo": 25709,
+ "cityof": 11595,
+ "cityscape": 40808,
+ "ciu": 39693,
+ "cius": 42559,
+ "civ": 40039,
+ "civic": 32240,
+ "civic": 11888,
+ "civil": 6923,
+ "civil": 6450,
+ "civilian": 21187,
+ "civilians": 18076,
+ "civilization": 22503,
+ "civilwar": 34524,
+ "ción": 44700,
+ "cj": 15238,
+ "cj": 15205,
+ "ck": 916,
+ "ck": 868,
+ "cke": 25224,
+ "cke": 40989,
+ "cked": 3441,
+ "cken": 25566,
+ "cker": 15509,
+ "cker": 4744,
+ "ckers": 37073,
+ "cket": 5525,
+ "ckett": 33899,
+ "ckey": 15029,
+ "ckey": 3657,
+ "cki": 36916,
+ "cki": 41055,
+ "cking": 4805,
+ "cko": 28818,
+ "cks": 2031,
+ "cky": 26229,
+ "cky": 3083,
+ "cl": 969,
+ "cl": 6482,
+ "cla": 940,
+ "cla": 20636,
+ "clad": 31606,
+ "cladding": 46411,
+ "clai": 29459,
+ "claim": 4290,
+ "claim": 6607,
+ "claimed": 9010,
+ "claiming": 15286,
+ "claims": 6852,
+ "clair": 31441,
+ "clair": 14039,
+ "claire": 20410,
+ "claire": 10460,
+ "clam": 13588,
+ "clam": 32598,
+ "clamation": 21793,
+ "clamp": 41501,
+ "clams": 38849,
+ "clan": 29252,
+ "clan": 14114,
+ "clancy": 37227,
+ "clans": 38279,
+ "clap": 30037,
+ "clap": 25546,
+ "clapham": 43619,
+ "clapton": 37683,
+ "clar": 3617,
+ "clara": 19468,
+ "clare": 18948,
+ "clare": 15927,
+ "claremont": 47789,
+ "clarence": 29320,
+ "clari": 15175,
+ "clarify": 37004,
+ "clarinet": 41178,
+ "clarity": 21323,
+ "clark": 13340,
+ "clark": 7521,
+ "clarke": 11548,
+ "clarkson": 25706,
+ "clas": 32003,
+ "clash": 38367,
+ "clash": 9359,
+ "clashes": 25193,
+ "clasico": 43567,
+ "class": 2876,
+ "class": 1874,
+ "classes": 6919,
+ "classi": 2507,
+ "classic": 9353,
+ "classic": 2713,
+ "classical": 22179,
+ "classical": 11355,
+ "classicalmusic": 27806,
+ "classiccar": 46906,
+ "classiccars": 21064,
+ "classics": 10634,
+ "classification": 26612,
+ "classified": 22056,
+ "classmate": 37090,
+ "classmates": 30062,
+ "classof": 25345,
+ "classroom": 9001,
+ "classrooms": 25768,
+ "classy": 11615,
+ "clau": 7526,
+ "claude": 17461,
+ "claudi": 39439,
+ "claudia": 21893,
+ "claudio": 31230,
+ "claus": 23317,
+ "clause": 26151,
+ "clave": 24111,
+ "claw": 49230,
+ "claw": 19106,
+ "claws": 29161,
+ "clay": 10402,
+ "clay": 8823,
+ "clays": 26128,
+ "clayton": 46445,
+ "clayton": 19413,
+ "clc": 31380,
+ "cle": 1321,
+ "cle": 2537,
+ "clean": 3572,
+ "clean": 3772,
+ "cleaned": 17468,
+ "cleanenergy": 43538,
+ "cleaner": 15619,
+ "cleaners": 33258,
+ "cleaning": 7210,
+ "cleanliness": 47886,
+ "cleans": 40827,
+ "cleanse": 28717,
+ "cleanser": 44170,
+ "cleansing": 25931,
+ "cleanup": 22353,
+ "clear": 4631,
+ "clear": 3143,
+ "clearance": 17959,
+ "cleared": 14880,
+ "clearer": 37031,
+ "clearing": 15481,
+ "clearly": 7767,
+ "clears": 29092,
+ "clearwater": 32124,
+ "cleary": 44342,
+ "cleats": 33486,
+ "cleavage": 44165,
+ "cled": 12827,
+ "clegg": 42915,
+ "clemens": 45896,
+ "clement": 22592,
+ "clement": 24714,
+ "clemente": 42461,
+ "clementine": 47112,
+ "clements": 49175,
+ "clemson": 38170,
+ "clemson": 19537,
+ "clen": 35547,
+ "cleo": 40344,
+ "cleop": 36287,
+ "cleopatra": 41212,
+ "cler": 11828,
+ "clergy": 42635,
+ "cleric": 43748,
+ "clerk": 22230,
+ "clermont": 47529,
+ "cles": 8077,
+ "cleve": 37599,
+ "clevel": 7701,
+ "cleveland": 30716,
+ "cleveland": 8430,
+ "clever": 30977,
+ "clever": 13385,
+ "clg": 47546,
+ "cli": 1503,
+ "clich": 44407,
+ "click": 16676,
+ "click": 3585,
+ "clicked": 29015,
+ "clicking": 26542,
+ "clicks": 31250,
+ "client": 48528,
+ "client": 7467,
+ "clients": 8114,
+ "clif": 13182,
+ "cliff": 23827,
+ "cliff": 10625,
+ "cliffe": 15170,
+ "clifford": 24226,
+ "cliffs": 20953,
+ "clifton": 23878,
+ "climat": 37283,
+ "climate": 7854,
+ "climate": 4589,
+ "climateaction": 31622,
+ "climatechange": 11055,
+ "climates": 46022,
+ "climax": 37033,
+ "climb": 7421,
+ "climb": 10649,
+ "climbed": 22528,
+ "climber": 36910,
+ "climbers": 47648,
+ "climbing": 9877,
+ "climbs": 29098,
+ "clin": 2879,
+ "clinch": 30404,
+ "clinched": 44064,
+ "cline": 37460,
+ "cling": 37068,
+ "cling": 4760,
+ "clinic": 7926,
+ "clinical": 35133,
+ "clinical": 9148,
+ "clinicians": 45866,
+ "clinics": 23330,
+ "clint": 37542,
+ "clint": 21160,
+ "clinton": 34403,
+ "clinton": 5820,
+ "clio": 46889,
+ "clip": 39712,
+ "clip": 9289,
+ "clipped": 45524,
+ "clipper": 42245,
+ "clippers": 23319,
+ "clipping": 47484,
+ "clips": 16594,
+ "clique": 34983,
+ "clive": 36086,
+ "clive": 21509,
+ "cll": 46091,
+ "cllr": 45743,
+ "cllr": 23034,
+ "clo": 1194,
+ "cloak": 36528,
+ "clock": 19878,
+ "clock": 6716,
+ "clocked": 49049,
+ "clocks": 25895,
+ "clockwise": 46150,
+ "clockwork": 42297,
+ "clon": 24477,
+ "clone": 22854,
+ "clones": 48047,
+ "clooney": 33161,
+ "clos": 48821,
+ "close": 10603,
+ "close": 2660,
+ "closed": 4552,
+ "closely": 13478,
+ "closer": 6377,
+ "closes": 11354,
+ "closest": 14975,
+ "closet": 14221,
+ "closeup": 35439,
+ "closing": 7101,
+ "closure": 13249,
+ "closures": 22923,
+ "cloth": 14559,
+ "clothes": 7080,
+ "clothing": 7425,
+ "clou": 4069,
+ "cloud": 12965,
+ "cloud": 3887,
+ "cloudcomputing": 41390,
+ "clouds": 6244,
+ "cloudy": 13106,
+ "clough": 42909,
+ "clover": 39574,
+ "clover": 22812,
+ "clow": 18386,
+ "clown": 15329,
+ "clowns": 30820,
+ "cls": 44251,
+ "clt": 29651,
+ "clt": 24236,
+ "clu": 996,
+ "club": 9642,
+ "club": 1736,
+ "clubbing": 48128,
+ "clubhouse": 26553,
+ "clubs": 9437,
+ "clue": 14994,
+ "clueless": 35350,
+ "clues": 23764,
+ "clusive": 41362,
+ "cluster": 15595,
+ "clusters": 33217,
+ "clut": 28507,
+ "clutch": 13953,
+ "clutter": 40804,
+ "cly": 12037,
+ "clyde": 39557,
+ "clyde": 18469,
+ "cm": 10190,
+ "cm": 3741,
+ "cma": 30554,
+ "cma": 31388,
+ "cmc": 45839,
+ "cmdr": 48250,
+ "cme": 34946,
+ "cmo": 24589,
+ "cmon": 42904,
+ "cmp": 46355,
+ "cms": 22520,
+ "cmt": 42727,
+ "cmu": 43046,
+ "cn": 3886,
+ "cn": 16200,
+ "cna": 48287,
+ "cnbc": 41242,
+ "cnbc": 24371,
+ "cnblue": 36018,
+ "cnc": 20571,
+ "cnet": 47487,
+ "cnews": 24319,
+ "cng": 41496,
+ "cnn": 22405,
+ "cnn": 8259,
+ "cns": 46095,
+ "cny": 31614,
+ "co": 622,
+ "co": 1320,
+ "coa": 29167,
+ "coach": 3275,
+ "coach": 2312,
+ "coached": 30228,
+ "coachella": 20222,
+ "coaches": 6924,
+ "coaching": 7766,
+ "coal": 10227,
+ "coal": 7919,
+ "coalition": 12920,
+ "coast": 6398,
+ "coast": 3720,
+ "coastal": 38246,
+ "coastal": 10852,
+ "coaster": 15944,
+ "coasters": 31548,
+ "coastguard": 40601,
+ "coastline": 27959,
+ "coasts": 42225,
+ "coat": 28869,
+ "coat": 7356,
+ "coated": 23401,
+ "coates": 36899,
+ "coating": 25369,
+ "coatings": 48706,
+ "coats": 18075,
+ "cob": 20140,
+ "cob": 32863,
+ "cobain": 36866,
+ "cobalt": 30896,
+ "cobb": 22719,
+ "cobble": 47894,
+ "cobra": 21574,
+ "coc": 23036,
+ "coc": 39498,
+ "coca": 21197,
+ "cocac": 26393,
+ "cocacola": 31248,
+ "cocaine": 20534,
+ "coch": 18599,
+ "cochran": 48798,
+ "cochrane": 41752,
+ "coco": 11850,
+ "coco": 13316,
+ "cocoa": 18074,
+ "cocon": 8597,
+ "coconut": 9581,
+ "cod": 16132,
+ "cod": 11915,
+ "code": 11582,
+ "code": 3217,
+ "coded": 33703,
+ "coden": 43914,
+ "coder": 41561,
+ "codes": 14566,
+ "codi": 39711,
+ "coding": 12647,
+ "cody": 23222,
+ "cody": 12666,
+ "coe": 15386,
+ "coed": 41028,
+ "coel": 45633,
+ "coer": 41198,
+ "coeur": 44986,
+ "coffe": 2255,
+ "coffee": 12898,
+ "coffee": 2453,
+ "coffees": 41184,
+ "coffey": 48066,
+ "cofficial": 18757,
+ "coffin": 29907,
+ "cog": 26362,
+ "cog": 35960,
+ "cogn": 12210,
+ "cognac": 44361,
+ "cognition": 46825,
+ "cognitive": 16584,
+ "cohe": 20669,
+ "cohen": 13381,
+ "coherent": 48450,
+ "cohort": 22782,
+ "coil": 25307,
+ "coim": 41528,
+ "coin": 14651,
+ "coin": 4170,
+ "coinci": 14015,
+ "coincidence": 19807,
+ "coins": 10530,
+ "coke": 39602,
+ "coke": 14035,
+ "col": 754,
+ "col": 9371,
+ "cola": 15444,
+ "colbert": 31647,
+ "colby": 32068,
+ "colchester": 31715,
+ "cold": 11146,
+ "cold": 3153,
+ "colder": 23859,
+ "coldest": 31438,
+ "coldplay": 27770,
+ "cole": 9305,
+ "cole": 8166,
+ "coleman": 15774,
+ "coles": 40265,
+ "coles": 30398,
+ "coli": 18877,
+ "coli": 15910,
+ "colin": 20989,
+ "colin": 10238,
+ "coliseum": 21836,
+ "coll": 25982,
+ "coll": 23898,
+ "colla": 2929,
+ "collab": 14013,
+ "collabor": 4437,
+ "collaborate": 21271,
+ "collaborated": 42265,
+ "collaborating": 25545,
+ "collaboration": 6642,
+ "collaborations": 36520,
+ "collaborative": 15841,
+ "collaborator": 48186,
+ "collaborators": 45901,
+ "collage": 11258,
+ "collagen": 36120,
+ "collap": 16881,
+ "collapse": 16520,
+ "collapsed": 25037,
+ "collapses": 43601,
+ "collar": 39662,
+ "collar": 13497,
+ "collateral": 44512,
+ "colle": 1801,
+ "colleague": 13067,
+ "colleagues": 8203,
+ "collec": 1733,
+ "collect": 10186,
+ "collected": 11980,
+ "collecti": 18530,
+ "collectible": 25680,
+ "collectibles": 21519,
+ "collecting": 10325,
+ "collection": 2548,
+ "collections": 12760,
+ "collective": 10162,
+ "collectively": 40687,
+ "collector": 13522,
+ "collectors": 20540,
+ "collects": 31576,
+ "colleen": 31020,
+ "college": 13512,
+ "college": 2229,
+ "colleges": 17357,
+ "collegi": 16311,
+ "collegiate": 18068,
+ "colli": 8262,
+ "collide": 27214,
+ "collie": 30611,
+ "collier": 35748,
+ "collin": 24056,
+ "collin": 32116,
+ "colling": 32319,
+ "collingwood": 45873,
+ "collins": 8684,
+ "collision": 15407,
+ "collo": 25115,
+ "colloqui": 37243,
+ "colloquium": 46514,
+ "collu": 25658,
+ "collusion": 33864,
+ "colo": 7300,
+ "colo": 27288,
+ "cologne": 22216,
+ "cology": 19187,
+ "colom": 8987,
+ "colombia": 12901,
+ "colombian": 28701,
+ "colombo": 33207,
+ "colon": 8280,
+ "colon": 29050,
+ "colonel": 22674,
+ "coloni": 22667,
+ "colonial": 16530,
+ "colonialism": 43385,
+ "colonies": 38738,
+ "colony": 18767,
+ "color": 4036,
+ "color": 3140,
+ "colorado": 34580,
+ "colorado": 6742,
+ "colorec": 41171,
+ "colored": 11775,
+ "colorful": 11444,
+ "colori": 28764,
+ "coloring": 17696,
+ "colorized": 46730,
+ "colors": 5389,
+ "colorstv": 28195,
+ "colorway": 44576,
+ "colossal": 40258,
+ "colosse": 48142,
+ "colossus": 34022,
+ "colour": 10240,
+ "colour": 4769,
+ "coloured": 17111,
+ "colourful": 15562,
+ "colouring": 31803,
+ "colours": 7626,
+ "cols": 35726,
+ "colt": 19726,
+ "colton": 32249,
+ "coltrane": 42333,
+ "colts": 16135,
+ "colum": 4164,
+ "columb": 31043,
+ "columbi": 25947,
+ "columbia": 9410,
+ "columbus": 11273,
+ "column": 10593,
+ "columnist": 28958,
+ "columns": 29056,
+ "com": 610,
+ "com": 2464,
+ "coma": 19620,
+ "comb": 3587,
+ "comb": 16380,
+ "combat": 35083,
+ "combat": 9275,
+ "combating": 46121,
+ "combe": 14363,
+ "combin": 25112,
+ "combination": 11312,
+ "combinations": 34950,
+ "combine": 12919,
+ "combined": 10427,
+ "combines": 22991,
+ "combining": 23561,
+ "combo": 10155,
+ "combos": 48117,
+ "combs": 30694,
+ "combu": 35629,
+ "combustion": 44654,
+ "comcast": 30043,
+ "come": 4225,
+ "come": 891,
+ "comeback": 8234,
+ "comedian": 13848,
+ "comedians": 33758,
+ "comedic": 43360,
+ "comedy": 19346,
+ "comedy": 4749,
+ "comer": 42997,
+ "comer": 20916,
+ "comers": 34436,
+ "comes": 2091,
+ "comet": 21405,
+ "comets": 40636,
+ "comey": 22957,
+ "comfor": 6563,
+ "comfort": 44000,
+ "comfort": 7808,
+ "comfortable": 8652,
+ "comfortably": 30392,
+ "comforting": 33835,
+ "comforts": 42243,
+ "comfy": 15736,
+ "comi": 40781,
+ "comic": 7729,
+ "comic": 4962,
+ "comicart": 46018,
+ "comicbook": 46564,
+ "comicbooks": 22018,
+ "comiccon": 18379,
+ "comicon": 43820,
+ "comics": 4256,
+ "comin": 18164,
+ "coming": 14916,
+ "coming": 1171,
+ "comingsoon": 19894,
+ "comm": 965,
+ "comm": 11413,
+ "comman": 39780,
+ "command": 18391,
+ "command": 11350,
+ "commander": 11265,
+ "commanders": 41667,
+ "commanding": 36933,
+ "commandments": 43409,
+ "commando": 31361,
+ "commands": 38163,
+ "comme": 29692,
+ "commemor": 9495,
+ "commemorate": 21242,
+ "commemorates": 45149,
+ "commemorating": 28734,
+ "commemoration": 29288,
+ "commemorative": 24623,
+ "commen": 15795,
+ "commence": 25059,
+ "commenced": 43908,
+ "commencement": 21666,
+ "commences": 48551,
+ "commend": 37555,
+ "commended": 40702,
+ "comment": 20035,
+ "comment": 5761,
+ "commentary": 14146,
+ "commentator": 32016,
+ "commented": 28328,
+ "commenting": 37292,
+ "comments": 6606,
+ "commer": 4028,
+ "commerce": 8333,
+ "commerci": 15601,
+ "commercial": 31802,
+ "commercial": 6287,
+ "commercials": 30724,
+ "commish": 45399,
+ "commissi": 6000,
+ "commission": 5292,
+ "commissioned": 16565,
+ "commissioner": 10221,
+ "commissioners": 30702,
+ "commissioning": 29585,
+ "commissions": 20668,
+ "commit": 3041,
+ "commit": 11797,
+ "commitment": 7770,
+ "commitments": 32136,
+ "commits": 20241,
+ "committed": 7907,
+ "committee": 5636,
+ "committees": 40504,
+ "committing": 21937,
+ "commod": 9496,
+ "commodities": 30350,
+ "commodity": 29041,
+ "commodore": 31129,
+ "common": 8414,
+ "common": 4176,
+ "commonly": 20344,
+ "commons": 16653,
+ "commonwealth": 16569,
+ "comms": 18832,
+ "commu": 9561,
+ "commun": 1515,
+ "communal": 32809,
+ "communi": 16164,
+ "communic": 4784,
+ "communicate": 19809,
+ "communication": 7999,
+ "communications": 10052,
+ "communion": 28579,
+ "communism": 35387,
+ "communist": 18602,
+ "communities": 6361,
+ "community": 14784,
+ "community": 1927,
+ "commute": 15898,
+ "commuter": 27782,
+ "commuters": 30823,
+ "commuting": 43503,
+ "como": 16236,
+ "comp": 2561,
+ "comp": 11679,
+ "compac": 40014,
+ "compact": 13690,
+ "compan": 1995,
+ "companies": 5361,
+ "companion": 14963,
+ "companions": 37124,
+ "company": 2634,
+ "compar": 7580,
+ "comparable": 27092,
+ "comparative": 33388,
+ "compare": 13771,
+ "compared": 10544,
+ "compares": 25104,
+ "comparing": 20564,
+ "comparison": 14186,
+ "comparisons": 40870,
+ "compart": 30072,
+ "compartment": 40383,
+ "compass": 19438,
+ "compassion": 14463,
+ "compassionate": 30193,
+ "compati": 17295,
+ "compatibility": 41614,
+ "compatible": 21286,
+ "compe": 5254,
+ "compelled": 49375,
+ "compelling": 21766,
+ "compen": 42079,
+ "compens": 15172,
+ "compensation": 18663,
+ "compet": 2932,
+ "compete": 10038,
+ "competed": 27767,
+ "competen": 31853,
+ "competence": 31165,
+ "competency": 49293,
+ "competent": 28113,
+ "competes": 39826,
+ "competing": 13068,
+ "competit": 15892,
+ "competiti": 32581,
+ "competition": 3742,
+ "competitions": 23259,
+ "competitive": 10687,
+ "competitiveness": 43209,
+ "competitor": 26633,
+ "competitors": 23638,
+ "compilation": 20446,
+ "compiled": 34579,
+ "compla": 7428,
+ "complain": 19292,
+ "complained": 42029,
+ "complaining": 20812,
+ "complains": 46363,
+ "complaint": 20391,
+ "complaints": 20020,
+ "comple": 1730,
+ "complement": 36624,
+ "complementary": 48953,
+ "complete": 3263,
+ "completed": 5976,
+ "completely": 5989,
+ "completes": 19321,
+ "completing": 14949,
+ "completion": 15915,
+ "complex": 16099,
+ "complex": 6324,
+ "complexes": 47870,
+ "complexion": 47732,
+ "complexity": 24815,
+ "compli": 5270,
+ "compliance": 14658,
+ "compliant": 29893,
+ "complic": 11460,
+ "complicated": 16621,
+ "complications": 29936,
+ "compliment": 25116,
+ "complimentary": 20948,
+ "compliments": 25477,
+ "comply": 36281,
+ "component": 21284,
+ "components": 16816,
+ "compos": 7783,
+ "compose": 43659,
+ "composed": 19916,
+ "composer": 12104,
+ "composers": 33314,
+ "composing": 40412,
+ "composite": 21606,
+ "composites": 45395,
+ "composition": 17510,
+ "compositions": 44652,
+ "compost": 46002,
+ "compost": 33307,
+ "compound": 19980,
+ "compounds": 33991,
+ "compre": 8483,
+ "compreh": 42976,
+ "comprehen": 12050,
+ "comprehend": 48230,
+ "comprehensive": 13854,
+ "compress": 33353,
+ "compressed": 42359,
+ "compression": 25638,
+ "compressor": 39607,
+ "compri": 29445,
+ "compromise": 26611,
+ "compromised": 38576,
+ "compromising": 45436,
+ "comps": 48665,
+ "compton": 28364,
+ "compu": 11639,
+ "compul": 25869,
+ "compulsory": 39345,
+ "computing": 12732,
+ "comra": 25553,
+ "comrade": 30844,
+ "comrades": 29282,
+ "coms": 30493,
+ "con": 616,
+ "con": 2457,
+ "cona": 30605,
+ "conan": 24750,
+ "conce": 9145,
+ "concealed": 35419,
+ "conceded": 37895,
+ "conceived": 39725,
+ "concentr": 11085,
+ "concentrate": 30846,
+ "concentrated": 36776,
+ "concentration": 18565,
+ "concep": 8389,
+ "concepcion": 47035,
+ "concept": 6353,
+ "conceptart": 31162,
+ "conception": 30510,
+ "conceptions": 40307,
+ "concepts": 16763,
+ "conceptu": 42745,
+ "conceptual": 34070,
+ "concer": 2228,
+ "concern": 12928,
+ "concerned": 12020,
+ "concerning": 21772,
+ "concerns": 11134,
+ "concert": 32180,
+ "concert": 3066,
+ "concerto": 24710,
+ "concerts": 14418,
+ "concession": 38117,
+ "concessions": 43981,
+ "concier": 28859,
+ "concierge": 39850,
+ "conclave": 38098,
+ "conclu": 9627,
+ "conclude": 37525,
+ "concluded": 27825,
+ "concludes": 30634,
+ "conclusion": 20932,
+ "conclusions": 39507,
+ "conco": 43034,
+ "concor": 19913,
+ "concord": 26448,
+ "concordia": 35492,
+ "concours": 36282,
+ "concourse": 37793,
+ "concre": 43658,
+ "concrete": 9637,
+ "concussion": 28321,
+ "condem": 13287,
+ "condemn": 27212,
+ "condemned": 35145,
+ "condemns": 32092,
+ "conden": 24816,
+ "conditi": 11170,
+ "condition": 36978,
+ "condition": 7336,
+ "conditional": 24671,
+ "conditioned": 37014,
+ "conditioner": 31239,
+ "conditioning": 18181,
+ "conditions": 5892,
+ "condo": 19952,
+ "condol": 18661,
+ "condolences": 20836,
+ "condom": 39021,
+ "condomin": 42589,
+ "condoms": 37878,
+ "condor": 47643,
+ "condos": 42342,
+ "condu": 40772,
+ "conduc": 5379,
+ "conduct": 11647,
+ "conducted": 13080,
+ "conducting": 16787,
+ "conductor": 22317,
+ "conducts": 32084,
+ "cone": 39279,
+ "cone": 10266,
+ "cones": 26718,
+ "coney": 41837,
+ "conf": 6477,
+ "confe": 1968,
+ "confeder": 17104,
+ "confederate": 24864,
+ "confederation": 43484,
+ "conferen": 37961,
+ "conference": 2230,
+ "conferences": 22811,
+ "conferencing": 47320,
+ "confess": 38860,
+ "confession": 22572,
+ "confessions": 29404,
+ "confetti": 37923,
+ "confi": 5005,
+ "confidence": 8510,
+ "confident": 12365,
+ "confidential": 28712,
+ "configu": 46746,
+ "configur": 26950,
+ "configuration": 33378,
+ "confin": 45316,
+ "confined": 40973,
+ "confir": 3930,
+ "confirm": 12130,
+ "confirmation": 19645,
+ "confirmed": 6346,
+ "confirming": 38433,
+ "confirms": 11803,
+ "confis": 36285,
+ "confit": 42241,
+ "confl": 8173,
+ "conflic": 19029,
+ "conflict": 10397,
+ "conflicting": 43894,
+ "conflicts": 28713,
+ "confor": 40933,
+ "confron": 20033,
+ "confront": 38382,
+ "confrontation": 41478,
+ "confu": 6890,
+ "confuse": 37503,
+ "confused": 10946,
+ "confusing": 24683,
+ "confusion": 20493,
+ "cong": 24407,
+ "conge": 20013,
+ "congestion": 24432,
+ "congo": 20334,
+ "congr": 1227,
+ "congrats": 1887,
+ "congratul": 1750,
+ "congratulate": 16633,
+ "congratulated": 42004,
+ "congratulates": 24580,
+ "congratulating": 30967,
+ "congratulation": 24751,
+ "congratulations": 1864,
+ "congre": 7947,
+ "congreg": 40727,
+ "congregation": 32618,
+ "congress": 12452,
+ "congress": 4599,
+ "congressional": 15239,
+ "congressman": 17145,
+ "congresswoman": 37317,
+ "coni": 39031,
+ "coni": 36651,
+ "conj": 41543,
+ "conju": 33821,
+ "conjunction": 34226,
+ "conley": 44536,
+ "conline": 37593,
+ "conn": 41836,
+ "conn": 20329,
+ "conne": 8437,
+ "connec": 29933,
+ "connect": 19969,
+ "connected": 27506,
+ "connecting": 41429,
+ "connection": 26840,
+ "connections": 37161,
+ "connie": 25739,
+ "connoisse": 46012,
+ "connol": 27739,
+ "connolly": 29537,
+ "connor": 21984,
+ "connor": 10218,
+ "conom": 2664,
+ "conomy": 22529,
+ "conor": 29955,
+ "conor": 19478,
+ "conqu": 13382,
+ "conquer": 38585,
+ "conquer": 19821,
+ "conquered": 27099,
+ "conquering": 43778,
+ "conquest": 35367,
+ "conrad": 22073,
+ "cons": 10311,
+ "consci": 9427,
+ "conscience": 27310,
+ "conscious": 14914,
+ "consciously": 46755,
+ "consciousness": 17894,
+ "conse": 34887,
+ "consecu": 12084,
+ "consecutive": 12413,
+ "consen": 23110,
+ "consensus": 25071,
+ "consent": 21922,
+ "consequ": 13003,
+ "consequence": 42262,
+ "consequences": 15682,
+ "conserv": 4649,
+ "conservancy": 46729,
+ "conservation": 37616,
+ "conservation": 8322,
+ "conservative": 11421,
+ "conservatives": 17631,
+ "conservatory": 32140,
+ "conserve": 34231,
+ "consi": 2899,
+ "consider": 12471,
+ "consider": 6734,
+ "considerable": 38256,
+ "considerably": 38510,
+ "consideration": 24310,
+ "considerations": 33700,
+ "considered": 9487,
+ "considering": 10761,
+ "considers": 24691,
+ "consist": 10410,
+ "consist": 33735,
+ "consisted": 49354,
+ "consistency": 25683,
+ "consistent": 16439,
+ "consistently": 23799,
+ "consisting": 39241,
+ "consists": 23458,
+ "consol": 27869,
+ "consolation": 38888,
+ "console": 13403,
+ "consoles": 33136,
+ "consoli": 21586,
+ "consolidation": 41111,
+ "consor": 27108,
+ "consortium": 29988,
+ "conspir": 12680,
+ "conspiracy": 15236,
+ "const": 3826,
+ "constable": 29179,
+ "constan": 38718,
+ "constance": 40682,
+ "constant": 32000,
+ "constant": 13111,
+ "constantine": 30640,
+ "constantly": 14336,
+ "constell": 21913,
+ "constellation": 25991,
+ "constitu": 6299,
+ "constituency": 22464,
+ "constituents": 32075,
+ "constitution": 12157,
+ "constitutional": 16091,
+ "constra": 28973,
+ "constraints": 41910,
+ "constru": 3983,
+ "construc": 13321,
+ "construct": 24467,
+ "constructed": 16876,
+ "constructing": 33653,
+ "construction": 48873,
+ "construction": 4585,
+ "constructive": 31810,
+ "consu": 4689,
+ "consul": 5295,
+ "consul": 33630,
+ "consulate": 34341,
+ "consult": 9438,
+ "consult": 26727,
+ "consultancy": 31735,
+ "consultant": 14196,
+ "consultants": 27203,
+ "consultation": 15777,
+ "consultations": 43424,
+ "consulting": 15883,
+ "consume": 28919,
+ "consumed": 29653,
+ "consumer": 34408,
+ "consumer": 10422,
+ "consumers": 14014,
+ "consuming": 30607,
+ "consumption": 14904,
+ "cont": 2036,
+ "cont": 21425,
+ "contact": 39367,
+ "contact": 3523,
+ "contacted": 37331,
+ "contacts": 22789,
+ "contag": 29259,
+ "contagious": 33984,
+ "contain": 9948,
+ "contain": 15187,
+ "contained": 23836,
+ "container": 14913,
+ "containers": 20448,
+ "containing": 20281,
+ "contains": 12844,
+ "contamin": 24662,
+ "contaminated": 35773,
+ "contamination": 31770,
+ "conte": 15402,
+ "conte": 26882,
+ "contempl": 21924,
+ "contemplating": 33854,
+ "contempor": 14538,
+ "contemporary": 16607,
+ "contemporary": 8859,
+ "contemporaryart": 20212,
+ "contempt": 39293,
+ "conten": 42201,
+ "contender": 23573,
+ "contenders": 29711,
+ "content": 15526,
+ "content": 4750,
+ "contentmarketing": 20429,
+ "contents": 14850,
+ "contest": 23103,
+ "contest": 4576,
+ "contestalert": 27313,
+ "contestant": 25682,
+ "contestants": 28062,
+ "contested": 37845,
+ "contests": 32210,
+ "contex": 42015,
+ "context": 13089,
+ "conti": 46431,
+ "conti": 40842,
+ "contin": 1918,
+ "continent": 19623,
+ "continental": 14089,
+ "continents": 38642,
+ "conting": 27104,
+ "contingent": 36467,
+ "continu": 4688,
+ "continually": 34086,
+ "continuation": 38964,
+ "continue": 3942,
+ "continued": 10150,
+ "continues": 4305,
+ "continuing": 11009,
+ "continuity": 34035,
+ "continuous": 17033,
+ "continuously": 29634,
+ "continuum": 44978,
+ "contour": 34733,
+ "contr": 22871,
+ "contra": 9880,
+ "contra": 38620,
+ "contrac": 7581,
+ "contracep": 35109,
+ "contract": 6120,
+ "contracting": 39091,
+ "contractor": 21429,
+ "contractors": 22427,
+ "contracts": 16563,
+ "contradic": 27957,
+ "contrary": 32805,
+ "contrast": 18501,
+ "contrasting": 40758,
+ "contribu": 4753,
+ "contribute": 14112,
+ "contributed": 19397,
+ "contributes": 34203,
+ "contributing": 21762,
+ "contribution": 11116,
+ "contributions": 14465,
+ "contributor": 24553,
+ "contributors": 32908,
+ "contro": 2372,
+ "control": 9963,
+ "control": 3366,
+ "controlled": 14140,
+ "controller": 12929,
+ "controllers": 30374,
+ "controlling": 26427,
+ "controls": 15746,
+ "controversi": 13674,
+ "controversial": 14617,
+ "controversy": 18659,
+ "conv": 48382,
+ "conve": 18421,
+ "conven": 7283,
+ "conveni": 33278,
+ "convenience": 17859,
+ "convenient": 18978,
+ "conveniently": 40844,
+ "convention": 6752,
+ "conventional": 20835,
+ "conventions": 41404,
+ "conver": 6336,
+ "convergence": 35381,
+ "convers": 4577,
+ "conversation": 5690,
+ "conversations": 12326,
+ "converse": 24149,
+ "conversion": 15111,
+ "conversions": 44137,
+ "convert": 20074,
+ "converted": 20808,
+ "converter": 34611,
+ "convertible": 19608,
+ "converting": 34674,
+ "converts": 42470,
+ "convey": 38342,
+ "convic": 11150,
+ "convicted": 18668,
+ "conviction": 24967,
+ "convictions": 44366,
+ "convin": 12889,
+ "convince": 20351,
+ "convinced": 17388,
+ "convincing": 27742,
+ "convo": 19372,
+ "convocation": 30674,
+ "convos": 44842,
+ "convoy": 30292,
+ "conway": 21410,
+ "conwy": 48971,
+ "cony": 14501,
+ "coo": 1664,
+ "coo": 21691,
+ "coogs": 47624,
+ "cook": 9726,
+ "cook": 5977,
+ "cookbook": 21086,
+ "cooke": 29979,
+ "cooked": 11452,
+ "cooker": 23806,
+ "cookery": 38779,
+ "cookie": 9367,
+ "cookies": 8320,
+ "cookin": 46610,
+ "cooking": 39248,
+ "cooking": 6283,
+ "cookout": 39743,
+ "cooks": 24256,
+ "cool": 5594,
+ "cool": 2077,
+ "cooled": 37170,
+ "cooler": 11078,
+ "coolest": 10566,
+ "cooling": 15291,
+ "coom": 41726,
+ "coon": 34260,
+ "coon": 16958,
+ "coop": 39917,
+ "coop": 18910,
+ "cooper": 7264,
+ "cooper": 8133,
+ "cooperate": 42936,
+ "cooperation": 11785,
+ "cooperative": 24517,
+ "coops": 48531,
+ "coordin": 8187,
+ "coordinate": 38250,
+ "coordinated": 32540,
+ "coordinating": 40075,
+ "coordination": 25611,
+ "coordinator": 13967,
+ "coors": 36025,
+ "cop": 3196,
+ "cop": 7070,
+ "copa": 22749,
+ "copd": 45876,
+ "cope": 47635,
+ "cope": 12564,
+ "copeland": 37604,
+ "copen": 15637,
+ "copenhagen": 17390,
+ "coper": 41891,
+ "copernic": 45519,
+ "copied": 36770,
+ "copies": 9851,
+ "coping": 30545,
+ "copolitics": 45846,
+ "copp": 20937,
+ "copped": 42229,
+ "copper": 24741,
+ "copper": 10333,
+ "coppola": 47427,
+ "cops": 10719,
+ "copter": 28049,
+ "copy": 11376,
+ "copy": 4509,
+ "copying": 38925,
+ "copyright": 15778,
+ "cor": 851,
+ "cor": 18559,
+ "cora": 34953,
+ "coral": 31220,
+ "coral": 12054,
+ "corbett": 35699,
+ "corbin": 35578,
+ "corbyn": 14026,
+ "cord": 40893,
+ "cord": 11181,
+ "corden": 41999,
+ "cordi": 41681,
+ "cordless": 44412,
+ "cords": 22164,
+ "core": 19622,
+ "core": 5000,
+ "cores": 37874,
+ "corey": 31279,
+ "corey": 15288,
+ "corgi": 31320,
+ "cori": 26508,
+ "coriander": 37491,
+ "corin": 17716,
+ "corinthians": 34471,
+ "cork": 18148,
+ "cork": 10376,
+ "corn": 5202,
+ "corn": 5894,
+ "cornelius": 45865,
+ "cornell": 38689,
+ "cornell": 20859,
+ "corner": 18509,
+ "corner": 5253,
+ "corners": 19584,
+ "cornerstone": 36280,
+ "cornish": 23774,
+ "cornwall": 37903,
+ "cornwall": 10777,
+ "coron": 13210,
+ "corona": 25564,
+ "coronado": 43946,
+ "coronary": 45955,
+ "coronation": 25014,
+ "coroner": 47241,
+ "corp": 29203,
+ "corp": 10918,
+ "corpor": 4258,
+ "corporal": 42445,
+ "corporate": 33877,
+ "corporate": 6838,
+ "corporation": 11282,
+ "corporations": 25482,
+ "corps": 11330,
+ "corpse": 29408,
+ "corpus": 31672,
+ "correc": 5011,
+ "correct": 8340,
+ "corrected": 35628,
+ "correction": 20843,
+ "correctional": 38030,
+ "corrections": 37507,
+ "correctly": 15359,
+ "correlation": 29218,
+ "correspon": 20203,
+ "correspondent": 29996,
+ "corri": 12974,
+ "corridor": 20592,
+ "corrie": 23961,
+ "corro": 24936,
+ "corro": 42033,
+ "corrosion": 39191,
+ "corru": 6501,
+ "corrup": 30429,
+ "corrupt": 15194,
+ "corruption": 9141,
+ "corsa": 47670,
+ "corsair": 42367,
+ "corset": 40408,
+ "cortex": 40109,
+ "cortez": 30461,
+ "corvette": 24367,
+ "cory": 23221,
+ "cory": 18329,
+ "cos": 5865,
+ "cos": 5700,
+ "cosby": 30324,
+ "cosc": 45944,
+ "coscino": 47909,
+ "cose": 26495,
+ "cosm": 37486,
+ "cosme": 9628,
+ "cosmetic": 23918,
+ "cosmetics": 12896,
+ "cosmic": 47398,
+ "cosmic": 18304,
+ "cosmo": 12829,
+ "cosmo": 32072,
+ "cosmopolitan": 35518,
+ "cosmos": 22151,
+ "cospla": 15149,
+ "cosplay": 42401,
+ "cosplay": 6435,
+ "cosplayer": 30215,
+ "cosplaying": 46701,
+ "cost": 11360,
+ "cost": 4713,
+ "costa": 10480,
+ "costar": 28659,
+ "costarica": 31272,
+ "costco": 31045,
+ "costello": 30667,
+ "costing": 39193,
+ "costly": 30170,
+ "costs": 7628,
+ "costu": 5786,
+ "costume": 7235,
+ "costumes": 15150,
+ "cosy": 22848,
+ "cot": 4718,
+ "cot": 5871,
+ "cote": 44234,
+ "cote": 20751,
+ "cotland": 32576,
+ "cotsw": 23303,
+ "cotswolds": 35546,
+ "cott": 8211,
+ "cott": 11349,
+ "cottage": 12155,
+ "cottages": 34405,
+ "cotton": 22218,
+ "cotton": 7050,
+ "cou": 1368,
+ "couch": 12724,
+ "cougar": 35028,
+ "cougar": 27042,
+ "cougars": 20425,
+ "cough": 35631,
+ "cough": 18498,
+ "cougs": 28482,
+ "coul": 22483,
+ "could": 44812,
+ "could": 1510,
+ "couldn": 4072,
+ "couldnt": 29042,
+ "coulter": 42291,
+ "coun": 939,
+ "counc": 12927,
+ "council": 18187,
+ "council": 3620,
+ "councill": 15732,
+ "councillor": 21179,
+ "councillors": 29695,
+ "councilman": 40833,
+ "councils": 29938,
+ "counsel": 13780,
+ "counsel": 19814,
+ "counseling": 25000,
+ "counsell": 47510,
+ "counselling": 40581,
+ "counselor": 26148,
+ "counselors": 38688,
+ "count": 6073,
+ "count": 5887,
+ "countdown": 39559,
+ "countdown": 7500,
+ "counted": 23149,
+ "counter": 10134,
+ "counter": 7352,
+ "counterfe": 33067,
+ "counterfeit": 44242,
+ "counterpart": 39216,
+ "counterparts": 42106,
+ "counters": 46170,
+ "countess": 46276,
+ "counties": 12338,
+ "counting": 9723,
+ "countless": 21819,
+ "countries": 5489,
+ "country": 7896,
+ "country": 2157,
+ "countryfile": 47023,
+ "countrymusic": 30372,
+ "countryside": 16303,
+ "counts": 12264,
+ "county": 18734,
+ "county": 2116,
+ "coup": 9871,
+ "coup": 16479,
+ "coupe": 16773,
+ "couple": 40136,
+ "couple": 3377,
+ "coupled": 37153,
+ "couples": 14752,
+ "coupling": 45595,
+ "coupon": 14019,
+ "coupons": 23945,
+ "cour": 1391,
+ "coura": 4436,
+ "courage": 9828,
+ "courageous": 25005,
+ "courier": 27217,
+ "cours": 21493,
+ "course": 43225,
+ "course": 2613,
+ "courses": 9464,
+ "court": 16837,
+ "court": 2908,
+ "courte": 5088,
+ "courtesy": 5228,
+ "courthouse": 22205,
+ "courtney": 33601,
+ "courtney": 15990,
+ "courtroom": 41071,
+ "courts": 13514,
+ "courty": 20121,
+ "courtyard": 21900,
+ "cous": 48397,
+ "cousin": 7780,
+ "cousins": 14073,
+ "cout": 29118,
+ "coutinho": 35530,
+ "couture": 14808,
+ "cov": 19384,
+ "cov": 48385,
+ "cove": 21700,
+ "cove": 14708,
+ "coven": 12483,
+ "covenant": 29647,
+ "coventry": 18007,
+ "cover": 13534,
+ "cover": 2202,
+ "coverage": 6810,
+ "covered": 5603,
+ "covering": 9462,
+ "covers": 7745,
+ "covert": 40134,
+ "coveted": 36119,
+ "covington": 43196,
+ "cow": 5076,
+ "cow": 9706,
+ "cowan": 42699,
+ "coward": 33729,
+ "cowards": 48972,
+ "cowboy": 25833,
+ "cowboy": 13657,
+ "cowboys": 11864,
+ "cowboysnation": 43082,
+ "cowell": 39015,
+ "cowgirl": 47090,
+ "coworker": 30727,
+ "coworkers": 30821,
+ "coworking": 36034,
+ "cows": 15204,
+ "cowx": 23831,
+ "cox": 25784,
+ "cox": 11597,
+ "coy": 12765,
+ "coy": 15742,
+ "coyi": 48407,
+ "coyle": 45348,
+ "coyne": 44729,
+ "coyo": 16614,
+ "coyote": 26586,
+ "coyotes": 30423,
+ "coys": 19736,
+ "coz": 39922,
+ "coz": 14282,
+ "cozy": 14873,
+ "cp": 7905,
+ "cp": 9130,
+ "cpa": 30095,
+ "cpac": 45731,
+ "cpc": 26125,
+ "cpd": 23402,
+ "cpec": 48007,
+ "cpfc": 27553,
+ "cpi": 41795,
+ "cpl": 26852,
+ "cpr": 25134,
+ "cps": 27078,
+ "cpt": 32892,
+ "cpu": 27700,
+ "cq": 48910,
+ "cq": 48417,
+ "cr": 1075,
+ "cr": 3483,
+ "cra": 1184,
+ "cra": 18362,
+ "crab": 27382,
+ "crab": 11574,
+ "crabs": 30908,
+ "crack": 11222,
+ "crack": 10334,
+ "crackdown": 29527,
+ "cracked": 19826,
+ "cracker": 16298,
+ "crackers": 26200,
+ "cracking": 13008,
+ "cracks": 21426,
+ "cracy": 24749,
+ "cradle": 29384,
+ "crae": 40438,
+ "craf": 10873,
+ "craft": 7717,
+ "craft": 3588,
+ "craftbeer": 12371,
+ "crafted": 12424,
+ "crafthour": 42324,
+ "crafting": 26886,
+ "crafts": 33276,
+ "crafts": 13383,
+ "craftsman": 39528,
+ "craftsmanship": 36682,
+ "crafty": 32317,
+ "craic": 46962,
+ "craig": 14042,
+ "craig": 8061,
+ "craigslist": 43865,
+ "cram": 29809,
+ "cramer": 44592,
+ "cramps": 46106,
+ "cran": 7761,
+ "cranberries": 49361,
+ "cranberry": 23824,
+ "crane": 14626,
+ "cranes": 26979,
+ "crani": 45674,
+ "crank": 46246,
+ "crank": 32283,
+ "cranston": 44340,
+ "crap": 11899,
+ "crappy": 30475,
+ "crash": 37150,
+ "crash": 5033,
+ "crashed": 16638,
+ "crashes": 17013,
+ "crashing": 24991,
+ "crat": 46696,
+ "crate": 24756,
+ "crater": 22663,
+ "crates": 30172,
+ "cratic": 32175,
+ "crative": 39999,
+ "crats": 43056,
+ "crave": 33397,
+ "craven": 33625,
+ "craving": 18344,
+ "cravings": 34476,
+ "craw": 7400,
+ "crawfish": 42772,
+ "crawford": 15918,
+ "crawl": 20106,
+ "crawler": 41012,
+ "crawley": 42316,
+ "crawling": 37066,
+ "cray": 24184,
+ "cray": 27032,
+ "crayon": 41801,
+ "crayons": 43508,
+ "craz": 25776,
+ "craze": 30637,
+ "craziest": 32690,
+ "craziness": 46436,
+ "crazy": 17540,
+ "crazy": 3578,
+ "crc": 25618,
+ "cre": 798,
+ "cre": 17762,
+ "cream": 23184,
+ "cream": 3867,
+ "creams": 41447,
+ "creamy": 17206,
+ "crease": 48441,
+ "create": 30949,
+ "create": 3380,
+ "created": 4080,
+ "creates": 10361,
+ "creati": 6714,
+ "creating": 5524,
+ "creation": 38293,
+ "creation": 6900,
+ "creations": 17411,
+ "creative": 15237,
+ "creative": 4450,
+ "creatives": 29352,
+ "creativity": 9636,
+ "creator": 10173,
+ "creators": 17981,
+ "creature": 14317,
+ "creatures": 13938,
+ "cred": 7314,
+ "cred": 22377,
+ "credenti": 29487,
+ "credentials": 33422,
+ "credi": 21097,
+ "credibility": 34984,
+ "credible": 32983,
+ "credit": 21467,
+ "credit": 3900,
+ "credited": 32480,
+ "credits": 10654,
+ "creds": 43462,
+ "cree": 33961,
+ "cree": 36014,
+ "creed": 18845,
+ "creek": 26120,
+ "creek": 5526,
+ "creep": 8153,
+ "creep": 26084,
+ "creeper": 38662,
+ "creeping": 29697,
+ "creeps": 45135,
+ "creepy": 11943,
+ "creighton": 42823,
+ "creme": 22681,
+ "creole": 45632,
+ "crepe": 38611,
+ "crescent": 18211,
+ "cress": 39124,
+ "crest": 35985,
+ "crest": 15760,
+ "crested": 36656,
+ "crete": 8584,
+ "crew": 21560,
+ "crew": 3462,
+ "crewe": 43284,
+ "crews": 10463,
+ "cri": 1621,
+ "cri": 38962,
+ "crib": 23271,
+ "cric": 4328,
+ "cricke": 19098,
+ "cricket": 21859,
+ "cricket": 5373,
+ "cricketer": 28439,
+ "cricketers": 43986,
+ "cried": 15290,
+ "cries": 19769,
+ "crime": 13872,
+ "crime": 4896,
+ "crimea": 28614,
+ "crimes": 11827,
+ "crimin": 5874,
+ "criminal": 30197,
+ "criminal": 8255,
+ "criminals": 18783,
+ "crimson": 19437,
+ "cringe": 42588,
+ "cripp": 33588,
+ "cris": 37818,
+ "crises": 36403,
+ "crisis": 5712,
+ "crisp": 15145,
+ "crispr": 39784,
+ "crisps": 35744,
+ "crispy": 16458,
+ "criss": 29708,
+ "cristi": 12699,
+ "cristian": 48808,
+ "cristiano": 14807,
+ "cristina": 33395,
+ "cristo": 38315,
+ "crit": 3613,
+ "crit": 48130,
+ "criteri": 33627,
+ "criteria": 24849,
+ "criterion": 43841,
+ "criti": 25333,
+ "critic": 12417,
+ "critic": 19361,
+ "critical": 15314,
+ "critical": 6808,
+ "critically": 21570,
+ "criticalrole": 33606,
+ "criticalrole": 22742,
+ "criticalrolefanart": 43663,
+ "critici": 20333,
+ "criticism": 17405,
+ "criticize": 46081,
+ "criticized": 41557,
+ "critics": 16946,
+ "critique": 32982,
+ "critters": 35423,
+ "crm": 22610,
+ "cro": 1192,
+ "cro": 22522,
+ "croati": 28072,
+ "croatia": 13323,
+ "croatian": 34795,
+ "croc": 43350,
+ "croche": 35352,
+ "crochet": 17554,
+ "crock": 41685,
+ "crocker": 47843,
+ "crockett": 48313,
+ "crocod": 24519,
+ "crocodile": 24757,
+ "crocs": 38988,
+ "croft": 16657,
+ "croissant": 46011,
+ "croix": 44735,
+ "crom": 25082,
+ "crombie": 46162,
+ "cromwell": 45345,
+ "cron": 17361,
+ "croo": 16443,
+ "crook": 43744,
+ "crooked": 48473,
+ "crooked": 25644,
+ "crooks": 44226,
+ "crop": 40751,
+ "crop": 9955,
+ "cropped": 31139,
+ "crops": 16290,
+ "crore": 18274,
+ "crores": 37281,
+ "cros": 16670,
+ "crosby": 21095,
+ "cross": 5266,
+ "cross": 3417,
+ "crossed": 11731,
+ "crosses": 20473,
+ "crossfit": 47214,
+ "crossfit": 20395,
+ "crossing": 8673,
+ "crossings": 43517,
+ "crossover": 17194,
+ "crossroads": 27427,
+ "crossword": 32945,
+ "crou": 31206,
+ "crouch": 36506,
+ "crow": 3138,
+ "crow": 16019,
+ "crowd": 12036,
+ "crowd": 4570,
+ "crowded": 20182,
+ "crowdfunding": 17971,
+ "crowds": 16092,
+ "crowe": 33560,
+ "crowley": 32287,
+ "crown": 22190,
+ "crown": 6902,
+ "crowned": 16109,
+ "crowns": 33229,
+ "crows": 27134,
+ "croy": 21676,
+ "croydon": 27116,
+ "crs": 28449,
+ "crt": 43877,
+ "cru": 1815,
+ "cru": 29788,
+ "cruci": 18499,
+ "crucial": 12396,
+ "crude": 20677,
+ "cruel": 16073,
+ "cruel": 17573,
+ "cruelty": 20675,
+ "cruis": 27721,
+ "cruise": 36425,
+ "cruise": 6764,
+ "cruiser": 21394,
+ "cruises": 19214,
+ "cruising": 19743,
+ "crum": 43268,
+ "crumb": 48327,
+ "crumb": 39909,
+ "crumble": 36595,
+ "crumbs": 35893,
+ "crun": 17407,
+ "crunch": 16620,
+ "crunchy": 31366,
+ "crusad": 19133,
+ "crusade": 36846,
+ "crusader": 40171,
+ "crusaders": 31319,
+ "crush": 22296,
+ "crush": 7610,
+ "crushed": 18270,
+ "crusher": 44923,
+ "crushes": 35844,
+ "crushing": 20790,
+ "crust": 23136,
+ "crusted": 37314,
+ "cruz": 33689,
+ "cruz": 8403,
+ "cry": 2837,
+ "cry": 6290,
+ "crying": 6828,
+ "cryo": 32215,
+ "cryp": 4865,
+ "crypt": 37814,
+ "cryptic": 46925,
+ "crypto": 8080,
+ "crypto": 9608,
+ "cryptocurrencies": 33329,
+ "cryptocurrency": 12070,
+ "cryst": 15891,
+ "crystal": 17387,
+ "crystal": 6517,
+ "crystalli": 47551,
+ "crystals": 18350,
+ "cs": 11978,
+ "cs": 2804,
+ "csa": 26355,
+ "csc": 41727,
+ "csc": 37266,
+ "csd": 36913,
+ "cse": 41659,
+ "csg": 47085,
+ "csgo": 28928,
+ "csi": 41750,
+ "csi": 28070,
+ "csk": 43036,
+ "csm": 40061,
+ "csn": 46329,
+ "cso": 43864,
+ "csp": 39243,
+ "csr": 32105,
+ "csr": 24598,
+ "csrracing": 44193,
+ "css": 41418,
+ "css": 19846,
+ "cst": 17016,
+ "csu": 35948,
+ "csu": 31261,
+ "csw": 41031,
+ "ct": 3381,
+ "ct": 1122,
+ "cta": 28397,
+ "ctar": 27842,
+ "ctc": 34123,
+ "cte": 31410,
+ "cted": 2910,
+ "ctf": 35250,
+ "cthulhu": 41064,
+ "cting": 7985,
+ "ction": 17578,
+ "ction": 1569,
+ "ctions": 7021,
+ "ctive": 9313,
+ "cto": 17445,
+ "ctor": 8108,
+ "ctr": 35602,
+ "ctr": 18481,
+ "cts": 6936,
+ "ctto": 25118,
+ "ctu": 20834,
+ "cture": 17668,
+ "ctv": 21213,
+ "ctv": 27590,
+ "cu": 729,
+ "cu": 11224,
+ "cuando": 40388,
+ "cub": 16938,
+ "cub": 19972,
+ "cuba": 11576,
+ "cuban": 15536,
+ "cube": 47753,
+ "cube": 11353,
+ "cubes": 31413,
+ "cubic": 48159,
+ "cubic": 29614,
+ "cubs": 9858,
+ "cuck": 26364,
+ "cuckoo": 38062,
+ "cucu": 16705,
+ "cucumber": 19787,
+ "cucumbers": 48065,
+ "cud": 42684,
+ "cudd": 12820,
+ "cuddle": 19568,
+ "cuddles": 24001,
+ "cuddling": 29696,
+ "cuddly": 36208,
+ "cudi": 48713,
+ "cue": 13424,
+ "cuer": 39506,
+ "cues": 35719,
+ "cuff": 34693,
+ "cuff": 22414,
+ "cufflinks": 43938,
+ "cuffs": 37221,
+ "cuis": 9938,
+ "cuisine": 10605,
+ "cuk": 34838,
+ "cul": 1877,
+ "cula": 35935,
+ "cular": 10940,
+ "culars": 45719,
+ "cule": 31066,
+ "cules": 18984,
+ "culin": 14772,
+ "culinary": 16466,
+ "cull": 21880,
+ "cull": 42061,
+ "cullen": 25973,
+ "culmin": 33778,
+ "culo": 36305,
+ "culprit": 41593,
+ "cult": 11965,
+ "cultiv": 16781,
+ "cultivate": 42983,
+ "cultivated": 48901,
+ "cultivation": 41539,
+ "cultur": 20780,
+ "cultural": 34908,
+ "cultural": 6753,
+ "culturally": 36783,
+ "culture": 20197,
+ "culture": 3673,
+ "cultured": 40176,
+ "cultures": 19552,
+ "culver": 42103,
+ "cum": 20142,
+ "cum": 27119,
+ "cumb": 10858,
+ "cumber": 15309,
+ "cumberbatch": 27541,
+ "cumberland": 28747,
+ "cumbri": 32010,
+ "cumbria": 17953,
+ "cumin": 42285,
+ "cumple": 47050,
+ "cumul": 42961,
+ "cumulative": 47610,
+ "cumulus": 46313,
+ "cun": 12423,
+ "cun": 29532,
+ "cunningham": 25321,
+ "cuomo": 25681,
+ "cup": 5059,
+ "cup": 1937,
+ "cupboard": 32074,
+ "cupcake": 17025,
+ "cupcakes": 12747,
+ "cupid": 34885,
+ "cuppa": 28077,
+ "cups": 11463,
+ "cur": 1092,
+ "cur": 33073,
+ "curated": 20341,
+ "curator": 20753,
+ "curb": 21931,
+ "curd": 38881,
+ "cure": 36758,
+ "cure": 9088,
+ "cured": 26248,
+ "cures": 38204,
+ "curfew": 48826,
+ "curi": 12640,
+ "curing": 44169,
+ "curiosity": 21583,
+ "curious": 9865,
+ "curl": 24306,
+ "curled": 43734,
+ "curling": 18543,
+ "curls": 24340,
+ "curly": 20795,
+ "curran": 40999,
+ "currant": 43501,
+ "curren": 6142,
+ "currencies": 23530,
+ "currency": 7853,
+ "current": 3653,
+ "currently": 3792,
+ "currents": 35450,
+ "curric": 16201,
+ "curriculum": 17947,
+ "currie": 39385,
+ "curry": 49285,
+ "curry": 8051,
+ "curse": 18479,
+ "cursed": 26408,
+ "cursor": 46546,
+ "curt": 38137,
+ "curtain": 17223,
+ "curtains": 30223,
+ "curti": 39925,
+ "curtis": 13808,
+ "curve": 15792,
+ "curved": 25789,
+ "curves": 22814,
+ "curvy": 45788,
+ "cus": 2736,
+ "cusa": 47414,
+ "cuse": 37950,
+ "cush": 43731,
+ "cushi": 15333,
+ "cushion": 20853,
+ "cushions": 34163,
+ "cussion": 16658,
+ "cussions": 46853,
+ "cust": 20900,
+ "custard": 26516,
+ "custo": 4376,
+ "custody": 16176,
+ "custom": 2662,
+ "custom": 4996,
+ "custome": 41323,
+ "customer": 24035,
+ "customer": 5102,
+ "customerexperience": 45167,
+ "customers": 5528,
+ "customerservice": 40611,
+ "customiz": 41793,
+ "customizable": 48253,
+ "customization": 48244,
+ "customize": 32179,
+ "customized": 23229,
+ "customs": 16880,
+ "cut": 10511,
+ "cut": 3032,
+ "cute": 16031,
+ "cute": 2242,
+ "cuteness": 19342,
+ "cuter": 27151,
+ "cutest": 8032,
+ "cuth": 44328,
+ "cutie": 10733,
+ "cuties": 40939,
+ "cuties": 23420,
+ "cutiesaturday": 41883,
+ "cutler": 40428,
+ "cutlery": 49073,
+ "cutout": 45016,
+ "cuts": 7435,
+ "cutt": 27338,
+ "cutt": 47647,
+ "cutter": 19719,
+ "cutters": 44783,
+ "cutting": 7266,
+ "cuz": 9215,
+ "cv": 13531,
+ "cv": 13947,
+ "cvs": 29603,
+ "cw": 10652,
+ "cw": 11065,
+ "cwc": 19179,
+ "cwgc": 48527,
+ "cws": 45186,
+ "cx": 44457,
+ "cx": 14283,
+ "cy": 1470,
+ "cy": 1678,
+ "cyber": 5830,
+ "cyber": 10210,
+ "cybercrime": 41772,
+ "cybermonday": 36578,
+ "cyberpunk": 36896,
+ "cybersecurity": 10581,
+ "cyborg": 36650,
+ "cycl": 9791,
+ "cycle": 19083,
+ "cycle": 5072,
+ "cycled": 31055,
+ "cycles": 14605,
+ "cycli": 12201,
+ "cycling": 26353,
+ "cycling": 6321,
+ "cyclist": 20686,
+ "cyclists": 20303,
+ "cyclo": 18122,
+ "cyclone": 48094,
+ "cyclone": 20917,
+ "cyclones": 34669,
+ "cylin": 18569,
+ "cylinder": 22092,
+ "cylinders": 48888,
+ "cymb": 36677,
+ "cymru": 24005,
+ "cyn": 14324,
+ "cynthi": 41994,
+ "cynthia": 23748,
+ "cyp": 14809,
+ "cypress": 25347,
+ "cypri": 36481,
+ "cyprus": 15263,
+ "cyril": 36028,
+ "cyrus": 14204,
+ "cystic": 46131,
+ "cyto": 31864,
+ "cz": 22898,
+ "cz": 22921,
+ "cze": 12152,
+ "czech": 43151,
+ "czech": 16141,
+ "cé": 36454,
+ "cé": 18317,
+ "d": 67,
+ "d": 323,
+ "da": 925,
+ "da": 1140,
+ "daa": 32642,
+ "daan": 44814,
+ "dab": 10413,
+ "dab": 22900,
+ "dac": 16222,
+ "dac": 27478,
+ "daca": 28477,
+ "dach": 34166,
+ "dachsh": 41641,
+ "dachshund": 42720,
+ "dad": 4346,
+ "dad": 2639,
+ "dada": 31325,
+ "daddy": 29466,
+ "daddy": 6546,
+ "dade": 23299,
+ "dades": 28289,
+ "dads": 12741,
+ "dae": 23358,
+ "dae": 15422,
+ "daener": 46934,
+ "daes": 47282,
+ "daesh": 35047,
+ "daf": 9972,
+ "daf": 36704,
+ "daffodils": 44769,
+ "daft": 36347,
+ "dag": 11434,
+ "dag": 25650,
+ "dagger": 34251,
+ "dah": 16976,
+ "dah": 11776,
+ "dahl": 45816,
+ "dahl": 22621,
+ "dahlia": 41768,
+ "dai": 13559,
+ "dai": 10632,
+ "dail": 14676,
+ "dailies": 21260,
+ "daily": 6689,
+ "daily": 2873,
+ "dailynews": 43466,
+ "dailys": 43160,
+ "dailysketch": 46738,
+ "daim": 40421,
+ "dain": 32222,
+ "dain": 28315,
+ "daipur": 47631,
+ "dair": 19998,
+ "dair": 42078,
+ "dairy": 25243,
+ "dairy": 10302,
+ "dairyfree": 49366,
+ "dais": 10502,
+ "daisi": 39947,
+ "daisies": 40654,
+ "daisy": 39310,
+ "daisy": 12865,
+ "dak": 6999,
+ "dak": 16095,
+ "dakar": 31137,
+ "dakota": 38522,
+ "dakota": 12358,
+ "dal": 2476,
+ "dal": 5601,
+ "dala": 42675,
+ "dalai": 41222,
+ "dalail": 35169,
+ "dalailama": 35849,
+ "dale": 11533,
+ "dale": 4677,
+ "dalejr": 38207,
+ "dales": 29031,
+ "daley": 28544,
+ "dalgo": 43614,
+ "dali": 36735,
+ "dali": 25703,
+ "dalit": 45432,
+ "dall": 43631,
+ "dalla": 16772,
+ "dallas": 27414,
+ "dallas": 5759,
+ "dallascowboys": 33016,
+ "dalmati": 44275,
+ "dalton": 21488,
+ "daly": 24873,
+ "dam": 1880,
+ "dam": 4926,
+ "damage": 6822,
+ "damaged": 13568,
+ "damages": 28842,
+ "damaging": 20610,
+ "damas": 23345,
+ "damascus": 25396,
+ "dame": 10069,
+ "dames": 44548,
+ "dami": 17783,
+ "damian": 43307,
+ "damian": 25375,
+ "damien": 25090,
+ "dammit": 31057,
+ "damn": 37409,
+ "damn": 4451,
+ "damned": 28428,
+ "damon": 48503,
+ "damon": 18244,
+ "damp": 26520,
+ "dams": 37680,
+ "dan": 2257,
+ "dan": 2284,
+ "dana": 44834,
+ "dana": 13777,
+ "danao": 38598,
+ "danc": 3945,
+ "dance": 10619,
+ "dance": 2724,
+ "danced": 32891,
+ "dancehall": 33300,
+ "dancer": 11400,
+ "dancers": 13153,
+ "dances": 24083,
+ "dancing": 33280,
+ "dancing": 6226,
+ "dand": 12593,
+ "dandelion": 38903,
+ "dandy": 31932,
+ "dane": 19330,
+ "danes": 47477,
+ "dang": 4283,
+ "dang": 14992,
+ "danger": 20083,
+ "danger": 11212,
+ "dangerous": 7350,
+ "dangerously": 35012,
+ "dangers": 23726,
+ "dangle": 39907,
+ "dani": 3001,
+ "dani": 17009,
+ "daniel": 7859,
+ "daniel": 4981,
+ "daniela": 44466,
+ "danielle": 30396,
+ "danielle": 15292,
+ "danielpadilla": 34702,
+ "daniels": 16146,
+ "danish": 15467,
+ "dank": 31849,
+ "dann": 11951,
+ "danny": 14950,
+ "danny": 7621,
+ "dano": 29703,
+ "dans": 16241,
+ "dant": 48097,
+ "dant": 28237,
+ "dante": 21911,
+ "danube": 44594,
+ "dany": 47816,
+ "dao": 36099,
+ "dap": 12149,
+ "dap": 38034,
+ "daph": 24591,
+ "daphne": 31687,
+ "dapl": 34478,
+ "dapp": 46857,
+ "dapper": 26071,
+ "daq": 25381,
+ "dar": 1377,
+ "dar": 6242,
+ "dara": 17064,
+ "darby": 34366,
+ "darcy": 32916,
+ "dare": 14833,
+ "dare": 9863,
+ "daredevil": 28849,
+ "dares": 42973,
+ "dareto": 46794,
+ "dari": 16292,
+ "dari": 14552,
+ "daria": 45622,
+ "daries": 18184,
+ "daring": 28166,
+ "dario": 33918,
+ "darius": 32606,
+ "darje": 49089,
+ "dark": 5724,
+ "dark": 3144,
+ "darker": 18737,
+ "darkest": 25898,
+ "darkness": 10521,
+ "darling": 13048,
+ "darlings": 39961,
+ "darlington": 34565,
+ "darn": 26059,
+ "darrell": 33522,
+ "darren": 20263,
+ "darren": 12275,
+ "darry": 29200,
+ "darryl": 35359,
+ "darshan": 34564,
+ "dart": 14001,
+ "dart": 19841,
+ "darth": 41304,
+ "darth": 23164,
+ "dartmoor": 31477,
+ "dartmouth": 29667,
+ "darts": 15246,
+ "darwin": 43013,
+ "darwin": 20926,
+ "daryl": 45607,
+ "daryl": 24532,
+ "das": 9940,
+ "das": 7359,
+ "dash": 13858,
+ "dash": 10206,
+ "dashboard": 27679,
+ "dashi": 12876,
+ "dashing": 33825,
+ "dat": 1717,
+ "dat": 9445,
+ "data": 14876,
+ "data": 2281,
+ "datab": 11941,
+ "database": 14678,
+ "databases": 48384,
+ "datac": 27329,
+ "datacenter": 40133,
+ "datasci": 14496,
+ "datascience": 15748,
+ "dataviz": 28138,
+ "date": 34300,
+ "date": 1524,
+ "dated": 13564,
+ "dates": 7228,
+ "dating": 8534,
+ "dation": 15311,
+ "datlantic": 34270,
+ "dato": 36075,
+ "dats": 48674,
+ "dau": 3162,
+ "dau": 33828,
+ "daugh": 42523,
+ "daughter": 3944,
+ "daughters": 13585,
+ "daun": 29470,
+ "dav": 3700,
+ "dav": 46488,
+ "davao": 31502,
+ "dave": 10089,
+ "dave": 5077,
+ "daven": 28350,
+ "davenport": 34624,
+ "davey": 33391,
+ "davi": 1732,
+ "david": 4640,
+ "david": 2259,
+ "davidbowie": 44448,
+ "davido": 35989,
+ "davids": 46695,
+ "davidson": 13166,
+ "davies": 13120,
+ "davin": 43187,
+ "davis": 24426,
+ "davis": 5536,
+ "davison": 43725,
+ "davos": 31887,
+ "davy": 41565,
+ "daw": 5971,
+ "daw": 24404,
+ "dawg": 18660,
+ "dawgs": 26431,
+ "dawn": 30590,
+ "dawn": 7689,
+ "dawson": 18611,
+ "dax": 29458,
+ "day": 1405,
+ "day": 575,
+ "daya": 38165,
+ "daybreak": 33862,
+ "daycare": 36363,
+ "daydream": 41587,
+ "dayin": 20332,
+ "daylight": 20809,
+ "dayo": 29856,
+ "dayo": 46605,
+ "dayof": 16272,
+ "dayofthe": 38043,
+ "days": 1161,
+ "daysof": 12379,
+ "daysofcode": 36537,
+ "daysto": 29886,
+ "daystogo": 42198,
+ "dayswild": 42052,
+ "daytime": 22830,
+ "dayton": 35729,
+ "dayton": 20262,
+ "daytona": 16335,
+ "dayweekend": 44526,
+ "dayz": 35949,
+ "daz": 15449,
+ "daz": 43844,
+ "daze": 33591,
+ "dazz": 17149,
+ "dazzle": 41164,
+ "dazzling": 28821,
+ "db": 19100,
+ "db": 8128,
+ "dbacks": 31175,
+ "dbs": 40558,
+ "dbz": 49226,
+ "dc": 5074,
+ "dc": 2743,
+ "dca": 49107,
+ "dcc": 33747,
+ "dccomics": 17610,
+ "dcfc": 35526,
+ "dci": 35336,
+ "dcs": 42878,
+ "dcu": 42647,
+ "dd": 1353,
+ "dd": 3766,
+ "dda": 35202,
+ "ddad": 39049,
+ "dday": 32689,
+ "dday": 26243,
+ "ddc": 48513,
+ "ddd": 24183,
+ "dddd": 35362,
+ "dden": 5013,
+ "dder": 9300,
+ "dders": 24827,
+ "ddi": 44450,
+ "ddin": 17175,
+ "dding": 48101,
+ "dding": 8974,
+ "ddings": 49106,
+ "ddington": 29238,
+ "ddle": 17633,
+ "ddle": 8357,
+ "ddled": 38392,
+ "ddles": 33901,
+ "ddleston": 25647,
+ "ddling": 30981,
+ "ddlovato": 28244,
+ "ddos": 46463,
+ "ddr": 26027,
+ "dds": 48334,
+ "ddu": 43836,
+ "ddy": 14981,
+ "ddy": 7876,
+ "de": 561,
+ "de": 654,
+ "dea": 18477,
+ "deacon": 29155,
+ "dead": 3906,
+ "dead": 2747,
+ "deadliest": 40811,
+ "deadline": 47209,
+ "deadline": 8458,
+ "deadlines": 44959,
+ "deadly": 10756,
+ "deadpool": 21471,
+ "deaf": 28229,
+ "deaf": 18358,
+ "deal": 7249,
+ "deal": 2696,
+ "dealer": 15218,
+ "dealers": 21697,
+ "dealership": 32096,
+ "dealing": 13138,
+ "deals": 4469,
+ "dealt": 30101,
+ "dean": 13807,
+ "dean": 5828,
+ "deandre": 43635,
+ "deans": 46852,
+ "dear": 15696,
+ "dear": 3817,
+ "dearest": 24880,
+ "dearly": 31880,
+ "deas": 34715,
+ "death": 7163,
+ "death": 2767,
+ "deaths": 12253,
+ "deau": 12399,
+ "deaux": 19883,
+ "deb": 2987,
+ "deb": 25687,
+ "debat": 32082,
+ "debate": 5196,
+ "debates": 19239,
+ "debating": 23472,
+ "debbie": 47186,
+ "debbie": 16735,
+ "debit": 32410,
+ "debor": 16738,
+ "deborah": 40997,
+ "deborah": 22150,
+ "debra": 33233,
+ "debris": 19208,
+ "debt": 8932,
+ "debts": 38770,
+ "debu": 9790,
+ "debun": 33123,
+ "debut": 42608,
+ "debut": 4085,
+ "debuted": 25215,
+ "debuting": 34817,
+ "debuts": 17044,
+ "dec": 3063,
+ "dec": 4628,
+ "deca": 33428,
+ "decad": 29914,
+ "decade": 11099,
+ "decadent": 41716,
+ "decades": 10488,
+ "decal": 26678,
+ "decals": 37606,
+ "decan": 40677,
+ "decat": 35334,
+ "decath": 47455,
+ "decatur": 38540,
+ "decay": 22703,
+ "dece": 3534,
+ "deceased": 30035,
+ "december": 3864,
+ "decent": 10698,
+ "decentr": 28960,
+ "decentralized": 38485,
+ "decep": 33529,
+ "deception": 33046,
+ "deci": 2262,
+ "decide": 8447,
+ "decided": 4939,
+ "decides": 17269,
+ "deciding": 22513,
+ "decision": 5575,
+ "decisions": 9903,
+ "decisive": 28690,
+ "deck": 24885,
+ "deck": 6943,
+ "decked": 39096,
+ "decker": 21449,
+ "decks": 23968,
+ "decl": 7091,
+ "decla": 10739,
+ "declan": 42341,
+ "declar": 18040,
+ "declaration": 19714,
+ "declare": 19856,
+ "declared": 13845,
+ "declares": 23641,
+ "declaring": 33273,
+ "decline": 15084,
+ "declined": 28911,
+ "declines": 40478,
+ "declining": 29221,
+ "deco": 26412,
+ "deco": 16422,
+ "decor": 5148,
+ "decor": 6928,
+ "decorate": 23651,
+ "decorated": 15917,
+ "decorating": 16968,
+ "decoration": 16029,
+ "decorations": 19158,
+ "decorative": 19289,
+ "decre": 12284,
+ "decrease": 24703,
+ "decreased": 33913,
+ "decreasing": 43763,
+ "decree": 43327,
+ "ded": 16744,
+ "ded": 1241,
+ "dedic": 4701,
+ "dedicate": 27610,
+ "dedicated": 6770,
+ "dedication": 10188,
+ "dedly": 36204,
+ "deduc": 22799,
+ "dee": 5268,
+ "dee": 6705,
+ "deed": 30260,
+ "deeds": 24516,
+ "deejay": 48304,
+ "deejay": 44511,
+ "deemed": 28102,
+ "deen": 26456,
+ "deen": 12912,
+ "deep": 5462,
+ "deep": 3383,
+ "deepak": 45528,
+ "deeper": 15224,
+ "deepest": 22245,
+ "deephouse": 35684,
+ "deepi": 19371,
+ "deepika": 34120,
+ "deepikap": 29903,
+ "deepikapadukone": 30646,
+ "deeplear": 22181,
+ "deeplearning": 24362,
+ "deeply": 11449,
+ "deer": 19454,
+ "deer": 8700,
+ "deere": 32901,
+ "dees": 12547,
+ "deets": 35537,
+ "def": 2044,
+ "def": 11649,
+ "defam": 35670,
+ "defamation": 42741,
+ "default": 21650,
+ "defe": 4148,
+ "defeat": 8477,
+ "defeated": 8927,
+ "defeating": 22594,
+ "defeats": 16317,
+ "defect": 44013,
+ "defects": 37485,
+ "defen": 3619,
+ "defence": 30307,
+ "defence": 9659,
+ "defend": 21970,
+ "defend": 11397,
+ "defended": 27161,
+ "defender": 10618,
+ "defenders": 20063,
+ "defending": 13098,
+ "defends": 20134,
+ "defense": 45875,
+ "defense": 6021,
+ "defenseman": 43714,
+ "defenses": 49198,
+ "defensive": 10824,
+ "defi": 17244,
+ "defiance": 36186,
+ "defiant": 47597,
+ "defibrill": 47684,
+ "defic": 18022,
+ "defici": 23387,
+ "deficiency": 30685,
+ "deficit": 20156,
+ "defin": 3188,
+ "define": 14919,
+ "defined": 15278,
+ "defines": 28218,
+ "defining": 20504,
+ "definite": 40793,
+ "definitely": 4824,
+ "definition": 11405,
+ "definitive": 25298,
+ "defl": 31467,
+ "deforestation": 41330,
+ "defstar": 36427,
+ "defy": 39148,
+ "defying": 38496,
+ "deg": 38498,
+ "degra": 28939,
+ "degradation": 44468,
+ "degre": 4653,
+ "degree": 7119,
+ "degrees": 8000,
+ "deh": 35582,
+ "dei": 33833,
+ "dei": 23279,
+ "deir": 42948,
+ "deity": 42574,
+ "deja": 46902,
+ "dek": 23901,
+ "dekalb": 37775,
+ "del": 1233,
+ "del": 2003,
+ "dela": 37986,
+ "delaney": 31528,
+ "delav": 23706,
+ "delavin": 40477,
+ "delavin": 40776,
+ "delavinkisses": 40631,
+ "delaware": 17547,
+ "delay": 12955,
+ "delay": 10934,
+ "delayed": 14567,
+ "delaying": 43781,
+ "delays": 11232,
+ "dele": 7922,
+ "dele": 33431,
+ "delec": 38615,
+ "delectable": 45500,
+ "deleg": 8046,
+ "delegate": 27259,
+ "delegates": 14623,
+ "delegation": 14632,
+ "delete": 19204,
+ "deleted": 16588,
+ "deleting": 41857,
+ "delft": 42749,
+ "delgado": 49182,
+ "delhi": 26723,
+ "delhi": 5717,
+ "deli": 1932,
+ "deli": 18601,
+ "delia": 33193,
+ "deliber": 18316,
+ "deliberate": 38271,
+ "deliberately": 35163,
+ "delic": 13366,
+ "delicacy": 49181,
+ "delicate": 18768,
+ "delici": 19993,
+ "delicious": 3959,
+ "deliciously": 39589,
+ "deliciousness": 42819,
+ "delight": 46165,
+ "delight": 13073,
+ "delighted": 5943,
+ "delightful": 15513,
+ "delights": 25330,
+ "deline": 18797,
+ "delines": 13562,
+ "delish": 25093,
+ "deliver": 19561,
+ "deliver": 7396,
+ "delivered": 7278,
+ "deliveries": 29336,
+ "delivering": 9943,
+ "delivers": 11753,
+ "delivery": 5619,
+ "dell": 24381,
+ "dell": 10242,
+ "della": 22986,
+ "delle": 35963,
+ "deloit": 29428,
+ "deloitte": 38667,
+ "dels": 48636,
+ "delta": 32250,
+ "delta": 8768,
+ "delu": 18779,
+ "delusional": 48059,
+ "delux": 13709,
+ "deluxe": 14056,
+ "delve": 46008,
+ "dely": 15040,
+ "dem": 3251,
+ "dem": 7825,
+ "dema": 40268,
+ "dema": 45046,
+ "deman": 48366,
+ "demand": 13072,
+ "demand": 5650,
+ "demanded": 33699,
+ "demanding": 17099,
+ "demands": 14241,
+ "demar": 46566,
+ "demarcus": 47873,
+ "demb": 35930,
+ "demdebate": 43973,
+ "deme": 25143,
+ "demean": 37376,
+ "demen": 12604,
+ "dementi": 46028,
+ "dementia": 14047,
+ "demetri": 39553,
+ "demi": 32879,
+ "demi": 14480,
+ "demise": 28756,
+ "demo": 2930,
+ "demo": 7380,
+ "democr": 3573,
+ "democracy": 7758,
+ "democrat": 15431,
+ "democratic": 9149,
+ "democrats": 8865,
+ "demographic": 31308,
+ "demol": 19382,
+ "demolished": 26537,
+ "demolition": 22237,
+ "demon": 5635,
+ "demon": 12085,
+ "demonetisation": 41338,
+ "demonic": 46920,
+ "demons": 18388,
+ "demonstr": 8579,
+ "demonstrate": 22231,
+ "demonstrated": 29477,
+ "demonstrates": 24806,
+ "demonstrating": 22107,
+ "demonstration": 16722,
+ "demonstrations": 33964,
+ "demonstrators": 46450,
+ "demos": 19304,
+ "demp": 22490,
+ "dempsey": 30188,
+ "dems": 10989,
+ "demsin": 42664,
+ "demsinphilly": 43091,
+ "den": 1177,
+ "den": 1181,
+ "dena": 32431,
+ "denali": 48076,
+ "dence": 3370,
+ "dency": 11659,
+ "dend": 37447,
+ "dends": 43985,
+ "dene": 45128,
+ "dened": 19571,
+ "deng": 43098,
+ "deng": 41788,
+ "dengue": 41932,
+ "denham": 39180,
+ "deni": 21995,
+ "denial": 25716,
+ "denied": 15780,
+ "denies": 19565,
+ "denim": 13606,
+ "denis": 47630,
+ "denis": 18750,
+ "denise": 45900,
+ "denise": 20899,
+ "denmark": 13268,
+ "dennis": 32738,
+ "dennis": 10534,
+ "denny": 26808,
+ "denomin": 41016,
+ "dens": 16533,
+ "dense": 19353,
+ "density": 22431,
+ "dent": 3593,
+ "dent": 1258,
+ "dental": 24635,
+ "dental": 8382,
+ "dentally": 10346,
+ "dented": 21923,
+ "denti": 4418,
+ "dential": 5459,
+ "dentist": 17816,
+ "dentistry": 25754,
+ "dently": 28817,
+ "denton": 23567,
+ "dents": 1517,
+ "denver": 27847,
+ "denver": 8569,
+ "deny": 18679,
+ "denying": 32771,
+ "denzel": 42503,
+ "deo": 26406,
+ "deo": 12121,
+ "deodor": 47639,
+ "deol": 41902,
+ "deon": 31466,
+ "deon": 16079,
+ "dep": 6079,
+ "dep": 24370,
+ "depar": 10794,
+ "depart": 5343,
+ "depart": 30649,
+ "departed": 32541,
+ "departing": 26902,
+ "department": 5744,
+ "departments": 29523,
+ "departs": 38998,
+ "departure": 17850,
+ "depe": 36118,
+ "depend": 13894,
+ "depend": 27371,
+ "dependence": 40243,
+ "dependent": 23280,
+ "depending": 23673,
+ "depends": 20497,
+ "depic": 11307,
+ "depicted": 34637,
+ "depicting": 24970,
+ "depiction": 31071,
+ "depicts": 29340,
+ "deple": 38504,
+ "deplo": 9356,
+ "deplor": 39232,
+ "deploy": 26944,
+ "deployed": 20009,
+ "deploying": 42212,
+ "deployment": 20183,
+ "depo": 14276,
+ "depor": 36110,
+ "deport": 23389,
+ "deportation": 36617,
+ "deported": 39320,
+ "deportes": 47878,
+ "depos": 21266,
+ "deposit": 16775,
+ "deposits": 30740,
+ "depot": 12589,
+ "depp": 24941,
+ "depre": 7107,
+ "depress": 38869,
+ "depressed": 23269,
+ "depressing": 29235,
+ "depression": 10023,
+ "depri": 28587,
+ "depriv": 45809,
+ "deprivation": 47810,
+ "deprived": 39140,
+ "dept": 9201,
+ "depth": 10350,
+ "depths": 28855,
+ "depu": 6912,
+ "deputies": 24914,
+ "deputy": 7932,
+ "der": 839,
+ "der": 801,
+ "dera": 20696,
+ "derail": 48502,
+ "derby": 13904,
+ "derby": 7177,
+ "derbyshire": 22147,
+ "derdale": 21513,
+ "dere": 5701,
+ "dere": 44194,
+ "dered": 3776,
+ "derek": 22461,
+ "derek": 11205,
+ "derel": 46728,
+ "derer": 11289,
+ "derers": 20882,
+ "deri": 34573,
+ "derick": 33908,
+ "dering": 6076,
+ "deriv": 33458,
+ "derived": 26461,
+ "derland": 35488,
+ "derman": 29740,
+ "dermatology": 48051,
+ "dern": 30086,
+ "dero": 37203,
+ "dero": 34026,
+ "derrick": 21798,
+ "derry": 45777,
+ "derry": 20535,
+ "ders": 37307,
+ "ders": 1923,
+ "derson": 12677,
+ "dery": 17172,
+ "des": 6797,
+ "des": 1437,
+ "desai": 35316,
+ "desc": 13866,
+ "descen": 32318,
+ "descend": 26004,
+ "descend": 46241,
+ "descendants": 36323,
+ "descending": 36620,
+ "descent": 19375,
+ "desch": 49209,
+ "descri": 4637,
+ "describe": 10967,
+ "described": 14671,
+ "describes": 13678,
+ "describing": 24239,
+ "descrip": 41832,
+ "description": 13951,
+ "descriptions": 40653,
+ "desde": 42218,
+ "dese": 27195,
+ "deser": 3659,
+ "desert": 45776,
+ "desert": 7301,
+ "deserted": 41560,
+ "deserve": 7043,
+ "deserved": 10061,
+ "deserves": 9079,
+ "deserving": 26615,
+ "desh": 25320,
+ "desh": 7448,
+ "deshi": 42769,
+ "desi": 6772,
+ "desi": 26635,
+ "desig": 1250,
+ "design": 8359,
+ "design": 1681,
+ "designated": 24119,
+ "designation": 41155,
+ "designed": 4486,
+ "designer": 35640,
+ "designer": 5728,
+ "designers": 12720,
+ "designing": 13467,
+ "designs": 6747,
+ "designthinking": 32450,
+ "desirable": 32368,
+ "desire": 11858,
+ "desired": 28631,
+ "desires": 27598,
+ "desk": 11937,
+ "desk": 6550,
+ "desks": 41014,
+ "desktop": 14345,
+ "desmond": 27821,
+ "desol": 41258,
+ "desp": 3642,
+ "despair": 28097,
+ "desper": 10144,
+ "desperate": 15072,
+ "desperately": 21993,
+ "despic": 32442,
+ "despicable": 37158,
+ "despite": 5325,
+ "dess": 7096,
+ "dess": 10001,
+ "dessert": 9753,
+ "desserts": 22948,
+ "desses": 43913,
+ "dest": 6540,
+ "dest": 4549,
+ "destin": 4934,
+ "destination": 32191,
+ "destination": 9179,
+ "destinations": 16981,
+ "destined": 28525,
+ "destiny": 39875,
+ "destiny": 10867,
+ "destro": 8287,
+ "destroy": 8308,
+ "destroy": 11930,
+ "destroyed": 9965,
+ "destroyer": 25291,
+ "destroying": 19613,
+ "destroys": 27634,
+ "destruc": 22945,
+ "destruction": 14281,
+ "destructive": 29591,
+ "det": 28966,
+ "det": 15366,
+ "deta": 1914,
+ "detached": 26252,
+ "detail": 7657,
+ "detailed": 12609,
+ "detailing": 23163,
+ "details": 2353,
+ "detained": 20260,
+ "dete": 5606,
+ "detec": 17991,
+ "detect": 22744,
+ "detected": 26988,
+ "detecting": 41290,
+ "detection": 16220,
+ "detective": 13672,
+ "detectives": 27994,
+ "detector": 27689,
+ "detectors": 45063,
+ "detention": 16908,
+ "deter": 10742,
+ "deter": 47458,
+ "detergent": 46726,
+ "deterior": 28512,
+ "determin": 8325,
+ "determination": 17410,
+ "determine": 16768,
+ "determined": 14371,
+ "determines": 42192,
+ "determining": 39884,
+ "deth": 38375,
+ "deto": 39710,
+ "deton": 39335,
+ "detour": 31211,
+ "detox": 22459,
+ "detri": 47951,
+ "detro": 6210,
+ "detroit": 19404,
+ "detroit": 7073,
+ "detta": 45438,
+ "dette": 35750,
+ "deu": 21457,
+ "deuce": 45332,
+ "deus": 37625,
+ "deut": 14970,
+ "deutsch": 30389,
+ "deutsche": 32760,
+ "deutschland": 36878,
+ "deux": 47089,
+ "dev": 2797,
+ "dev": 3670,
+ "deva": 45179,
+ "devan": 37072,
+ "devast": 12913,
+ "devastated": 29865,
+ "devastating": 19280,
+ "devastation": 42452,
+ "devel": 1820,
+ "develop": 1966,
+ "develop": 7708,
+ "developed": 8763,
+ "developer": 10929,
+ "developers": 13248,
+ "developing": 8131,
+ "development": 2855,
+ "developmental": 29347,
+ "developments": 17393,
+ "develops": 29895,
+ "deven": 45537,
+ "devgn": 29871,
+ "devi": 12926,
+ "devi": 20717,
+ "deviant": 25593,
+ "deviantart": 26046,
+ "device": 8163,
+ "devices": 9067,
+ "devil": 8894,
+ "devil": 8043,
+ "deville": 34329,
+ "devils": 11683,
+ "devin": 31193,
+ "devin": 20996,
+ "devine": 33019,
+ "devlin": 48040,
+ "devo": 11861,
+ "devo": 43444,
+ "devon": 16205,
+ "devon": 10046,
+ "devops": 21504,
+ "devos": 40646,
+ "devote": 37777,
+ "devoted": 24561,
+ "devotees": 39759,
+ "devotion": 25821,
+ "devotional": 35456,
+ "devs": 27374,
+ "dew": 31952,
+ "dew": 16358,
+ "dewey": 40399,
+ "dex": 10030,
+ "dex": 13790,
+ "dexpo": 42502,
+ "dexter": 45049,
+ "dexter": 22781,
+ "dey": 11829,
+ "dez": 23190,
+ "dez": 8122,
+ "df": 12908,
+ "df": 10468,
+ "dfc": 41903,
+ "dfs": 32880,
+ "dfw": 20439,
+ "dg": 2394,
+ "dg": 9742,
+ "dgate": 41684,
+ "dge": 4016,
+ "dge": 1360,
+ "dged": 11830,
+ "dgeon": 45655,
+ "dgers": 8733,
+ "dges": 5432,
+ "dging": 9565,
+ "dh": 6669,
+ "dh": 9960,
+ "dha": 11629,
+ "dha": 27377,
+ "dhabi": 22349,
+ "dhaka": 32877,
+ "dham": 29635,
+ "dham": 30838,
+ "dhan": 12542,
+ "dhan": 28569,
+ "dhanush": 26162,
+ "dhanush": 36200,
+ "dhanushkraja": 29266,
+ "dhar": 12397,
+ "dharma": 30536,
+ "dhary": 28706,
+ "dhawan": 44699,
+ "dhe": 29706,
+ "dheim": 44280,
+ "dhi": 31553,
+ "dhi": 26166,
+ "dho": 37834,
+ "dhoni": 25698,
+ "dhru": 40257,
+ "dhry": 39960,
+ "dhs": 26849,
+ "dhu": 32387,
+ "di": 570,
+ "di": 1618,
+ "dia": 7351,
+ "dia": 3357,
+ "diab": 15954,
+ "diabe": 19167,
+ "diabete": 43826,
+ "diabetes": 10319,
+ "diabetic": 30230,
+ "diablo": 23931,
+ "diag": 6851,
+ "diagno": 7736,
+ "diagnose": 44429,
+ "diagnosed": 16979,
+ "diagnosis": 15715,
+ "diagnostic": 26351,
+ "diagnostics": 37723,
+ "diagram": 22697,
+ "dial": 18416,
+ "dial": 11381,
+ "dialo": 30709,
+ "dialog": 48945,
+ "dialogue": 11288,
+ "dialogues": 40330,
+ "dialysis": 44798,
+ "diam": 4347,
+ "diameter": 27189,
+ "diamon": 8873,
+ "diamond": 18535,
+ "diamond": 6235,
+ "diamonds": 12687,
+ "dian": 16021,
+ "dian": 4998,
+ "diana": 12803,
+ "diane": 15855,
+ "dianne": 42299,
+ "dians": 21041,
+ "diaper": 34382,
+ "diapers": 39659,
+ "diar": 25932,
+ "diaries": 15541,
+ "diary": 10380,
+ "dias": 22137,
+ "dias": 29354,
+ "diaspora": 28390,
+ "diaz": 17688,
+ "dic": 1404,
+ "dic": 6717,
+ "dicap": 30023,
+ "dicaprio": 30755,
+ "dice": 14406,
+ "dick": 14413,
+ "dick": 9554,
+ "dickens": 33421,
+ "dict": 45360,
+ "dict": 15159,
+ "dictat": 26156,
+ "dictator": 27399,
+ "dictatorship": 37989,
+ "dictionary": 19699,
+ "did": 1861,
+ "did": 1335,
+ "diddy": 33527,
+ "didi": 34396,
+ "didier": 45614,
+ "didn": 2376,
+ "didnt": 13057,
+ "dido": 31725,
+ "didyou": 12295,
+ "didyouknow": 12506,
+ "die": 3150,
+ "die": 2082,
+ "diec": 27729,
+ "diecast": 37936,
+ "died": 3622,
+ "diego": 30940,
+ "diego": 6306,
+ "diem": 45571,
+ "dience": 33686,
+ "dient": 27231,
+ "dier": 29702,
+ "dier": 16394,
+ "dies": 20104,
+ "dies": 1862,
+ "diesel": 46312,
+ "diesel": 10591,
+ "diest": 45739,
+ "diet": 21295,
+ "diet": 6582,
+ "dietary": 29009,
+ "dietrich": 47005,
+ "diets": 35173,
+ "dif": 18656,
+ "dif": 48731,
+ "diff": 44073,
+ "diff": 20331,
+ "diffe": 1967,
+ "differ": 34620,
+ "differen": 14903,
+ "difference": 4731,
+ "differences": 14003,
+ "different": 2731,
+ "differenti": 21729,
+ "differential": 34027,
+ "differentiate": 49032,
+ "differently": 18325,
+ "diffic": 6140,
+ "difficult": 7405,
+ "difficulties": 23468,
+ "difficulty": 25245,
+ "diffu": 31603,
+ "diffuser": 49400,
+ "dig": 1831,
+ "dig": 9887,
+ "dige": 17820,
+ "digest": 20413,
+ "digestion": 40533,
+ "digestive": 32304,
+ "digg": 43240,
+ "digger": 35919,
+ "diggin": 48466,
+ "digging": 14971,
+ "digi": 15627,
+ "digi": 39361,
+ "digimon": 44181,
+ "digit": 14899,
+ "digit": 27472,
+ "digital": 4704,
+ "digital": 2794,
+ "digitalart": 16987,
+ "digitalhealth": 32190,
+ "digitalindia": 46630,
+ "digitally": 27543,
+ "digitalmarketing": 15299,
+ "digitaltransformation": 20047,
+ "digiti": 25935,
+ "digits": 31710,
+ "digni": 45532,
+ "dignit": 39497,
+ "dignity": 17744,
+ "digo": 35701,
+ "digs": 26877,
+ "dih": 43089,
+ "dii": 32755,
+ "dijk": 44444,
+ "dik": 38854,
+ "dik": 37747,
+ "dike": 42683,
+ "dil": 7643,
+ "dil": 17942,
+ "dile": 25428,
+ "dilemma": 29787,
+ "dilig": 30664,
+ "dill": 12318,
+ "dill": 27206,
+ "dillon": 21056,
+ "dilu": 45242,
+ "dim": 19576,
+ "dim": 17523,
+ "dime": 24443,
+ "dimen": 10935,
+ "dimension": 20479,
+ "dimensional": 25252,
+ "dimensions": 25086,
+ "diment": 43500,
+ "dimes": 44888,
+ "dimini": 37459,
+ "dimit": 22250,
+ "dimitri": 48840,
+ "dimp": 38853,
+ "din": 1462,
+ "din": 5673,
+ "dina": 36815,
+ "dinah": 30903,
+ "dine": 20951,
+ "dine": 12989,
+ "diner": 16963,
+ "dinesh": 48341,
+ "ding": 7545,
+ "ding": 796,
+ "dinger": 45580,
+ "dingh": 48064,
+ "dings": 5473,
+ "dington": 24804,
+ "dinho": 47370,
+ "dini": 20196,
+ "dining": 8658,
+ "dinner": 27548,
+ "dinner": 2571,
+ "dinners": 33570,
+ "dino": 9692,
+ "dino": 14077,
+ "dinosa": 18955,
+ "dinosaur": 15095,
+ "dinosaurs": 20387,
+ "dio": 3779,
+ "dio": 1521,
+ "dioce": 20763,
+ "diocese": 27091,
+ "dion": 42899,
+ "dion": 16250,
+ "dior": 23655,
+ "dios": 37563,
+ "dious": 27417,
+ "dioxide": 38102,
+ "dip": 19918,
+ "dip": 11343,
+ "dipl": 8490,
+ "diplo": 38115,
+ "diplom": 11169,
+ "diploma": 21251,
+ "diplomacy": 23798,
+ "diplomat": 32828,
+ "diplomatic": 23782,
+ "diplomats": 44126,
+ "dipped": 30610,
+ "dipper": 49317,
+ "dipping": 33544,
+ "dips": 37522,
+ "dir": 4251,
+ "dir": 8478,
+ "dire": 38355,
+ "dire": 25664,
+ "direc": 1534,
+ "direct": 43224,
+ "direct": 6016,
+ "directed": 8392,
+ "directing": 21817,
+ "direction": 15923,
+ "direction": 5407,
+ "directional": 38687,
+ "directioner": 48042,
+ "directioners": 22055,
+ "directions": 16440,
+ "directive": 40630,
+ "directly": 9701,
+ "director": 20337,
+ "director": 2681,
+ "directorial": 45327,
+ "directors": 11940,
+ "directory": 25272,
+ "directs": 34349,
+ "directv": 48652,
+ "dirk": 28171,
+ "dirt": 31415,
+ "dirt": 11795,
+ "dirty": 20127,
+ "dirty": 7615,
+ "dis": 1518,
+ "dis": 6112,
+ "disa": 3882,
+ "disab": 47380,
+ "disabilities": 17350,
+ "disability": 48986,
+ "disability": 13261,
+ "disabled": 13613,
+ "disadvantaged": 40577,
+ "disagree": 23199,
+ "disapp": 5384,
+ "disappear": 21148,
+ "disappear": 25173,
+ "disappearance": 35929,
+ "disappeared": 23139,
+ "disappearing": 35819,
+ "disappears": 44406,
+ "disappo": 7605,
+ "disappoint": 25446,
+ "disappointed": 13794,
+ "disappointing": 21941,
+ "disappointment": 23884,
+ "disappoints": 48545,
+ "disappro": 48276,
+ "disar": 42971,
+ "disaster": 9072,
+ "disasters": 26976,
+ "disastrous": 35790,
+ "disc": 1472,
+ "disc": 10712,
+ "discar": 40532,
+ "discarded": 45197,
+ "discer": 49140,
+ "dischar": 22671,
+ "discharge": 32485,
+ "disci": 9559,
+ "discip": 38951,
+ "discipl": 10467,
+ "disciples": 39366,
+ "disciplinary": 20232,
+ "discipline": 18903,
+ "disciplines": 42032,
+ "discla": 40248,
+ "disclaimer": 46465,
+ "disclo": 17481,
+ "disclose": 46379,
+ "disclosed": 30905,
+ "disclosure": 26502,
+ "disco": 2475,
+ "disco": 11964,
+ "discography": 47545,
+ "discomfort": 48054,
+ "discord": 23582,
+ "discoun": 18515,
+ "discount": 7638,
+ "discounted": 20993,
+ "discounts": 18186,
+ "discoura": 45850,
+ "discourse": 29441,
+ "discover": 10539,
+ "discover": 4834,
+ "discovered": 6986,
+ "discoveries": 29308,
+ "discovering": 17967,
+ "discovers": 29719,
+ "discovery": 40491,
+ "discovery": 8027,
+ "discre": 20616,
+ "discrimin": 11721,
+ "discrimination": 14775,
+ "discs": 29270,
+ "discu": 1984,
+ "discus": 41828,
+ "discuss": 4312,
+ "discussed": 11300,
+ "discusses": 8116,
+ "discussing": 5900,
+ "discussion": 5060,
+ "discussions": 13806,
+ "dise": 4262,
+ "disease": 5336,
+ "diseases": 12035,
+ "disen": 46468,
+ "disgrace": 29877,
+ "disgraceful": 44146,
+ "disgu": 9793,
+ "disguise": 27803,
+ "disguised": 37149,
+ "disgusted": 41977,
+ "disgusting": 16218,
+ "dish": 11039,
+ "dish": 4531,
+ "disha": 42498,
+ "dishes": 11412,
+ "dishon": 30777,
+ "dishu": 44728,
+ "dishwasher": 40524,
+ "disin": 19484,
+ "disinfe": 48050,
+ "disintegr": 49275,
+ "disk": 17970,
+ "dislike": 30796,
+ "dism": 30836,
+ "dism": 38821,
+ "dismant": 36557,
+ "dismiss": 43287,
+ "dismissal": 42068,
+ "dismissed": 30087,
+ "dismisses": 45238,
+ "disney": 6729,
+ "disney": 4696,
+ "disneyland": 39481,
+ "disneyland": 13661,
+ "disneyworld": 28469,
+ "diso": 26305,
+ "disobe": 42841,
+ "dison": 19310,
+ "disorder": 12635,
+ "disorders": 17114,
+ "disp": 11073,
+ "dispar": 24633,
+ "disparities": 45122,
+ "dispat": 28652,
+ "dispatch": 26306,
+ "dispen": 19077,
+ "dispenser": 40116,
+ "disper": 34499,
+ "displa": 9326,
+ "displac": 17718,
+ "displaced": 22817,
+ "displacement": 37931,
+ "display": 4456,
+ "displayed": 18967,
+ "displaying": 26468,
+ "displays": 15648,
+ "dispo": 13651,
+ "dispon": 38872,
+ "disponible": 46130,
+ "dispos": 45177,
+ "disposable": 37275,
+ "disposal": 28231,
+ "dispro": 32927,
+ "dispropor": 40354,
+ "disproportion": 45492,
+ "disregard": 43869,
+ "disrespect": 34055,
+ "disrespectful": 41723,
+ "disru": 13763,
+ "disrup": 14641,
+ "disrupt": 25214,
+ "disrupted": 46674,
+ "disrupting": 42419,
+ "disruption": 19635,
+ "disruptive": 31554,
+ "diss": 10766,
+ "diss": 35688,
+ "dissec": 43879,
+ "dissemin": 40463,
+ "dissent": 45154,
+ "disser": 25560,
+ "dissertation": 29448,
+ "dissi": 25088,
+ "dissol": 27398,
+ "dissuper": 33461,
+ "dist": 5479,
+ "dist": 12116,
+ "distance": 7964,
+ "distances": 37078,
+ "distant": 18949,
+ "distill": 41586,
+ "distilled": 49179,
+ "distillery": 22200,
+ "distin": 11892,
+ "distinct": 25056,
+ "distinction": 28183,
+ "distinctive": 25486,
+ "distingui": 15053,
+ "distinguish": 45418,
+ "distinguished": 16513,
+ "distor": 23781,
+ "distortion": 43690,
+ "distr": 11885,
+ "distract": 39309,
+ "distracted": 24049,
+ "distraction": 32039,
+ "distress": 26866,
+ "distressed": 37515,
+ "distri": 5987,
+ "distribu": 6138,
+ "distribute": 32313,
+ "distributed": 16419,
+ "distributing": 35216,
+ "distribution": 10484,
+ "distributor": 28354,
+ "distributors": 44240,
+ "distric": 3208,
+ "district": 46683,
+ "district": 3506,
+ "districts": 17565,
+ "distur": 11732,
+ "disturb": 33018,
+ "disturb": 39449,
+ "disturbance": 42416,
+ "disturbed": 29967,
+ "disturbing": 21476,
+ "disupdates": 45667,
+ "dit": 5752,
+ "dit": 2524,
+ "dita": 47965,
+ "ditch": 43715,
+ "ditch": 19291,
+ "dited": 40392,
+ "diti": 2363,
+ "dition": 16452,
+ "dition": 3015,
+ "ditional": 4322,
+ "ditions": 4503,
+ "dito": 43705,
+ "dits": 49374,
+ "dity": 16436,
+ "dium": 2903,
+ "div": 5293,
+ "div": 14869,
+ "diva": 13605,
+ "divas": 23534,
+ "dive": 26042,
+ "dive": 9058,
+ "diver": 13119,
+ "diver": 22094,
+ "divergence": 48735,
+ "divergent": 36132,
+ "divers": 30241,
+ "divers": 27038,
+ "diverse": 11464,
+ "diversi": 24475,
+ "diversion": 38457,
+ "diversity": 35634,
+ "diversity": 6257,
+ "diverted": 41049,
+ "dives": 13893,
+ "divi": 8375,
+ "divid": 31337,
+ "divide": 18842,
+ "divided": 18689,
+ "dividend": 32067,
+ "dividends": 45146,
+ "dividing": 45605,
+ "divin": 21838,
+ "divine": 46919,
+ "divine": 10976,
+ "diving": 9886,
+ "divinity": 39754,
+ "divisi": 39196,
+ "division": 5378,
+ "divisional": 40912,
+ "divisions": 33715,
+ "divor": 13543,
+ "divorce": 17060,
+ "divorced": 39437,
+ "divya": 47767,
+ "diwali": 18218,
+ "dix": 45838,
+ "dix": 27620,
+ "dixie": 24484,
+ "dixit": 28279,
+ "dixon": 16086,
+ "diy": 28472,
+ "diy": 7845,
+ "diya": 36459,
+ "diz": 32740,
+ "dized": 36232,
+ "dizz": 40239,
+ "dizzy": 35464,
+ "dj": 3761,
+ "dj": 3723,
+ "djan": 35338,
+ "django": 46498,
+ "dji": 35284,
+ "dji": 28379,
+ "djing": 36113,
+ "djo": 19432,
+ "djoker": 42721,
+ "djokernole": 42830,
+ "djokovic": 27944,
+ "djs": 18117,
+ "dk": 20702,
+ "dk": 16196,
+ "dl": 12558,
+ "dl": 9373,
+ "dlc": 19079,
+ "dle": 11057,
+ "dle": 3287,
+ "dled": 23494,
+ "dler": 40279,
+ "dles": 7890,
+ "dless": 14997,
+ "dley": 12808,
+ "dling": 18221,
+ "dly": 3069,
+ "dm": 19070,
+ "dm": 4667,
+ "dma": 42903,
+ "dman": 18826,
+ "dmc": 28991,
+ "dmit": 31607,
+ "dmitry": 48326,
+ "dms": 19955,
+ "dmv": 27508,
+ "dmx": 45255,
+ "dn": 11552,
+ "dn": 7459,
+ "dna": 8790,
+ "dnb": 35422,
+ "dnc": 20237,
+ "dnd": 11678,
+ "dnr": 37051,
+ "dns": 39245,
+ "dnt": 26795,
+ "do": 639,
+ "do": 818,
+ "doa": 48332,
+ "dob": 29640,
+ "doba": 35605,
+ "dobbs": 43006,
+ "dobson": 46888,
+ "doc": 3009,
+ "doc": 7251,
+ "doch": 25101,
+ "dock": 17311,
+ "dock": 8997,
+ "docked": 46784,
+ "docker": 31152,
+ "docking": 40845,
+ "docks": 24091,
+ "docs": 15157,
+ "doctor": 7872,
+ "doctor": 5547,
+ "doctoral": 23649,
+ "doctorate": 39134,
+ "doctors": 9705,
+ "doctorwho": 12996,
+ "doctr": 28497,
+ "doctrine": 35612,
+ "docu": 4433,
+ "document": 29293,
+ "document": 15121,
+ "documentaries": 44209,
+ "documentary": 7881,
+ "documentation": 31560,
+ "documented": 22310,
+ "documenting": 37876,
+ "documents": 14105,
+ "dod": 13847,
+ "dod": 30187,
+ "dodd": 36748,
+ "dodge": 31263,
+ "dodge": 12093,
+ "dodgeball": 43244,
+ "dodger": 31641,
+ "dodgers": 12422,
+ "dodgy": 37727,
+ "doe": 13296,
+ "does": 2397,
+ "does": 1897,
+ "doesn": 2503,
+ "doesnt": 17937,
+ "dof": 8277,
+ "doff": 20193,
+ "dofficial": 42516,
+ "dog": 4326,
+ "dog": 1929,
+ "dogcelebration": 41819,
+ "dogday": 27475,
+ "doge": 42187,
+ "dogg": 20749,
+ "doggie": 32237,
+ "doggo": 42155,
+ "doggy": 26359,
+ "doglo": 40733,
+ "dogre": 40030,
+ "dogrescue": 44158,
+ "dogs": 42182,
+ "dogs": 3255,
+ "dogsoftwitter": 19415,
+ "doh": 23581,
+ "doha": 20908,
+ "doherty": 31774,
+ "doi": 36361,
+ "doin": 15412,
+ "doing": 37408,
+ "doing": 1960,
+ "doit": 32272,
+ "doit": 28109,
+ "doj": 25700,
+ "dojo": 35901,
+ "dok": 40547,
+ "dok": 41034,
+ "doka": 46528,
+ "dol": 2287,
+ "dol": 19170,
+ "dola": 38005,
+ "dolan": 27200,
+ "dolby": 42414,
+ "dolce": 30033,
+ "dolce": 30661,
+ "dole": 41040,
+ "doll": 27031,
+ "doll": 9286,
+ "dollar": 35092,
+ "dollar": 7474,
+ "dollars": 10669,
+ "dolls": 15090,
+ "dolly": 43281,
+ "dolly": 23821,
+ "dolom": 37137,
+ "dolores": 40741,
+ "dolph": 8900,
+ "dolph": 22257,
+ "dolphin": 42963,
+ "dolphin": 16464,
+ "dolphins": 14002,
+ "dom": 2164,
+ "dom": 1919,
+ "domain": 15492,
+ "domaine": 48744,
+ "domains": 36358,
+ "dome": 8515,
+ "dome": 9827,
+ "domen": 37584,
+ "domest": 21936,
+ "domestic": 28189,
+ "domestic": 9043,
+ "domin": 4361,
+ "dominance": 30546,
+ "dominant": 20565,
+ "dominate": 21431,
+ "dominated": 23048,
+ "dominates": 34043,
+ "dominating": 29303,
+ "domination": 30919,
+ "domingo": 24882,
+ "dominic": 39007,
+ "dominic": 19095,
+ "dominican": 22934,
+ "dominion": 27155,
+ "domino": 30752,
+ "dominos": 39770,
+ "domo": 44293,
+ "doms": 30126,
+ "don": 1067,
+ "don": 847,
+ "dona": 26789,
+ "donal": 42375,
+ "donald": 5990,
+ "donald": 4335,
+ "donaldson": 37783,
+ "donaldtrump": 6652,
+ "donat": 36384,
+ "donate": 6429,
+ "donated": 8705,
+ "donates": 26960,
+ "donating": 12621,
+ "donation": 7924,
+ "donations": 9928,
+ "doncaster": 38008,
+ "doncaster": 25352,
+ "doncasterisgreat": 47333,
+ "done": 5136,
+ "done": 1700,
+ "donegal": 24172,
+ "donesia": 41281,
+ "donet": 33724,
+ "donetsk": 33999,
+ "dong": 26242,
+ "dong": 31478,
+ "dongha": 28365,
+ "donghae": 28945,
+ "donia": 24014,
+ "donkey": 21415,
+ "donkeys": 44644,
+ "donna": 9158,
+ "donne": 30897,
+ "donnein": 38308,
+ "donneinarte": 40193,
+ "donnell": 35118,
+ "donnelly": 39070,
+ "donnie": 47058,
+ "donnie": 30609,
+ "donny": 37291,
+ "donny": 32887,
+ "dono": 14840,
+ "donor": 18013,
+ "donors": 17887,
+ "donovan": 21499,
+ "dons": 22127,
+ "dont": 8094,
+ "dont": 4632,
+ "donut": 18471,
+ "donuts": 13970,
+ "doo": 4543,
+ "doo": 11643,
+ "doodle": 9388,
+ "doodled": 41030,
+ "doodles": 22156,
+ "doodling": 37548,
+ "dooley": 47609,
+ "doom": 23263,
+ "doom": 14344,
+ "doomed": 33251,
+ "doomsday": 41791,
+ "doon": 36612,
+ "doop": 33886,
+ "door": 7188,
+ "door": 2489,
+ "doors": 4228,
+ "doorstep": 19533,
+ "doorway": 46575,
+ "dop": 42381,
+ "dop": 31722,
+ "dope": 42587,
+ "dope": 10094,
+ "doping": 30285,
+ "dopp": 21774,
+ "doppelg": 45216,
+ "doppler": 42540,
+ "dor": 2766,
+ "dor": 8695,
+ "dora": 18104,
+ "dorado": 32350,
+ "dorchester": 32656,
+ "dore": 39423,
+ "dores": 34323,
+ "dorf": 17296,
+ "dori": 49270,
+ "doria": 43186,
+ "dorian": 44016,
+ "doris": 24285,
+ "dork": 36206,
+ "dorm": 24263,
+ "doro": 15498,
+ "doro": 37389,
+ "dorothy": 20805,
+ "dors": 31240,
+ "dorset": 42109,
+ "dorset": 16047,
+ "dorsey": 41607,
+ "dortmund": 24290,
+ "dory": 36135,
+ "dos": 44258,
+ "dos": 5474,
+ "dose": 11497,
+ "doses": 37873,
+ "dossier": 46042,
+ "dost": 44222,
+ "dot": 7473,
+ "dot": 7004,
+ "dota": 23085,
+ "dotcom": 12443,
+ "dote": 31202,
+ "dothis": 47864,
+ "dotnet": 43124,
+ "dotorg": 46587,
+ "dots": 19019,
+ "dotted": 47950,
+ "dou": 1756,
+ "dou": 23608,
+ "doub": 19631,
+ "double": 13013,
+ "double": 3200,
+ "doubled": 24948,
+ "doubleheader": 34668,
+ "doubles": 12539,
+ "doubling": 36850,
+ "doubt": 37071,
+ "doubt": 8671,
+ "doubts": 30894,
+ "douche": 44292,
+ "doug": 20271,
+ "doug": 10758,
+ "dough": 15785,
+ "dough": 14983,
+ "doughnut": 32555,
+ "doughnuts": 31124,
+ "dougie": 46317,
+ "dougla": 9140,
+ "douglas": 10065,
+ "douglass": 45692,
+ "doun": 44785,
+ "dov": 38856,
+ "dova": 26551,
+ "dove": 27511,
+ "dove": 18281,
+ "dover": 43019,
+ "dover": 14683,
+ "doves": 47067,
+ "dow": 8022,
+ "dow": 10688,
+ "dowell": 27344,
+ "down": 1833,
+ "down": 1136,
+ "downe": 46501,
+ "downed": 35814,
+ "downer": 42522,
+ "downers": 43739,
+ "downey": 29429,
+ "downfall": 48702,
+ "downhill": 27387,
+ "downing": 28140,
+ "download": 35076,
+ "download": 3794,
+ "downloadable": 49105,
+ "downloaded": 22961,
+ "downloading": 30519,
+ "downloads": 26481,
+ "downpour": 39034,
+ "downpours": 40160,
+ "downs": 10706,
+ "downside": 41937,
+ "downstairs": 28174,
+ "downstream": 43822,
+ "downtime": 41964,
+ "downton": 45023,
+ "downton": 42668,
+ "downtown": 18230,
+ "downtown": 5061,
+ "downward": 37430,
+ "dowski": 43556,
+ "dox": 44786,
+ "dox": 14510,
+ "doyle": 17728,
+ "doyou": 27256,
+ "doz": 31106,
+ "dozen": 16401,
+ "dozens": 17883,
+ "dp": 23820,
+ "dp": 6465,
+ "dprint": 46644,
+ "dprinting": 16194,
+ "dprk": 47920,
+ "dps": 34288,
+ "dq": 28741,
+ "dr": 1084,
+ "dr": 1701,
+ "dra": 1114,
+ "dra": 7402,
+ "drac": 20168,
+ "dracing": 41253,
+ "dracula": 25405,
+ "draf": 37426,
+ "draft": 30624,
+ "draft": 5198,
+ "drafted": 19129,
+ "drafting": 33528,
+ "drafts": 29194,
+ "drag": 8452,
+ "drag": 12463,
+ "dragged": 27884,
+ "dragging": 37069,
+ "dragon": 9187,
+ "dragon": 5471,
+ "dragonball": 40959,
+ "dragoncon": 47802,
+ "dragonfly": 32824,
+ "dragons": 10203,
+ "dragrace": 40762,
+ "drags": 45368,
+ "drain": 23347,
+ "drain": 19467,
+ "drainage": 25953,
+ "drained": 44630,
+ "drains": 43638,
+ "drainthe": 47337,
+ "drake": 32504,
+ "drake": 8958,
+ "dral": 7503,
+ "dram": 6937,
+ "dram": 32170,
+ "drama": 5055,
+ "dramas": 33467,
+ "dramati": 43512,
+ "dramatic": 11240,
+ "dramatically": 24495,
+ "drank": 21712,
+ "draped": 49113,
+ "drastic": 43159,
+ "drastically": 35478,
+ "drau": 18621,
+ "draw": 17675,
+ "draw": 4001,
+ "drawer": 23219,
+ "drawers": 38975,
+ "drawing": 36996,
+ "drawing": 3610,
+ "drawings": 13397,
+ "drawn": 8893,
+ "draws": 12043,
+ "dray": 25562,
+ "drayton": 49044,
+ "drc": 21434,
+ "dre": 960,
+ "dre": 14584,
+ "dread": 17412,
+ "dread": 31403,
+ "dreaded": 47227,
+ "dreadful": 35846,
+ "dreality": 48367,
+ "dream": 4595,
+ "dream": 2984,
+ "dreambig": 46495,
+ "dreamcast": 47226,
+ "dreamed": 27984,
+ "dreamer": 25692,
+ "dreamers": 27194,
+ "dreaming": 11662,
+ "dreamliner": 49143,
+ "dreams": 4405,
+ "dreamt": 43743,
+ "dreamteam": 40090,
+ "dreamy": 23517,
+ "dred": 10903,
+ "dredge": 48783,
+ "dren": 29068,
+ "dren": 47309,
+ "drenched": 46378,
+ "dres": 48852,
+ "dres": 44697,
+ "dresden": 34836,
+ "dress": 12622,
+ "dress": 2595,
+ "dressage": 36144,
+ "dressed": 6559,
+ "dresser": 26346,
+ "dresses": 8184,
+ "dressing": 6348,
+ "drew": 18792,
+ "drew": 5281,
+ "drex": 33985,
+ "drey": 48271,
+ "dri": 1203,
+ "dri": 28833,
+ "drian": 36870,
+ "dribb": 42153,
+ "dric": 23448,
+ "dridge": 22956,
+ "drie": 40170,
+ "dried": 16037,
+ "drier": 39877,
+ "dries": 33857,
+ "drif": 33585,
+ "drift": 18194,
+ "drifting": 30276,
+ "drill": 11626,
+ "drilled": 46338,
+ "drilling": 18634,
+ "drills": 24378,
+ "drin": 3375,
+ "drin": 47133,
+ "drink": 14131,
+ "drink": 3979,
+ "drinking": 5778,
+ "drinklocal": 45998,
+ "drinks": 6732,
+ "drip": 24050,
+ "dripping": 38787,
+ "dris": 35804,
+ "drive": 11402,
+ "drive": 2620,
+ "driven": 9314,
+ "driver": 27563,
+ "driver": 4383,
+ "driverless": 46769,
+ "drivers": 7384,
+ "drives": 11441,
+ "driveway": 26273,
+ "driving": 37800,
+ "driving": 4161,
+ "drizzle": 28240,
+ "drm": 39674,
+ "dro": 1494,
+ "dro": 12442,
+ "drogba": 49199,
+ "droid": 38016,
+ "drome": 9157,
+ "dron": 43898,
+ "dron": 23360,
+ "drone": 33557,
+ "drone": 9397,
+ "drones": 14006,
+ "droo": 30715,
+ "drool": 41554,
+ "drooling": 44360,
+ "drop": 16407,
+ "drop": 3387,
+ "dropbox": 47216,
+ "dropped": 6792,
+ "dropping": 8339,
+ "drops": 6437,
+ "dros": 47033,
+ "drou": 38558,
+ "drought": 13935,
+ "drove": 13753,
+ "drow": 21159,
+ "drown": 28571,
+ "drowned": 34005,
+ "drowning": 24618,
+ "drs": 21257,
+ "dru": 2275,
+ "dru": 49048,
+ "drug": 20601,
+ "drug": 5600,
+ "drugs": 8021,
+ "druid": 40297,
+ "drum": 13353,
+ "drum": 8698,
+ "drummer": 13618,
+ "drummers": 46191,
+ "drumming": 35480,
+ "drummond": 42213,
+ "drums": 11690,
+ "drun": 15488,
+ "drunk": 37398,
+ "drunk": 8232,
+ "drunken": 28196,
+ "drupal": 46481,
+ "drush": 43009,
+ "drwho": 48342,
+ "dry": 13544,
+ "dry": 4501,
+ "dryer": 24425,
+ "drying": 23203,
+ "ds": 3361,
+ "ds": 646,
+ "dsa": 47607,
+ "dsb": 47168,
+ "dsb": 14257,
+ "dsburg": 47237,
+ "dsc": 37240,
+ "dsd": 45383,
+ "dsley": 40740,
+ "dslr": 33740,
+ "dsm": 39502,
+ "dson": 40310,
+ "dsp": 45291,
+ "dss": 41580,
+ "dstv": 35027,
+ "dt": 13104,
+ "dt": 7427,
+ "dthe": 13863,
+ "dtla": 31885,
+ "dtm": 42407,
+ "dts": 46233,
+ "du": 691,
+ "du": 3686,
+ "dua": 25244,
+ "dual": 39739,
+ "dual": 5347,
+ "duane": 38946,
+ "dub": 14526,
+ "dub": 13144,
+ "duba": 5485,
+ "dubai": 32599,
+ "dubai": 5985,
+ "dubbed": 27740,
+ "dublin": 20707,
+ "dublin": 6145,
+ "dubnation": 47329,
+ "dubois": 48046,
+ "dubrov": 46709,
+ "dubrovnik": 48724,
+ "dubs": 27013,
+ "dubstep": 38303,
+ "dubu": 43257,
+ "duc": 979,
+ "duc": 36446,
+ "ducati": 28570,
+ "ducation": 17197,
+ "duce": 3660,
+ "duchess": 21713,
+ "duck": 12708,
+ "duck": 6910,
+ "ducks": 11202,
+ "duct": 26829,
+ "dude": 48087,
+ "dude": 5710,
+ "dudes": 14449,
+ "dudley": 27324,
+ "due": 2887,
+ "duel": 27143,
+ "dues": 37646,
+ "duet": 25457,
+ "duf": 38713,
+ "duff": 38071,
+ "duff": 21934,
+ "duffy": 23599,
+ "dug": 22743,
+ "dug": 21000,
+ "dugg": 40523,
+ "duggan": 46169,
+ "dugout": 36831,
+ "duh": 26716,
+ "dui": 29693,
+ "duk": 14160,
+ "duke": 18402,
+ "duke": 7732,
+ "dukes": 27914,
+ "dul": 6738,
+ "dulce": 44872,
+ "dulil": 32565,
+ "dulkar": 47980,
+ "dull": 19433,
+ "dulu": 28865,
+ "duluth": 32109,
+ "dulwich": 47343,
+ "dum": 13400,
+ "dum": 11564,
+ "dumb": 15901,
+ "dumb": 12464,
+ "dumbass": 38980,
+ "dummies": 40899,
+ "dummy": 34246,
+ "dump": 12655,
+ "dump": 17146,
+ "dumped": 23768,
+ "dumping": 31707,
+ "dumplings": 35495,
+ "dumps": 45804,
+ "dumpster": 45467,
+ "dun": 2616,
+ "dun": 18284,
+ "dunbar": 41453,
+ "duncan": 31084,
+ "duncan": 13502,
+ "dundal": 38185,
+ "dundas": 39300,
+ "dundee": 18619,
+ "dune": 32833,
+ "dune": 28208,
+ "dunedin": 40121,
+ "dunes": 23526,
+ "dung": 33712,
+ "dungeon": 28812,
+ "dungeon": 22931,
+ "dungeons": 42572,
+ "dungeonsand": 34970,
+ "dungeonsanddragons": 35497,
+ "dunham": 42501,
+ "duni": 43454,
+ "dunk": 17222,
+ "dunkin": 48022,
+ "dunkin": 36415,
+ "dunkirk": 46928,
+ "dunks": 48977,
+ "dunlop": 34753,
+ "dunn": 19185,
+ "dunne": 38538,
+ "dunno": 24502,
+ "duo": 8696,
+ "dup": 36805,
+ "dup": 10445,
+ "duper": 44850,
+ "duplex": 41186,
+ "duplic": 28992,
+ "dupont": 35994,
+ "dur": 4355,
+ "dur": 23230,
+ "dura": 28173,
+ "dura": 47382,
+ "durability": 43671,
+ "durable": 22285,
+ "duran": 28185,
+ "durango": 44443,
+ "durant": 24861,
+ "duras": 27518,
+ "duration": 31663,
+ "durban": 24474,
+ "dure": 19108,
+ "durga": 38456,
+ "durham": 26765,
+ "durham": 14335,
+ "during": 1590,
+ "dus": 9931,
+ "dusa": 28546,
+ "dusk": 19708,
+ "dust": 29723,
+ "dust": 8349,
+ "dusted": 38274,
+ "duster": 46280,
+ "dustin": 42423,
+ "dustin": 21235,
+ "dusting": 41756,
+ "dusty": 22029,
+ "dut": 32625,
+ "dutch": 22277,
+ "dutch": 7991,
+ "duter": 21624,
+ "duterte": 22371,
+ "duties": 19603,
+ "dutt": 30081,
+ "dutton": 42771,
+ "duty": 6458,
+ "duval": 42459,
+ "duvet": 48006,
+ "dux": 28562,
+ "dv": 4288,
+ "dv": 26265,
+ "dvd": 7170,
+ "dvds": 36655,
+ "dvn": 29811,
+ "dvr": 29210,
+ "dw": 8455,
+ "dw": 19997,
+ "dwar": 13487,
+ "dwarf": 22643,
+ "dwayne": 31395,
+ "dwell": 27549,
+ "dwell": 18755,
+ "dwelling": 37098,
+ "dwight": 22473,
+ "dwp": 46976,
+ "dwts": 30220,
+ "dwyer": 43878,
+ "dx": 22717,
+ "dx": 15679,
+ "dy": 1444,
+ "dy": 907,
+ "dyce": 48325,
+ "dye": 37159,
+ "dye": 15997,
+ "dyed": 24906,
+ "dyer": 29495,
+ "dyes": 39874,
+ "dying": 5115,
+ "dyk": 12142,
+ "dyke": 32632,
+ "dylan": 21004,
+ "dylan": 9900,
+ "dyn": 44289,
+ "dyn": 30669,
+ "dynam": 5735,
+ "dynamic": 10057,
+ "dynamics": 14329,
+ "dynamite": 29003,
+ "dynamo": 28281,
+ "dynasty": 14593,
+ "dyne": 42756,
+ "dyou": 11484,
+ "dyour": 22525,
+ "dys": 11022,
+ "dys": 38384,
+ "dysfunction": 36865,
+ "dysfunctional": 40757,
+ "dysle": 33681,
+ "dyslexia": 43199,
+ "dyson": 34475,
+ "dyssey": 17435,
+ "dystop": 28276,
+ "dystopian": 38915,
+ "dz": 24421,
+ "dz": 22913,
+ "dé": 25466,
+ "dü": 46948,
+ "dÃŃ": 46988,
+ "e": 68,
+ "e": 324,
+ "ea": 2150,
+ "ea": 8100,
+ "eable": 20693,
+ "each": 31442,
+ "each": 2416,
+ "eachother": 40792,
+ "ead": 42556,
+ "ead": 45523,
+ "eae": 27446,
+ "eag": 3743,
+ "eager": 21551,
+ "eagerly": 30094,
+ "eagle": 20207,
+ "eagle": 7517,
+ "eagles": 6920,
+ "eal": 48872,
+ "ealing": 40484,
+ "eames": 49072,
+ "eamon": 45954,
+ "ean": 13327,
+ "ear": 1055,
+ "ear": 8373,
+ "earbuds": 47807,
+ "eared": 9127,
+ "earl": 30573,
+ "earl": 14235,
+ "earle": 40292,
+ "earlier": 4297,
+ "earliest": 22097,
+ "early": 15840,
+ "early": 2090,
+ "earn": 33977,
+ "earn": 8465,
+ "earned": 8898,
+ "earnest": 45422,
+ "earning": 14550,
+ "earnings": 15912,
+ "earns": 16760,
+ "earp": 35296,
+ "earphones": 44905,
+ "earring": 28664,
+ "earrings": 9136,
+ "ears": 9861,
+ "eart": 7086,
+ "earth": 5184,
+ "earth": 3475,
+ "earthand": 34229,
+ "earthandclouds": 34480,
+ "earthday": 19481,
+ "earthquake": 10060,
+ "earthquakes": 32895,
+ "earthy": 47139,
+ "earts": 38824,
+ "eas": 5740,
+ "ease": 13574,
+ "easier": 8817,
+ "easiest": 26314,
+ "easily": 8197,
+ "easing": 44825,
+ "easport": 42251,
+ "east": 5022,
+ "east": 2602,
+ "eastbound": 28827,
+ "eastbourne": 38455,
+ "eastenders": 23545,
+ "easter": 14783,
+ "easter": 4811,
+ "eastern": 34522,
+ "eastern": 6311,
+ "eastman": 48280,
+ "easton": 29619,
+ "eastside": 42650,
+ "eastwood": 28270,
+ "easy": 18308,
+ "easy": 3176,
+ "eat": 5418,
+ "eat": 3384,
+ "eaten": 16750,
+ "eater": 24060,
+ "eaters": 37645,
+ "eatery": 46559,
+ "eating": 4371,
+ "eatlocal": 42868,
+ "eaton": 28462,
+ "eats": 13188,
+ "eau": 17608,
+ "eazy": 36536,
+ "eb": 12283,
+ "eb": 8677,
+ "eba": 40889,
+ "ebay": 34412,
+ "ebay": 4099,
+ "eber": 34020,
+ "ebo": 46635,
+ "ebola": 15864,
+ "ebon": 22013,
+ "ebony": 30651,
+ "ebook": 13122,
+ "ebooks": 25774,
+ "ec": 747,
+ "ec": 10879,
+ "eca": 18465,
+ "ecar": 34500,
+ "ecb": 26205,
+ "ecc": 33128,
+ "eccc": 47401,
+ "eccentric": 43228,
+ "eccle": 27494,
+ "ece": 2163,
+ "eces": 5905,
+ "ecg": 45983,
+ "ech": 15797,
+ "ech": 31147,
+ "echel": 41233,
+ "echo": 17366,
+ "echo": 13989,
+ "echoes": 32564,
+ "eci": 31936,
+ "eck": 25866,
+ "eck": 15969,
+ "ecker": 39661,
+ "ecker": 40890,
+ "ecla": 47806,
+ "eclec": 25114,
+ "eclectic": 28382,
+ "eclip": 30841,
+ "eclipse": 11505,
+ "eclub": 38983,
+ "eco": 5106,
+ "eco": 10077,
+ "ecofriendly": 43412,
+ "ecol": 22706,
+ "ecological": 25127,
+ "ecology": 18578,
+ "ecommerce": 15529,
+ "econ": 26755,
+ "econ": 21158,
+ "econom": 2768,
+ "economic": 36649,
+ "economic": 5259,
+ "economical": 48782,
+ "economically": 39406,
+ "economics": 12625,
+ "economies": 27136,
+ "economist": 18836,
+ "economists": 43701,
+ "economy": 5644,
+ "ecor": 28962,
+ "ecosystem": 15788,
+ "ecosystems": 28725,
+ "ecoun": 27924,
+ "ecr": 48572,
+ "ecraft": 11439,
+ "ecs": 23485,
+ "ecstasy": 47286,
+ "ecstatic": 36244,
+ "ect": 25168,
+ "ecu": 13087,
+ "ecu": 32919,
+ "ecuador": 19813,
+ "ecz": 43530,
+ "ed": 843,
+ "ed": 538,
+ "eda": 10804,
+ "edad": 44724,
+ "eday": 39258,
+ "edc": 21245,
+ "edchat": 14702,
+ "edd": 35431,
+ "eddi": 42930,
+ "eddie": 22748,
+ "eddie": 9517,
+ "eddy": 25959,
+ "ede": 29632,
+ "eded": 19555,
+ "edel": 20460,
+ "edelman": 48139,
+ "eden": 23621,
+ "eden": 13741,
+ "eder": 16249,
+ "edes": 36247,
+ "edfringe": 27402,
+ "edg": 35955,
+ "edgar": 33543,
+ "edgar": 17914,
+ "edge": 16914,
+ "edge": 5461,
+ "edged": 39188,
+ "edges": 20938,
+ "edgy": 35393,
+ "edi": 8750,
+ "edi": 27148,
+ "edible": 19795,
+ "edic": 25184,
+ "edics": 30641,
+ "edin": 6524,
+ "edinburgh": 27574,
+ "edinburgh": 8068,
+ "eding": 5742,
+ "edison": 25846,
+ "edit": 8239,
+ "edit": 8013,
+ "edited": 13945,
+ "edith": 28597,
+ "editing": 10178,
+ "edition": 3062,
+ "editions": 21664,
+ "editor": 7661,
+ "editorial": 12325,
+ "editors": 19486,
+ "edits": 24945,
+ "edm": 37843,
+ "edm": 13539,
+ "edmon": 11275,
+ "edmond": 41581,
+ "edmonds": 46520,
+ "edmonton": 37311,
+ "edmonton": 15058,
+ "edmun": 36561,
+ "edmund": 27567,
+ "edna": 39002,
+ "edo": 29145,
+ "edo": 18096,
+ "edon": 41467,
+ "edor": 30184,
+ "edou": 47678,
+ "edp": 46066,
+ "eds": 1941,
+ "edsheeran": 30386,
+ "edt": 15071,
+ "edtech": 41825,
+ "edtech": 15262,
+ "edu": 11757,
+ "edu": 11799,
+ "eduardo": 30604,
+ "educ": 2200,
+ "educate": 17563,
+ "educated": 21447,
+ "education": 22358,
+ "education": 2806,
+ "educational": 10400,
+ "educator": 19875,
+ "educators": 15420,
+ "edwar": 27586,
+ "edward": 26184,
+ "edward": 7450,
+ "edwards": 12627,
+ "edwin": 48718,
+ "edwin": 22471,
+ "edy": 17072,
+ "edy": 4144,
+ "ee": 2644,
+ "ee": 4708,
+ "eed": 17513,
+ "eee": 24632,
+ "eee": 9361,
+ "eeee": 11696,
+ "eeee": 17570,
+ "eeeee": 26938,
+ "eeeeee": 41407,
+ "eek": 46591,
+ "eel": 27462,
+ "eels": 44416,
+ "eem": 27236,
+ "een": 47490,
+ "een": 21230,
+ "eer": 35409,
+ "eer": 31846,
+ "eera": 36664,
+ "eerie": 33846,
+ "ees": 40308,
+ "eet": 48935,
+ "eez": 39033,
+ "ef": 1490,
+ "ef": 1829,
+ "efa": 16999,
+ "eface": 48804,
+ "efan": 33556,
+ "efc": 22065,
+ "efcc": 46087,
+ "efer": 26199,
+ "eff": 20548,
+ "eff": 21715,
+ "effe": 2808,
+ "effec": 3943,
+ "effect": 5436,
+ "effective": 6837,
+ "effectively": 17516,
+ "effectiveness": 26847,
+ "effects": 7331,
+ "effic": 36004,
+ "efficacy": 39937,
+ "effici": 6670,
+ "efficiency": 11823,
+ "efficient": 11334,
+ "efficiently": 32915,
+ "effor": 6356,
+ "effort": 40078,
+ "effort": 6255,
+ "effortless": 41639,
+ "effortlessly": 42320,
+ "efforts": 6847,
+ "efish": 35813,
+ "efl": 27172,
+ "efron": 48111,
+ "efs": 7389,
+ "eg": 8053,
+ "eg": 14599,
+ "ega": 41193,
+ "egan": 42943,
+ "eger": 46704,
+ "eger": 22767,
+ "egg": 13778,
+ "egg": 5911,
+ "eggplant": 34906,
+ "eggs": 7099,
+ "ego": 34712,
+ "ego": 14250,
+ "egos": 43992,
+ "egre": 27044,
+ "egret": 42002,
+ "egy": 5224,
+ "egyp": 10250,
+ "egypt": 7267,
+ "egyptian": 12428,
+ "eh": 9277,
+ "eh": 9135,
+ "eha": 48563,
+ "ehealth": 48617,
+ "ehr": 45271,
+ "ehs": 44648,
+ "ei": 4006,
+ "ei": 18264,
+ "eic": 40251,
+ "eid": 28038,
+ "eid": 13979,
+ "eidmubarak": 46275,
+ "eiffel": 29720,
+ "eigh": 13468,
+ "eight": 7910,
+ "eighteen": 49316,
+ "eighth": 21237,
+ "eighty": 47449,
+ "eil": 29457,
+ "eileen": 31468,
+ "ein": 29944,
+ "ein": 24524,
+ "eindhoven": 47172,
+ "eing": 7702,
+ "einstein": 20587,
+ "eira": 47708,
+ "eis": 13802,
+ "eisen": 25273,
+ "eisenhower": 35562,
+ "either": 6036,
+ "ej": 19887,
+ "ej": 25009,
+ "ejec": 29771,
+ "ek": 4212,
+ "ek": 2092,
+ "el": 544,
+ "el": 832,
+ "ela": 11284,
+ "ela": 3787,
+ "elab": 38866,
+ "elabor": 26034,
+ "elaborate": 33855,
+ "elaine": 22523,
+ "elan": 17763,
+ "elan": 18399,
+ "eland": 24930,
+ "eland": 6275,
+ "elas": 41078,
+ "elast": 27479,
+ "elastic": 30282,
+ "elba": 48598,
+ "elbow": 21965,
+ "eld": 5684,
+ "elder": 11791,
+ "elder": 14416,
+ "elderly": 15455,
+ "elders": 28617,
+ "eldest": 33503,
+ "elding": 28223,
+ "elds": 13466,
+ "ele": 2084,
+ "ele": 9766,
+ "eleague": 36577,
+ "eleanor": 18604,
+ "elearning": 29969,
+ "elec": 1564,
+ "elec": 38768,
+ "elect": 15336,
+ "elected": 8828,
+ "election": 19312,
+ "election": 4247,
+ "electionday": 40540,
+ "elections": 6949,
+ "elector": 16465,
+ "electoral": 19544,
+ "electr": 3654,
+ "electra": 48959,
+ "electri": 23927,
+ "electric": 19547,
+ "electric": 5031,
+ "electrical": 12176,
+ "electrician": 46422,
+ "electricity": 10950,
+ "electrifying": 48843,
+ "electro": 11648,
+ "electro": 23244,
+ "electromagnetic": 46530,
+ "electron": 33396,
+ "electronic": 33865,
+ "electronic": 9273,
+ "electronica": 43119,
+ "electronics": 13081,
+ "eled": 20357,
+ "elee": 44112,
+ "eleg": 8075,
+ "elegance": 19146,
+ "elegant": 11124,
+ "elek": 34559,
+ "elem": 25406,
+ "element": 14909,
+ "elementary": 8143,
+ "elements": 10925,
+ "elen": 30654,
+ "elen": 39164,
+ "elena": 19421,
+ "eleng": 48180,
+ "eleph": 7554,
+ "elephant": 10299,
+ "elephants": 16871,
+ "eler": 24646,
+ "eless": 15244,
+ "eless": 30837,
+ "elets": 19400,
+ "elev": 7921,
+ "elevate": 26736,
+ "elevated": 23967,
+ "elevation": 23826,
+ "elevator": 19021,
+ "eleven": 31617,
+ "eleven": 17795,
+ "elf": 45961,
+ "elf": 11924,
+ "elfie": 39955,
+ "elg": 28790,
+ "elgin": 31868,
+ "eli": 1018,
+ "eli": 6292,
+ "elia": 10956,
+ "elian": 42508,
+ "elias": 47274,
+ "elias": 29902,
+ "elic": 34743,
+ "elic": 13492,
+ "elie": 38677,
+ "elie": 26501,
+ "elier": 14634,
+ "elife": 37429,
+ "elife": 12719,
+ "eligibility": 34937,
+ "eligible": 16978,
+ "elijah": 26065,
+ "elike": 48913,
+ "elim": 9296,
+ "elimin": 11386,
+ "eliminate": 19655,
+ "eliminated": 29075,
+ "eliminating": 36619,
+ "elimination": 24176,
+ "elin": 25353,
+ "elin": 13458,
+ "eline": 46199,
+ "eline": 7153,
+ "eling": 9990,
+ "elio": 47943,
+ "elion": 30682,
+ "elions": 44159,
+ "eliot": 33326,
+ "elis": 23411,
+ "elis": 48021,
+ "elisa": 25610,
+ "elisa": 44051,
+ "elisabeth": 33127,
+ "elise": 27124,
+ "elit": 40882,
+ "elite": 32277,
+ "elite": 6553,
+ "elited": 43943,
+ "elitedangerous": 47138,
+ "elites": 35975,
+ "elius": 35623,
+ "elive": 49338,
+ "elive": 23505,
+ "elives": 49174,
+ "elix": 32926,
+ "elixir": 42887,
+ "eliz": 42844,
+ "eliza": 6132,
+ "eliza": 29992,
+ "elizabeth": 22397,
+ "elizabeth": 7026,
+ "elk": 34013,
+ "elk": 21896,
+ "ell": 826,
+ "ell": 812,
+ "ella": 20692,
+ "ella": 2957,
+ "elland": 43326,
+ "ellar": 38443,
+ "ellas": 37053,
+ "elle": 12818,
+ "elle": 4765,
+ "elled": 13146,
+ "ellen": 14007,
+ "ellen": 12312,
+ "ellenshow": 34812,
+ "eller": 20927,
+ "eller": 4465,
+ "ellers": 19010,
+ "elles": 24431,
+ "elli": 3367,
+ "elli": 6673,
+ "ellic": 38905,
+ "ellie": 16769,
+ "ellier": 44054,
+ "ellin": 40374,
+ "elling": 2220,
+ "ellington": 34477,
+ "ellini": 43256,
+ "elliot": 20761,
+ "elliott": 44456,
+ "elliott": 13788,
+ "ellip": 44816,
+ "ellis": 11553,
+ "ellison": 32295,
+ "ello": 2512,
+ "ellor": 14594,
+ "ells": 2433,
+ "ellu": 35560,
+ "elly": 8041,
+ "elly": 20355,
+ "elm": 25199,
+ "elm": 22082,
+ "elman": 33622,
+ "elmer": 45958,
+ "elmo": 32150,
+ "elo": 6170,
+ "elo": 13490,
+ "elon": 26381,
+ "elon": 20406,
+ "elondon": 47377,
+ "elong": 44363,
+ "elonmusk": 37076,
+ "elope": 23367,
+ "eloqu": 37795,
+ "elos": 44733,
+ "elot": 43490,
+ "elove": 43319,
+ "elove": 19165,
+ "elover": 21732,
+ "elovers": 33946,
+ "els": 35958,
+ "els": 1645,
+ "elsa": 22050,
+ "else": 18857,
+ "else": 3344,
+ "elsewhere": 22906,
+ "elson": 19624,
+ "elt": 18692,
+ "elton": 20758,
+ "elu": 14208,
+ "elusive": 28903,
+ "elves": 29111,
+ "elvi": 47008,
+ "elvis": 47359,
+ "elvis": 14498,
+ "elxn": 37726,
+ "ely": 12189,
+ "ely": 1273,
+ "elyn": 29691,
+ "elyn": 18126,
+ "em": 908,
+ "em": 2270,
+ "ema": 7002,
+ "ema": 11131,
+ "emabiggest": 23101,
+ "emabiggestfans": 29587,
+ "email": 33537,
+ "email": 4462,
+ "emailed": 40470,
+ "emailmarketing": 40188,
+ "emails": 12871,
+ "eman": 24416,
+ "eman": 36868,
+ "emancip": 42996,
+ "emanuel": 35232,
+ "emb": 3692,
+ "embar": 8266,
+ "embaras": 48019,
+ "embark": 33953,
+ "embarra": 11382,
+ "embarrass": 27183,
+ "embarrassed": 28217,
+ "embarrassing": 19653,
+ "embarrassment": 41346,
+ "embassy": 13598,
+ "embe": 46041,
+ "embed": 19703,
+ "embedded": 22046,
+ "embelli": 32144,
+ "embellished": 46992,
+ "ember": 47049,
+ "emblem": 21163,
+ "embo": 23065,
+ "embr": 35267,
+ "embrac": 16928,
+ "embrace": 12118,
+ "embraced": 35739,
+ "embraces": 38404,
+ "embracing": 22196,
+ "embro": 12550,
+ "embroi": 18667,
+ "embroide": 21530,
+ "embroidered": 22381,
+ "embroidery": 20823,
+ "emc": 20897,
+ "emc": 31602,
+ "emcee": 42038,
+ "eme": 22910,
+ "eme": 21548,
+ "emea": 40352,
+ "emed": 11028,
+ "emen": 22033,
+ "ement": 40841,
+ "ement": 2057,
+ "ements": 11058,
+ "emer": 3132,
+ "emer": 25727,
+ "emerald": 46878,
+ "emerald": 16980,
+ "emerge": 22182,
+ "emerged": 26425,
+ "emergen": 24096,
+ "emergence": 39867,
+ "emergencies": 35759,
+ "emergency": 44038,
+ "emergency": 5897,
+ "emerges": 30801,
+ "emerging": 38174,
+ "emerging": 11113,
+ "emeritus": 35333,
+ "emerson": 24147,
+ "emery": 32678,
+ "emi": 44327,
+ "emi": 18525,
+ "emil": 26794,
+ "emil": 40624,
+ "emile": 43926,
+ "emili": 20709,
+ "emilia": 34238,
+ "emilio": 39722,
+ "emily": 14545,
+ "emily": 7640,
+ "emin": 17227,
+ "emin": 23995,
+ "eminem": 22129,
+ "eminent": 33779,
+ "eming": 40398,
+ "emir": 13337,
+ "emir": 47613,
+ "emirates": 47244,
+ "emirates": 17867,
+ "emission": 27761,
+ "emissions": 14172,
+ "emit": 49043,
+ "emma": 18177,
+ "emma": 7445,
+ "emmanuel": 48045,
+ "emmanuel": 20411,
+ "emmett": 45779,
+ "emmy": 35625,
+ "emmy": 17089,
+ "emmys": 21875,
+ "emo": 3738,
+ "emo": 19381,
+ "emoji": 16327,
+ "emojis": 27870,
+ "emon": 34406,
+ "emor": 45034,
+ "emory": 44274,
+ "emotion": 17464,
+ "emotional": 7357,
+ "emotionally": 24088,
+ "emotions": 12904,
+ "emp": 3831,
+ "emp": 41004,
+ "empathy": 22420,
+ "emper": 12522,
+ "emperor": 13828,
+ "empha": 16237,
+ "emphasi": 47176,
+ "emphasis": 29588,
+ "empire": 26212,
+ "empire": 7614,
+ "empires": 46510,
+ "emplo": 3409,
+ "employ": 37290,
+ "employ": 39626,
+ "employe": 5037,
+ "employed": 26567,
+ "employee": 36631,
+ "employee": 9560,
+ "employees": 7377,
+ "employer": 21296,
+ "employers": 17647,
+ "employment": 10959,
+ "empor": 27386,
+ "emporium": 48541,
+ "empower": 13612,
+ "empower": 17230,
+ "empowered": 29087,
+ "empowering": 20086,
+ "empowerment": 15747,
+ "empowers": 46206,
+ "empress": 26656,
+ "empty": 41203,
+ "empty": 7893,
+ "emra": 39259,
+ "ems": 2858,
+ "emt": 46360,
+ "emu": 48149,
+ "emu": 29296,
+ "emul": 23272,
+ "emy": 31076,
+ "en": 524,
+ "en": 576,
+ "ena": 3452,
+ "enab": 17308,
+ "enable": 15642,
+ "enabled": 23666,
+ "enables": 23417,
+ "enabling": 23590,
+ "enam": 41486,
+ "enamel": 22746,
+ "enary": 13132,
+ "enas": 34536,
+ "enation": 20860,
+ "enberg": 15658,
+ "enburg": 28430,
+ "enc": 33169,
+ "enca": 37774,
+ "encan": 30345,
+ "encapsul": 40874,
+ "ence": 6495,
+ "ence": 954,
+ "enced": 6549,
+ "ences": 3777,
+ "enchan": 17290,
+ "enchanted": 28258,
+ "enchanting": 32531,
+ "enchil": 47396,
+ "enci": 32207,
+ "encia": 30068,
+ "encies": 18729,
+ "encing": 10326,
+ "enclosed": 43243,
+ "enclosure": 37419,
+ "encom": 44026,
+ "encore": 20549,
+ "encoun": 17309,
+ "encounter": 13164,
+ "encountered": 32492,
+ "encounters": 25399,
+ "encoura": 6169,
+ "encourage": 12090,
+ "encouraged": 20299,
+ "encouragement": 24959,
+ "encourages": 23848,
+ "encouraging": 15875,
+ "encro": 45822,
+ "encry": 28600,
+ "encryp": 42928,
+ "encrypted": 48710,
+ "encryption": 31423,
+ "ency": 3484,
+ "encyclo": 32104,
+ "encyclopedia": 38376,
+ "end": 945,
+ "end": 806,
+ "enda": 6735,
+ "endale": 20290,
+ "endange": 13990,
+ "endangered": 14931,
+ "ende": 11373,
+ "ende": 40306,
+ "endeav": 18134,
+ "endeavor": 40502,
+ "endeavors": 44394,
+ "endeavour": 38035,
+ "ended": 2622,
+ "endemic": 41241,
+ "endent": 16265,
+ "ender": 48106,
+ "ender": 12383,
+ "enders": 7418,
+ "endez": 43850,
+ "endgame": 23042,
+ "endi": 31359,
+ "ending": 2695,
+ "endings": 36516,
+ "endish": 38841,
+ "endless": 12688,
+ "endlessly": 45145,
+ "endment": 45894,
+ "endo": 13476,
+ "endo": 15830,
+ "endocr": 36486,
+ "endof": 40786,
+ "endome": 46996,
+ "endon": 48018,
+ "endor": 8092,
+ "endorf": 37249,
+ "endorse": 28819,
+ "endorsed": 24307,
+ "endorsement": 21205,
+ "endorses": 34603,
+ "endorsing": 46779,
+ "endow": 45895,
+ "endra": 22321,
+ "ends": 1339,
+ "endthe": 46256,
+ "endu": 26032,
+ "endur": 19557,
+ "endurance": 21027,
+ "endure": 32419,
+ "enduring": 30851,
+ "enduro": 47042,
+ "ene": 3297,
+ "ene": 6049,
+ "ened": 2494,
+ "eneed": 45137,
+ "enegger": 33235,
+ "enei": 48906,
+ "enemies": 15824,
+ "enemy": 10310,
+ "enen": 45113,
+ "ener": 2244,
+ "ener": 13600,
+ "energ": 39451,
+ "energetic": 24197,
+ "energi": 23044,
+ "energies": 42374,
+ "energized": 48635,
+ "energy": 14974,
+ "energy": 2650,
+ "energye": 32271,
+ "energyefficiency": 40586,
+ "eners": 48208,
+ "enes": 42066,
+ "eness": 11806,
+ "enet": 46336,
+ "enew": 29672,
+ "enews": 13442,
+ "eney": 20706,
+ "enez": 33110,
+ "enf": 38167,
+ "enfield": 27808,
+ "enfor": 10592,
+ "enforce": 40224,
+ "enforced": 44597,
+ "enforcement": 12460,
+ "eng": 1035,
+ "eng": 6730,
+ "enga": 22297,
+ "engag": 6793,
+ "engage": 11089,
+ "engaged": 11475,
+ "engagement": 7281,
+ "engaging": 13060,
+ "enge": 26279,
+ "enge": 2742,
+ "engel": 38265,
+ "engen": 48286,
+ "enger": 6618,
+ "engers": 7533,
+ "engine": 3355,
+ "engine": 5857,
+ "engineer": 40151,
+ "engineer": 8517,
+ "engineered": 26580,
+ "engineering": 5273,
+ "engineers": 11494,
+ "engines": 14487,
+ "england": 20904,
+ "england": 3595,
+ "english": 15942,
+ "english": 3469,
+ "engra": 17560,
+ "engraved": 29421,
+ "engraving": 33309,
+ "engul": 43655,
+ "engv": 28401,
+ "enh": 7449,
+ "enhall": 48781,
+ "enham": 24592,
+ "enhan": 26827,
+ "enhance": 13993,
+ "enhanced": 16070,
+ "enhancement": 35601,
+ "enhances": 38259,
+ "enhancing": 25986,
+ "eni": 4395,
+ "eni": 17538,
+ "enic": 46780,
+ "enic": 28292,
+ "enig": 19754,
+ "enig": 48730,
+ "enight": 32848,
+ "enight": 20640,
+ "enigma": 34998,
+ "ening": 1133,
+ "enium": 34380,
+ "enix": 25720,
+ "enjo": 1498,
+ "enjoy": 12981,
+ "enjoy": 2218,
+ "enjoyable": 17444,
+ "enjoyed": 5045,
+ "enjoying": 3603,
+ "enjoyment": 34905,
+ "enjoys": 17024,
+ "enka": 43942,
+ "enko": 25312,
+ "enlar": 38136,
+ "enligh": 21364,
+ "enlighten": 28200,
+ "enlightened": 44032,
+ "enlightening": 44005,
+ "enlightenment": 29255,
+ "enlisted": 43555,
+ "enly": 43023,
+ "enn": 43563,
+ "enna": 8095,
+ "enne": 21176,
+ "enne": 11518,
+ "ennedy": 46266,
+ "ennes": 43613,
+ "enni": 7049,
+ "ennial": 14220,
+ "ennis": 48923,
+ "ennis": 26309,
+ "eno": 9429,
+ "eno": 12843,
+ "enoch": 47917,
+ "enor": 13955,
+ "enormous": 20129,
+ "enos": 44759,
+ "enote": 44955,
+ "enough": 2744,
+ "enow": 26876,
+ "enqu": 28417,
+ "enqui": 22810,
+ "enquire": 46658,
+ "enquiries": 31901,
+ "enquiry": 45141,
+ "enri": 18915,
+ "enrich": 20058,
+ "enrich": 45504,
+ "enriched": 45166,
+ "enrichment": 32903,
+ "enrique": 25489,
+ "enrol": 44279,
+ "enroll": 23739,
+ "enroll": 30366,
+ "enrolled": 36853,
+ "enrollment": 24875,
+ "enroute": 40548,
+ "ens": 41799,
+ "ens": 1323,
+ "ense": 12657,
+ "ense": 27658,
+ "ensemble": 14843,
+ "ensis": 32842,
+ "ensla": 37535,
+ "enslaved": 48675,
+ "ensure": 7492,
+ "ensures": 29707,
+ "ensuring": 19403,
+ "ent": 724,
+ "ent": 621,
+ "enta": 17681,
+ "ental": 32342,
+ "ental": 6168,
+ "entary": 9833,
+ "entation": 37412,
+ "ente": 17433,
+ "ente": 9935,
+ "ented": 3800,
+ "entennial": 43088,
+ "enter": 2963,
+ "enter": 3819,
+ "entered": 10679,
+ "entering": 12580,
+ "enterpri": 7339,
+ "enterprise": 9220,
+ "enterprises": 21219,
+ "enters": 15287,
+ "entertain": 5566,
+ "entertain": 23510,
+ "entertained": 30631,
+ "entertainer": 28674,
+ "entertaining": 13897,
+ "entertainment": 6166,
+ "entes": 24213,
+ "enthr": 36202,
+ "enthusi": 9631,
+ "enthusiasm": 20525,
+ "enthusiast": 27153,
+ "enthusiastic": 22068,
+ "enthusiasts": 27514,
+ "enti": 1938,
+ "ential": 5194,
+ "entially": 37695,
+ "entic": 10340,
+ "entine": 49212,
+ "enting": 20526,
+ "entire": 4709,
+ "entirely": 13911,
+ "entirety": 43242,
+ "entit": 15209,
+ "entities": 38134,
+ "entitled": 18680,
+ "entity": 28455,
+ "ently": 2922,
+ "ento": 21917,
+ "ento": 8762,
+ "entom": 31676,
+ "entourage": 47893,
+ "entr": 7129,
+ "entrance": 9129,
+ "entrata": 27304,
+ "entre": 34188,
+ "entre": 19600,
+ "entren": 46959,
+ "entrepre": 4583,
+ "entreprene": 4789,
+ "entrepreneu": 26784,
+ "entrepreneur": 12119,
+ "entrepreneur": 8033,
+ "entrepreneurial": 28261,
+ "entrepreneurs": 11054,
+ "entrepreneurship": 12858,
+ "entries": 13766,
+ "entry": 5362,
+ "ents": 870,
+ "entu": 6650,
+ "enty": 5657,
+ "enu": 23430,
+ "env": 32280,
+ "env": 39207,
+ "envel": 20052,
+ "envelope": 27358,
+ "envir": 3512,
+ "enviro": 46200,
+ "environ": 3599,
+ "environment": 33039,
+ "environment": 5501,
+ "environmental": 7831,
+ "environmentally": 32855,
+ "environments": 19577,
+ "envision": 49031,
+ "envoy": 29263,
+ "envy": 21017,
+ "eny": 20482,
+ "enya": 36509,
+ "enyc": 39520,
+ "enz": 25805,
+ "enz": 31873,
+ "enza": 25239,
+ "enzie": 14839,
+ "enzo": 31543,
+ "enzyme": 40348,
+ "enzymes": 47465,
+ "eo": 16054,
+ "eo": 11712,
+ "eoin": 48634,
+ "eon": 31915,
+ "eos": 17805,
+ "ep": 1178,
+ "ep": 1117,
+ "epa": 15866,
+ "epage": 26931,
+ "epaper": 33584,
+ "epcot": 32524,
+ "eper": 43071,
+ "eph": 45752,
+ "eph": 41240,
+ "ephe": 25129,
+ "epi": 7219,
+ "epi": 34641,
+ "epic": 12683,
+ "epic": 4991,
+ "epiconetsy": 49222,
+ "epide": 17382,
+ "epidemi": 44447,
+ "epidemic": 21522,
+ "epile": 23150,
+ "epilepsy": 29547,
+ "epilo": 31291,
+ "epilots": 39766,
+ "epiph": 40561,
+ "epiphany": 43251,
+ "epis": 24616,
+ "episcop": 28037,
+ "episcopal": 31221,
+ "episo": 2708,
+ "episode": 2965,
+ "episodes": 11837,
+ "epit": 21967,
+ "epitome": 35114,
+ "epl": 25950,
+ "epo": 25810,
+ "epp": 39054,
+ "epp": 39593,
+ "eps": 4090,
+ "epsilon": 40019,
+ "epsom": 40364,
+ "epstein": 34688,
+ "eq": 39331,
+ "eq": 33692,
+ "equ": 2563,
+ "equal": 17373,
+ "equal": 10433,
+ "equality": 48981,
+ "equality": 9578,
+ "equally": 18172,
+ "equals": 30278,
+ "equation": 28591,
+ "equations": 38225,
+ "eque": 19518,
+ "equestrian": 24728,
+ "equi": 8752,
+ "equili": 43262,
+ "equine": 33801,
+ "equinox": 32652,
+ "equip": 6526,
+ "equip": 36979,
+ "equipment": 6893,
+ "equipo": 45688,
+ "equipped": 18331,
+ "equitable": 44717,
+ "equities": 44015,
+ "equity": 11293,
+ "equivalent": 19489,
+ "er": 517,
+ "er": 528,
+ "era": 30548,
+ "era": 2072,
+ "erable": 18801,
+ "erad": 24194,
+ "eradic": 36346,
+ "eradicate": 46164,
+ "eral": 6222,
+ "eran": 13069,
+ "eras": 19325,
+ "eras": 39090,
+ "erase": 33893,
+ "erased": 46762,
+ "erasmus": 38935,
+ "erc": 5360,
+ "erc": 32382,
+ "erd": 25645,
+ "erdo": 21112,
+ "erdogan": 24453,
+ "ere": 17907,
+ "ere": 642,
+ "erec": 21526,
+ "erected": 39365,
+ "ered": 9097,
+ "eres": 15751,
+ "ergon": 38120,
+ "ergy": 19550,
+ "eri": 2769,
+ "eri": 9509,
+ "eria": 11634,
+ "erial": 5409,
+ "eric": 1206,
+ "eric": 5396,
+ "erica": 13208,
+ "erich": 26070,
+ "erick": 27434,
+ "erick": 36959,
+ "erickson": 45286,
+ "ericsson": 39645,
+ "eridge": 45408,
+ "erie": 7005,
+ "eries": 9099,
+ "erik": 22805,
+ "erik": 16532,
+ "erika": 25531,
+ "erin": 17532,
+ "erin": 11333,
+ "erina": 25176,
+ "ering": 1785,
+ "erit": 23335,
+ "eritrea": 30738,
+ "erjee": 41665,
+ "erly": 14380,
+ "erm": 31649,
+ "erman": 17990,
+ "ern": 6992,
+ "ern": 12140,
+ "ernal": 20868,
+ "ernan": 34617,
+ "ernation": 48796,
+ "erne": 33930,
+ "ernest": 23006,
+ "ernie": 23636,
+ "ernity": 14653,
+ "erno": 40812,
+ "ernst": 30099,
+ "ero": 3211,
+ "ero": 3732,
+ "erock": 38206,
+ "eron": 32837,
+ "eroom": 46690,
+ "eros": 30597,
+ "erose": 48657,
+ "erosion": 30174,
+ "erotic": 30708,
+ "erotica": 39126,
+ "erous": 6384,
+ "eroy": 36461,
+ "erp": 28268,
+ "err": 22479,
+ "err": 25346,
+ "erra": 48446,
+ "errands": 45485,
+ "error": 12097,
+ "errors": 21195,
+ "erry": 45236,
+ "erry": 24124,
+ "ers": 4840,
+ "ers": 612,
+ "ersfc": 37925,
+ "ership": 2884,
+ "erson": 25780,
+ "erson": 6811,
+ "ert": 40325,
+ "ert": 3112,
+ "erta": 32007,
+ "erton": 26245,
+ "erts": 12921,
+ "eru": 36068,
+ "erun": 41642,
+ "erup": 17093,
+ "erupted": 48862,
+ "eruption": 33705,
+ "erville": 37557,
+ "erwin": 43724,
+ "ery": 12467,
+ "ery": 1692,
+ "erz": 38711,
+ "es": 957,
+ "es": 542,
+ "esa": 46834,
+ "esa": 12489,
+ "esanders": 23099,
+ "esc": 3330,
+ "esc": 28420,
+ "escal": 15902,
+ "escap": 11499,
+ "escape": 32484,
+ "escape": 7568,
+ "escaped": 18707,
+ "escapes": 29916,
+ "escaping": 21767,
+ "escar": 39229,
+ "escence": 37972,
+ "esch": 46760,
+ "esch": 41945,
+ "esco": 32482,
+ "escobar": 48807,
+ "escor": 24360,
+ "escort": 24976,
+ "escorted": 47667,
+ "escorts": 48574,
+ "escu": 36517,
+ "esday": 19553,
+ "ese": 18766,
+ "ese": 2260,
+ "esg": 41674,
+ "esh": 17119,
+ "esh": 13407,
+ "esha": 28799,
+ "eshop": 38451,
+ "eshop": 45570,
+ "eshopsuk": 39349,
+ "esi": 30064,
+ "esis": 12414,
+ "esk": 19359,
+ "esl": 26201,
+ "eso": 29890,
+ "eso": 28921,
+ "esof": 17047,
+ "eson": 46845,
+ "esp": 3849,
+ "esp": 13870,
+ "espa": 37301,
+ "espan": 41731,
+ "españa": 41118,
+ "especially": 4878,
+ "esper": 29216,
+ "espino": 46633,
+ "espionage": 43498,
+ "espn": 22917,
+ "espn": 7540,
+ "espnu": 47747,
+ "espo": 34381,
+ "esports": 16035,
+ "espresso": 17098,
+ "esq": 47352,
+ "esqu": 34616,
+ "esque": 25877,
+ "ess": 3118,
+ "ess": 9764,
+ "essa": 39125,
+ "essay": 12751,
+ "essays": 27328,
+ "esse": 22305,
+ "essen": 30489,
+ "essence": 17830,
+ "essenti": 11163,
+ "essential": 47264,
+ "essential": 6895,
+ "essentially": 30042,
+ "essentials": 16191,
+ "essex": 30563,
+ "essex": 11623,
+ "est": 2291,
+ "est": 1509,
+ "esta": 41449,
+ "esta": 10135,
+ "estab": 7010,
+ "establi": 8412,
+ "establish": 19709,
+ "established": 13143,
+ "establishing": 29420,
+ "establishment": 20213,
+ "estas": 39072,
+ "estate": 47130,
+ "estate": 6159,
+ "estates": 26054,
+ "este": 12968,
+ "este": 20579,
+ "esteban": 48381,
+ "esteem": 31541,
+ "esteemed": 36293,
+ "ester": 45808,
+ "esthe": 18468,
+ "esther": 24393,
+ "estim": 8904,
+ "estimate": 21883,
+ "estimated": 16665,
+ "estimates": 21957,
+ "esto": 31589,
+ "esto": 23958,
+ "estonia": 26260,
+ "estonian": 48895,
+ "estrada": 48116,
+ "estre": 31271,
+ "estu": 26272,
+ "estuary": 35269,
+ "esur": 35758,
+ "esville": 39187,
+ "esy": 46268,
+ "et": 1169,
+ "et": 875,
+ "eta": 8761,
+ "etal": 25221,
+ "etary": 13074,
+ "etc": 5353,
+ "etched": 40411,
+ "etching": 41375,
+ "ete": 38820,
+ "ete": 40245,
+ "eter": 8587,
+ "eter": 17007,
+ "eternal": 13732,
+ "eternally": 48486,
+ "eternity": 23832,
+ "eters": 18392,
+ "etf": 31661,
+ "eth": 4819,
+ "eth": 5927,
+ "ethan": 24245,
+ "ethan": 15958,
+ "ethanol": 38166,
+ "ethe": 21312,
+ "ethel": 45921,
+ "ether": 23349,
+ "ethere": 18705,
+ "ethereal": 40925,
+ "ethereum": 19612,
+ "ethernet": 35026,
+ "ethi": 10327,
+ "ethic": 39104,
+ "ethical": 47041,
+ "ethical": 17679,
+ "ethics": 13355,
+ "ethiop": 10897,
+ "ethiopia": 13920,
+ "ethiopian": 24507,
+ "ethnic": 30522,
+ "ethnic": 16344,
+ "ethnicity": 46787,
+ "ethno": 34225,
+ "ethos": 48768,
+ "eti": 11188,
+ "eti": 30394,
+ "etienne": 46118,
+ "eties": 15137,
+ "etihad": 38489,
+ "etiquette": 37957,
+ "etis": 38216,
+ "etisation": 39733,
+ "etna": 41940,
+ "eto": 27829,
+ "eto": 33837,
+ "eton": 44339,
+ "etour": 41462,
+ "etr": 23012,
+ "etres": 42838,
+ "ets": 3442,
+ "etsy": 13237,
+ "etsy": 6282,
+ "etsym": 22902,
+ "etsymntt": 25416,
+ "etsyshop": 44643,
+ "ett": 32729,
+ "ett": 24998,
+ "etta": 30466,
+ "ette": 19981,
+ "ette": 5212,
+ "ettes": 35326,
+ "etto": 44219,
+ "etty": 40759,
+ "etu": 36593,
+ "etv": 49155,
+ "etv": 20325,
+ "etwork": 20585,
+ "ety": 25920,
+ "ety": 2746,
+ "etz": 36181,
+ "etz": 25301,
+ "eu": 1506,
+ "eu": 3238,
+ "eucalyp": 41068,
+ "eucalyptus": 42351,
+ "euchar": 38362,
+ "eugen": 30678,
+ "eugene": 17760,
+ "eul": 46749,
+ "eun": 16431,
+ "eun": 26219,
+ "eunhyuk": 47526,
+ "eup": 44435,
+ "euph": 21386,
+ "euphoria": 41051,
+ "eur": 18343,
+ "eur": 12018,
+ "eura": 32605,
+ "eure": 25311,
+ "euref": 48017,
+ "eureka": 31686,
+ "euro": 2039,
+ "euro": 8463,
+ "euroleague": 46821,
+ "europa": 18290,
+ "europale": 42473,
+ "europaleague": 44029,
+ "europarl": 44922,
+ "europe": 4198,
+ "europe": 3848,
+ "european": 26712,
+ "european": 4759,
+ "europeans": 37082,
+ "euros": 22274,
+ "eurovision": 17593,
+ "eurozone": 42555,
+ "eurusd": 40895,
+ "eus": 44214,
+ "euston": 46905,
+ "euthan": 43280,
+ "euve": 40652,
+ "eux": 25019,
+ "ev": 776,
+ "ev": 10133,
+ "eva": 6845,
+ "evacu": 13187,
+ "evacuated": 26806,
+ "evacuation": 27353,
+ "eval": 25139,
+ "eval": 9703,
+ "evalu": 10314,
+ "evaluate": 27174,
+ "evaluating": 34541,
+ "evaluation": 17640,
+ "evan": 12821,
+ "evan": 12847,
+ "evangel": 20518,
+ "evangeli": 21372,
+ "evangelical": 36151,
+ "evangelist": 42275,
+ "evankirstel": 46581,
+ "evans": 8836,
+ "evansville": 44782,
+ "evapor": 33352,
+ "evasion": 48795,
+ "eve": 5732,
+ "eve": 1866,
+ "eved": 19820,
+ "evel": 39315,
+ "evelyn": 26687,
+ "evement": 8210,
+ "even": 6359,
+ "even": 1427,
+ "evening": 34487,
+ "evening": 2285,
+ "evenings": 19994,
+ "evenly": 45974,
+ "event": 10612,
+ "event": 1655,
+ "eventful": 45628,
+ "evento": 38155,
+ "eventprofs": 24980,
+ "events": 3667,
+ "eventu": 14055,
+ "eventual": 45321,
+ "eventually": 14397,
+ "ever": 888,
+ "ever": 1247,
+ "everest": 21722,
+ "everett": 25456,
+ "everglades": 46294,
+ "evergreen": 23852,
+ "everlasting": 32849,
+ "evers": 31914,
+ "everton": 13315,
+ "every": 1091,
+ "every": 1505,
+ "everybody": 5901,
+ "everyday": 25049,
+ "everyday": 5160,
+ "everyone": 1584,
+ "everything": 36376,
+ "everything": 2410,
+ "everytime": 16911,
+ "everywhere": 6364,
+ "eves": 7323,
+ "evi": 5348,
+ "evi": 36989,
+ "evic": 21336,
+ "eviction": 37111,
+ "eviden": 46220,
+ "evidence": 6439,
+ "evident": 34529,
+ "evie": 47195,
+ "evil": 23218,
+ "evil": 6006,
+ "eville": 16143,
+ "eving": 24729,
+ "evo": 17962,
+ "evo": 13169,
+ "evoc": 43133,
+ "evol": 5350,
+ "evolu": 7725,
+ "evolution": 8902,
+ "evolutionary": 30629,
+ "evolve": 23406,
+ "evolved": 22613,
+ "evolving": 23675,
+ "evp": 46154,
+ "evs": 33576,
+ "ew": 11942,
+ "ew": 15428,
+ "ewan": 40247,
+ "ewe": 48438,
+ "ewing": 38873,
+ "ews": 9878,
+ "ex": 659,
+ "ex": 4118,
+ "exac": 5460,
+ "exact": 12651,
+ "exactly": 5840,
+ "exagger": 29766,
+ "exal": 49324,
+ "exam": 4428,
+ "exam": 8785,
+ "examination": 20970,
+ "examine": 25728,
+ "examined": 44004,
+ "examiner": 29149,
+ "examines": 28160,
+ "examining": 30616,
+ "example": 6228,
+ "examples": 14790,
+ "exams": 14028,
+ "exas": 47536,
+ "exc": 1302,
+ "excav": 20733,
+ "excavation": 45909,
+ "exce": 10999,
+ "exceed": 32521,
+ "exceeded": 36221,
+ "exceeding": 47213,
+ "exceeds": 49353,
+ "excel": 28351,
+ "excel": 18754,
+ "excell": 3298,
+ "excellence": 8171,
+ "excellency": 36503,
+ "excellent": 4239,
+ "excelsi": 47315,
+ "excep": 8882,
+ "except": 8541,
+ "exception": 25018,
+ "exceptional": 13425,
+ "exceptionally": 29306,
+ "excer": 17737,
+ "excerpt": 20586,
+ "excess": 22491,
+ "excessive": 21332,
+ "exchange": 6616,
+ "exchanged": 48919,
+ "exchanges": 29730,
+ "exchanging": 47760,
+ "excit": 10510,
+ "excite": 47711,
+ "excited": 1889,
+ "excitement": 11407,
+ "exciting": 4300,
+ "exclu": 3114,
+ "exclude": 49235,
+ "excluded": 46216,
+ "excluding": 44326,
+ "exclusion": 40219,
+ "exclusive": 3747,
+ "exclusively": 13565,
+ "exclusives": 47149,
+ "excu": 7324,
+ "excur": 27533,
+ "excursion": 34869,
+ "excuse": 9266,
+ "excuses": 19388,
+ "exe": 3554,
+ "exe": 48027,
+ "exec": 15052,
+ "execs": 35728,
+ "execu": 4360,
+ "execute": 36405,
+ "executed": 20432,
+ "execution": 18085,
+ "executive": 5944,
+ "executives": 24357,
+ "exem": 19753,
+ "exemp": 28602,
+ "exempl": 36371,
+ "exemplary": 39123,
+ "exempli": 41934,
+ "exempt": 44278,
+ "exemption": 47481,
+ "exer": 40295,
+ "exerc": 5932,
+ "exercise": 7016,
+ "exercises": 19669,
+ "exercising": 39036,
+ "exeter": 32137,
+ "exeter": 18837,
+ "exfoli": 38823,
+ "exhau": 11154,
+ "exhaust": 21812,
+ "exhausted": 21741,
+ "exhausting": 40035,
+ "exhaustion": 49221,
+ "exhi": 3022,
+ "exhib": 3783,
+ "exhibit": 24992,
+ "exhibit": 8209,
+ "exhibiting": 23889,
+ "exhibition": 4219,
+ "exhibitions": 28311,
+ "exhibitor": 44192,
+ "exhibitors": 38542,
+ "exhibits": 30093,
+ "exhilar": 40262,
+ "exhilarating": 49289,
+ "exi": 5297,
+ "exico": 38712,
+ "exile": 28566,
+ "exist": 10899,
+ "exist": 9645,
+ "existed": 23198,
+ "existence": 13832,
+ "existent": 43541,
+ "existential": 38752,
+ "existing": 12886,
+ "exists": 14608,
+ "exit": 9374,
+ "exited": 37581,
+ "exiting": 39577,
+ "exits": 34943,
+ "exmoor": 48260,
+ "exo": 15600,
+ "exo": 5842,
+ "exodus": 30098,
+ "exol": 42856,
+ "exop": 35288,
+ "exoplan": 37980,
+ "exor": 24506,
+ "exorcist": 46309,
+ "exotic": 15639,
+ "exp": 9923,
+ "exp": 19066,
+ "expan": 7512,
+ "expand": 10382,
+ "expand": 13141,
+ "expanded": 18390,
+ "expanding": 15755,
+ "expands": 22223,
+ "expanse": 46886,
+ "expansion": 10138,
+ "expansive": 49261,
+ "expat": 43900,
+ "expe": 2560,
+ "expect": 9802,
+ "expect": 5716,
+ "expectation": 34273,
+ "expectations": 12529,
+ "expected": 5573,
+ "expecting": 12525,
+ "expects": 24536,
+ "expedition": 16761,
+ "expeditions": 49327,
+ "expelled": 48834,
+ "expen": 7216,
+ "expend": 29302,
+ "expenditure": 47044,
+ "expense": 28473,
+ "expenses": 21797,
+ "expensive": 9649,
+ "exper": 1533,
+ "experi": 4723,
+ "experience": 31867,
+ "experience": 2415,
+ "experienced": 10417,
+ "experiences": 8233,
+ "experiencing": 16643,
+ "experiential": 44952,
+ "experim": 6697,
+ "experiment": 13079,
+ "experimental": 16539,
+ "experimenting": 28263,
+ "experiments": 21077,
+ "expert": 6284,
+ "expertise": 16555,
+ "experts": 6960,
+ "expi": 26850,
+ "expir": 35077,
+ "expire": 49315,
+ "expired": 30200,
+ "expires": 34739,
+ "expl": 3261,
+ "expla": 3517,
+ "explain": 48918,
+ "explain": 7304,
+ "explained": 14229,
+ "explaining": 13136,
+ "explains": 6655,
+ "explan": 13294,
+ "explanation": 16577,
+ "explanations": 34383,
+ "explic": 21011,
+ "explicit": 33228,
+ "explo": 3586,
+ "explode": 31262,
+ "exploded": 28947,
+ "explodes": 38119,
+ "exploding": 34683,
+ "exploit": 36953,
+ "exploited": 48554,
+ "explor": 11958,
+ "exploration": 14043,
+ "explore": 10405,
+ "explore": 5147,
+ "explorebc": 38754,
+ "explorecanada": 36600,
+ "explored": 25016,
+ "explorer": 15776,
+ "explorers": 28491,
+ "explores": 13996,
+ "exploring": 7584,
+ "explosion": 13785,
+ "explosions": 38646,
+ "explosive": 18888,
+ "explosives": 44705,
+ "expo": 7820,
+ "expo": 6344,
+ "expon": 27905,
+ "export": 14444,
+ "exporting": 47433,
+ "exports": 20088,
+ "expose": 23181,
+ "exposed": 12180,
+ "exposes": 33575,
+ "exposing": 28362,
+ "exposition": 36943,
+ "exposure": 11903,
+ "expre": 6085,
+ "express": 18553,
+ "express": 5642,
+ "expressed": 20777,
+ "expresses": 31931,
+ "expressing": 30207,
+ "expression": 11357,
+ "expressions": 20314,
+ "expressive": 42060,
+ "expressway": 31658,
+ "exquis": 16575,
+ "exquisite": 17958,
+ "ext": 5711,
+ "ext": 20072,
+ "exten": 5555,
+ "extend": 14492,
+ "extended": 9614,
+ "extending": 25652,
+ "extends": 20688,
+ "extension": 10275,
+ "extensions": 24525,
+ "extensive": 16870,
+ "extensively": 47365,
+ "extent": 24913,
+ "exter": 9797,
+ "exterior": 19352,
+ "extermin": 41671,
+ "external": 15028,
+ "extin": 13553,
+ "extinct": 24488,
+ "extinction": 21186,
+ "extingui": 38567,
+ "extor": 35620,
+ "extr": 29082,
+ "extra": 6416,
+ "extra": 4231,
+ "extrac": 18550,
+ "extract": 18962,
+ "extraction": 28789,
+ "extracts": 45576,
+ "extraordin": 23628,
+ "extraordinaire": 30909,
+ "extraordinary": 10982,
+ "extras": 29817,
+ "extravag": 22299,
+ "extravaganza": 29461,
+ "extre": 3978,
+ "extreme": 38357,
+ "extreme": 8331,
+ "extremely": 6519,
+ "extremism": 31493,
+ "extremist": 36383,
+ "extremists": 41425,
+ "extru": 43010,
+ "ey": 1541,
+ "ey": 1477,
+ "eyang": 28915,
+ "eye": 5034,
+ "eye": 3272,
+ "eyebrow": 34250,
+ "eyebrows": 19923,
+ "eyed": 15512,
+ "eyeing": 34916,
+ "eyel": 17075,
+ "eyelashes": 42074,
+ "eyeliner": 33354,
+ "eyeon": 25126,
+ "eyes": 3095,
+ "eyeshadow": 35213,
+ "eyewear": 30165,
+ "eyewitness": 36258,
+ "eyou": 31996,
+ "eyour": 40229,
+ "eyre": 44115,
+ "ez": 10082,
+ "ez": 8387,
+ "eze": 25993,
+ "eze": 27229,
+ "ezekiel": 41428,
+ "ezra": 27552,
+ "f": 69,
+ "f": 325,
+ "fa": 778,
+ "fa": 2800,
+ "faa": 27577,
+ "fab": 2833,
+ "fab": 5492,
+ "faber": 43461,
+ "faber": 42488,
+ "fabi": 29425,
+ "fabian": 34539,
+ "fabio": 31666,
+ "fabric": 16217,
+ "fabric": 10033,
+ "fabricated": 40851,
+ "fabrication": 33476,
+ "fabrics": 23159,
+ "fabulous": 5189,
+ "fac": 1053,
+ "fac": 35438,
+ "facade": 29217,
+ "face": 2545,
+ "face": 1710,
+ "facebook": 36156,
+ "facebook": 2943,
+ "faced": 10941,
+ "faceli": 32023,
+ "facelift": 36380,
+ "faceoff": 42710,
+ "facep": 45285,
+ "faces": 4905,
+ "faceted": 43435,
+ "facetime": 24076,
+ "facial": 11909,
+ "facil": 39973,
+ "facilit": 13567,
+ "facilitate": 26733,
+ "facilitated": 43853,
+ "facilitating": 34796,
+ "facilities": 10388,
+ "facility": 8165,
+ "facing": 7619,
+ "fact": 17189,
+ "fact": 3598,
+ "factfriday": 27953,
+ "faction": 14629,
+ "factor": 21082,
+ "factor": 8124,
+ "factories": 36492,
+ "factors": 12733,
+ "factory": 42483,
+ "factory": 6072,
+ "facts": 5085,
+ "factual": 45471,
+ "faculty": 9504,
+ "facup": 25283,
+ "fad": 12632,
+ "fad": 47669,
+ "fade": 20486,
+ "faded": 26051,
+ "fades": 40441,
+ "fading": 32882,
+ "fadnavis": 38945,
+ "faf": 31052,
+ "faf": 43903,
+ "fag": 25617,
+ "fag": 39305,
+ "fah": 25495,
+ "fah": 35429,
+ "fahren": 45527,
+ "fai": 20519,
+ "fai": 26384,
+ "fail": 7105,
+ "fail": 6801,
+ "failed": 8314,
+ "failing": 15757,
+ "fails": 13388,
+ "failure": 8732,
+ "failures": 25442,
+ "faint": 30807,
+ "fair": 3031,
+ "fair": 2849,
+ "fairbanks": 43962,
+ "faire": 34745,
+ "faire": 20798,
+ "fairfax": 29368,
+ "fairfield": 29664,
+ "fairgrounds": 38325,
+ "fairi": 28884,
+ "fairies": 33590,
+ "fairly": 14961,
+ "fairmont": 41547,
+ "fairness": 29388,
+ "fairs": 8655,
+ "fairtrade": 33361,
+ "fairview": 43479,
+ "fairway": 44022,
+ "fairy": 17021,
+ "fairy": 10444,
+ "fairytale": 28944,
+ "fais": 23542,
+ "faisal": 35459,
+ "fait": 20567,
+ "faith": 10653,
+ "faith": 5080,
+ "faithful": 15511,
+ "faiz": 41775,
+ "fake": 18794,
+ "fake": 5777,
+ "faken": 22853,
+ "fakenews": 26943,
+ "fakespeare": 49095,
+ "fal": 2778,
+ "fal": 40494,
+ "fala": 47120,
+ "falcon": 22498,
+ "falcon": 13571,
+ "falcons": 13834,
+ "falk": 34648,
+ "falkirk": 44080,
+ "fall": 6489,
+ "fall": 2359,
+ "fallen": 8688,
+ "falling": 48709,
+ "falling": 7293,
+ "fallon": 39596,
+ "fallon": 21281,
+ "fallontonight": 44627,
+ "fallout": 49365,
+ "fallout": 16009,
+ "falls": 4778,
+ "falmouth": 38261,
+ "false": 38948,
+ "false": 9078,
+ "falsely": 42321,
+ "fam": 1058,
+ "fam": 5128,
+ "fame": 6573,
+ "famed": 23302,
+ "famer": 24554,
+ "famil": 3395,
+ "famili": 8488,
+ "familia": 25622,
+ "familiar": 10020,
+ "families": 4612,
+ "family": 8137,
+ "family": 1315,
+ "familyfun": 46308,
+ "familytime": 47236,
+ "familytravel": 38222,
+ "famine": 35847,
+ "famous": 44811,
+ "famous": 4096,
+ "famously": 44505,
+ "fan": 1675,
+ "fan": 2261,
+ "fanart": 41059,
+ "fanart": 7855,
+ "fanartfriday": 45346,
+ "fanatic": 36643,
+ "fanatics": 39610,
+ "fanbase": 36921,
+ "fanboy": 43369,
+ "fanc": 29017,
+ "fancafe": 45080,
+ "fanci": 35908,
+ "fanclub": 31530,
+ "fancy": 47622,
+ "fancy": 6733,
+ "fand": 19684,
+ "fandom": 47634,
+ "fandom": 11534,
+ "fanfest": 42916,
+ "fanfic": 47243,
+ "fang": 14269,
+ "fang": 27428,
+ "fangirl": 28813,
+ "fangirling": 39463,
+ "fanning": 37282,
+ "fanny": 30401,
+ "fans": 32454,
+ "fans": 1840,
+ "fansign": 25288,
+ "fant": 4467,
+ "fanta": 2703,
+ "fantaken": 39412,
+ "fantasia": 49306,
+ "fantastic": 31289,
+ "fantastic": 2935,
+ "fantasy": 15124,
+ "fantasy": 5267,
+ "fantasyfootball": 35713,
+ "fao": 31155,
+ "faq": 28533,
+ "far": 1578,
+ "far": 2384,
+ "fara": 48562,
+ "farage": 28340,
+ "farah": 31547,
+ "fare": 8620,
+ "fare": 6461,
+ "fares": 27525,
+ "farewell": 10734,
+ "fargo": 18870,
+ "fari": 26197,
+ "farley": 43761,
+ "farm": 9066,
+ "farm": 3985,
+ "farmer": 19735,
+ "farmer": 10474,
+ "farmers": 29752,
+ "farmers": 6402,
+ "farmersmarket": 41808,
+ "farmhouse": 26293,
+ "farming": 10399,
+ "farmington": 49305,
+ "farmland": 45258,
+ "farms": 11277,
+ "farn": 27527,
+ "faroo": 39147,
+ "farra": 33657,
+ "farrakhan": 46293,
+ "farrell": 24234,
+ "fart": 34664,
+ "farther": 42233,
+ "fas": 4830,
+ "fas": 42995,
+ "fasci": 17191,
+ "fascin": 7327,
+ "fascinated": 32964,
+ "fascinating": 8640,
+ "fascism": 28213,
+ "fascist": 23870,
+ "fascists": 43598,
+ "fash": 42682,
+ "fashi": 2099,
+ "fashion": 6976,
+ "fashion": 2444,
+ "fashionable": 24597,
+ "fashionblogger": 31726,
+ "fashioned": 21563,
+ "fashioni": 26062,
+ "fashionista": 30415,
+ "fashions": 37601,
+ "fashionshow": 45653,
+ "fashionweek": 28684,
+ "fass": 42398,
+ "fast": 8509,
+ "fast": 1953,
+ "fasten": 44990,
+ "faster": 8835,
+ "fastest": 9808,
+ "fasting": 24656,
+ "fat": 4751,
+ "fat": 5484,
+ "fatal": 12124,
+ "fatalities": 44168,
+ "fatally": 34069,
+ "fate": 26315,
+ "fate": 11734,
+ "father": 11607,
+ "father": 3224,
+ "fathers": 12780,
+ "fathersday": 16731,
+ "fati": 13430,
+ "fatigue": 23747,
+ "fatima": 28202,
+ "fats": 30151,
+ "fatt": 44131,
+ "fatty": 22953,
+ "fau": 5571,
+ "fau": 31381,
+ "faucet": 44273,
+ "faul": 16230,
+ "faulkner": 37840,
+ "fault": 13862,
+ "faults": 42752,
+ "faulty": 47103,
+ "fauna": 30808,
+ "faust": 44772,
+ "faux": 19429,
+ "fav": 1355,
+ "fav": 5426,
+ "fave": 7272,
+ "faves": 18003,
+ "favor": 1766,
+ "favor": 12160,
+ "favorable": 35392,
+ "favored": 46640,
+ "favorite": 35262,
+ "favorite": 1916,
+ "favorited": 36926,
+ "favorites": 10564,
+ "favors": 36085,
+ "favour": 3111,
+ "favour": 20469,
+ "favourite": 3342,
+ "favourites": 16585,
+ "favs": 18879,
+ "faw": 21800,
+ "fawad": 46425,
+ "fawn": 48624,
+ "fax": 32535,
+ "fax": 9337,
+ "fay": 8939,
+ "fay": 40074,
+ "faye": 30257,
+ "fayette": 32043,
+ "fayette": 19782,
+ "fayetteville": 37771,
+ "fayre": 34982,
+ "faz": 26238,
+ "faze": 44880,
+ "fb": 22637,
+ "fb": 3307,
+ "fball": 29663,
+ "fbf": 20004,
+ "fbi": 10293,
+ "fbloggers": 41389,
+ "fbs": 48454,
+ "fc": 4278,
+ "fc": 1399,
+ "fca": 24540,
+ "fcb": 26639,
+ "fcb": 25045,
+ "fcbarcelona": 32174,
+ "fcbayern": 35033,
+ "fcblive": 44608,
+ "fcc": 21240,
+ "fck": 40080,
+ "fck": 49263,
+ "fcofficial": 27805,
+ "fcs": 32095,
+ "fcu": 47898,
+ "fd": 16972,
+ "fd": 11525,
+ "fda": 17823,
+ "fdi": 45579,
+ "fdn": 18563,
+ "fdny": 41084,
+ "fdr": 42298,
+ "fe": 623,
+ "fe": 873,
+ "fear": 8744,
+ "fear": 5402,
+ "feared": 31154,
+ "fearless": 17470,
+ "fears": 13867,
+ "fearthe": 33449,
+ "feasi": 34977,
+ "feast": 37963,
+ "feast": 9564,
+ "feat": 1703,
+ "feat": 5611,
+ "feather": 24905,
+ "feather": 17871,
+ "feathers": 21138,
+ "featherweight": 44939,
+ "feature": 30413,
+ "feature": 4527,
+ "featured": 4743,
+ "features": 4643,
+ "featuring": 3706,
+ "feb": 4317,
+ "febru": 4202,
+ "february": 4248,
+ "fect": 31293,
+ "fed": 22518,
+ "fed": 7035,
+ "feder": 4737,
+ "federal": 6369,
+ "federation": 15530,
+ "federer": 18246,
+ "federico": 40539,
+ "fedex": 32603,
+ "fedora": 45111,
+ "feds": 30593,
+ "fee": 28242,
+ "fee": 9224,
+ "feed": 6662,
+ "feed": 5839,
+ "feedback": 8683,
+ "feeder": 24482,
+ "feeders": 44523,
+ "feeding": 9879,
+ "feeds": 21788,
+ "feel": 2408,
+ "feel": 2051,
+ "feelin": 19903,
+ "feeling": 33087,
+ "feeling": 3045,
+ "feelings": 9452,
+ "feels": 4808,
+ "feelthe": 22322,
+ "feelthebern": 27743,
+ "fees": 11765,
+ "feet": 4804,
+ "fei": 23441,
+ "fei": 34217,
+ "fein": 46707,
+ "feinstein": 41313,
+ "fel": 2081,
+ "fel": 20304,
+ "feld": 45913,
+ "feld": 14219,
+ "feldman": 41942,
+ "feli": 7498,
+ "felic": 25845,
+ "felici": 23379,
+ "felicia": 41139,
+ "felicidades": 41648,
+ "felicity": 35123,
+ "feline": 29471,
+ "felipe": 27681,
+ "felix": 33455,
+ "felix": 16514,
+ "feliz": 26104,
+ "feliz": 20221,
+ "fell": 33540,
+ "fell": 6266,
+ "fella": 17586,
+ "fellas": 18787,
+ "feller": 29226,
+ "fellow": 12099,
+ "fellow": 5242,
+ "fellows": 15766,
+ "fellowship": 13857,
+ "felony": 31068,
+ "felt": 5413,
+ "fem": 24574,
+ "fem": 36615,
+ "fema": 41721,
+ "female": 22062,
+ "female": 3970,
+ "females": 21028,
+ "femi": 38607,
+ "femin": 11423,
+ "femini": 11894,
+ "feminine": 24911,
+ "feminism": 18784,
+ "feminist": 14921,
+ "feminists": 38809,
+ "femme": 31331,
+ "fen": 5509,
+ "fen": 25024,
+ "fence": 12679,
+ "fences": 34312,
+ "fencing": 23489,
+ "fender": 17117,
+ "fener": 41208,
+ "fenerbah": 46652,
+ "feng": 33291,
+ "fennel": 28689,
+ "fent": 26395,
+ "fenton": 47265,
+ "fenway": 29206,
+ "fer": 1765,
+ "fer": 2897,
+ "fera": 37705,
+ "feral": 29972,
+ "ferdin": 25541,
+ "ferdinand": 27591,
+ "fere": 43144,
+ "feren": 35652,
+ "ference": 19984,
+ "ferg": 44938,
+ "fergie": 39119,
+ "fergu": 10988,
+ "fergus": 42041,
+ "ferguson": 11904,
+ "fermentation": 45817,
+ "fermented": 36886,
+ "fern": 10747,
+ "fern": 21685,
+ "fernandes": 44391,
+ "fernandez": 23436,
+ "fernando": 17140,
+ "ferns": 38277,
+ "feroci": 45652,
+ "ferr": 7256,
+ "ferra": 47911,
+ "ferrari": 9606,
+ "ferre": 29626,
+ "ferred": 10432,
+ "ferreira": 48686,
+ "ferrell": 41112,
+ "ferrer": 38904,
+ "ferri": 42008,
+ "ferries": 28489,
+ "ferris": 27532,
+ "ferry": 38936,
+ "ferry": 10278,
+ "fers": 12378,
+ "fert": 14925,
+ "fert": 43662,
+ "fertil": 41987,
+ "fertile": 44837,
+ "fertili": 23912,
+ "fertility": 23528,
+ "fertilizer": 36786,
+ "fery": 47448,
+ "fes": 32300,
+ "fest": 17383,
+ "fest": 2590,
+ "festa": 42124,
+ "festi": 1943,
+ "festiv": 19222,
+ "festival": 20946,
+ "festival": 2240,
+ "festivals": 17834,
+ "festive": 9533,
+ "festivities": 21020,
+ "fet": 21409,
+ "feta": 31705,
+ "fetal": 42031,
+ "fetch": 30271,
+ "fete": 34629,
+ "fett": 37979,
+ "fetus": 26768,
+ "feu": 24912,
+ "feu": 32990,
+ "feud": 27365,
+ "fever": 40896,
+ "fever": 9989,
+ "fevre": 43861,
+ "few": 1939,
+ "fewer": 19128,
+ "fex": 41584,
+ "fex": 26392,
+ "fey": 39069,
+ "fey": 23298,
+ "fez": 43081,
+ "ff": 1021,
+ "ff": 1304,
+ "ffa": 15355,
+ "ffame": 42873,
+ "ffc": 19832,
+ "ffe": 1138,
+ "ffe": 8631,
+ "ffect": 29151,
+ "ffed": 8448,
+ "ffee": 26377,
+ "ffel": 22656,
+ "ffen": 46537,
+ "ffer": 27369,
+ "ffer": 11636,
+ "ffers": 32163,
+ "fferty": 44771,
+ "ffes": 46441,
+ "ffey": 30138,
+ "fff": 28106,
+ "ffi": 19961,
+ "ffic": 4762,
+ "ffice": 26044,
+ "ffici": 3639,
+ "fficial": 39818,
+ "fficial": 6463,
+ "fficiency": 27800,
+ "fficient": 20424,
+ "ffin": 12779,
+ "ffin": 7367,
+ "ffing": 16592,
+ "ffins": 17898,
+ "ffl": 39490,
+ "ffle": 7749,
+ "ffler": 39819,
+ "ffles": 19344,
+ "ffman": 15823,
+ "ffo": 42264,
+ "ffs": 4424,
+ "ffxiv": 26569,
+ "ffxv": 46786,
+ "ffy": 26404,
+ "ffy": 7795,
+ "fg": 45977,
+ "fg": 6823,
+ "fgm": 32178,
+ "fgo": 46113,
+ "fh": 21649,
+ "fh": 21010,
+ "fhs": 45094,
+ "fi": 701,
+ "fi": 3589,
+ "fia": 8827,
+ "fiable": 34373,
+ "fianc": 27752,
+ "fiance": 44114,
+ "fiancé": 34039,
+ "fiasco": 40944,
+ "fiat": 16740,
+ "fiawec": 39485,
+ "fib": 40594,
+ "fiba": 34993,
+ "fiber": 35074,
+ "fiber": 12612,
+ "fibers": 44587,
+ "fibre": 21401,
+ "fibro": 21294,
+ "fibrosis": 36307,
+ "fic": 1788,
+ "fic": 2059,
+ "fica": 26952,
+ "fically": 14854,
+ "fication": 4523,
+ "fications": 12512,
+ "ficial": 48192,
+ "fics": 42505,
+ "fiction": 6218,
+ "fictional": 25570,
+ "fid": 34197,
+ "fid": 23966,
+ "fidd": 25218,
+ "fiddle": 35968,
+ "fide": 45375,
+ "fidel": 21740,
+ "fidel": 36837,
+ "fidelity": 30109,
+ "fidget": 48664,
+ "fie": 28487,
+ "fie": 10348,
+ "fied": 29642,
+ "fied": 2853,
+ "fiel": 1361,
+ "field": 7571,
+ "field": 1570,
+ "fielder": 11046,
+ "fieldhouse": 37969,
+ "fielding": 30465,
+ "fields": 6494,
+ "fieldwork": 33155,
+ "fiends": 37869,
+ "fier": 11167,
+ "fier": 10598,
+ "fierc": 48609,
+ "fierce": 13896,
+ "fiercely": 49039,
+ "fiers": 16113,
+ "fiery": 24557,
+ "fies": 9537,
+ "fiesta": 14580,
+ "fif": 5309,
+ "fifa": 21976,
+ "fifa": 8516,
+ "fifaworldcup": 38819,
+ "fifawwc": 41329,
+ "fife": 24374,
+ "fifteen": 29504,
+ "fifth": 25515,
+ "fifth": 8772,
+ "fifthharmony": 31075,
+ "fifty": 24456,
+ "fifty": 15978,
+ "fig": 4814,
+ "fig": 20719,
+ "figaro": 48044,
+ "figh": 23274,
+ "fight": 5262,
+ "fight": 2757,
+ "fighter": 35884,
+ "fighter": 6438,
+ "fighters": 7371,
+ "fightfor": 48909,
+ "fightfor": 35740,
+ "fighting": 38625,
+ "fighting": 4652,
+ "fighton": 45578,
+ "fights": 12132,
+ "figs": 38882,
+ "figu": 6390,
+ "figur": 16948,
+ "figurative": 44042,
+ "figure": 48820,
+ "figure": 5274,
+ "figured": 15630,
+ "figures": 8739,
+ "figurine": 33306,
+ "figuring": 31513,
+ "fiji": 48270,
+ "fiji": 18285,
+ "fik": 46589,
+ "fil": 1142,
+ "fil": 14915,
+ "fila": 30992,
+ "filament": 49252,
+ "file": 12545,
+ "file": 4512,
+ "filed": 13864,
+ "files": 7850,
+ "filet": 43155,
+ "fili": 9590,
+ "filing": 16576,
+ "filip": 14368,
+ "filipino": 19153,
+ "fill": 15904,
+ "fill": 6277,
+ "filled": 5589,
+ "filler": 32816,
+ "fillers": 45005,
+ "fillet": 39276,
+ "filling": 9736,
+ "fillion": 38048,
+ "fillmore": 43922,
+ "fills": 21750,
+ "filly": 27690,
+ "film": 5117,
+ "film": 1860,
+ "filmed": 15801,
+ "filmfare": 42224,
+ "filmfest": 24508,
+ "filmfestival": 28066,
+ "filming": 6866,
+ "filmmaker": 17202,
+ "filmmakers": 24896,
+ "filmmaking": 18226,
+ "films": 5370,
+ "fils": 40271,
+ "filter": 7541,
+ "filtered": 29926,
+ "filtering": 47770,
+ "filters": 18385,
+ "filth": 39713,
+ "filthy": 26899,
+ "filtr": 21408,
+ "filtration": 42036,
+ "fim": 47525,
+ "fin": 735,
+ "fin": 10663,
+ "fina": 34497,
+ "final": 11968,
+ "final": 1755,
+ "finale": 7844,
+ "finalfantasy": 44543,
+ "finalfour": 46999,
+ "finalist": 12620,
+ "finalists": 13422,
+ "finalized": 48930,
+ "finally": 1992,
+ "finals": 4536,
+ "finan": 4807,
+ "finance": 6117,
+ "finances": 28767,
+ "financi": 12846,
+ "financial": 19783,
+ "financial": 4930,
+ "financially": 28124,
+ "financing": 18375,
+ "finch": 18523,
+ "find": 18638,
+ "find": 1416,
+ "finder": 15045,
+ "finders": 43884,
+ "findia": 47064,
+ "finding": 37455,
+ "finding": 6002,
+ "findings": 16529,
+ "findlay": 48227,
+ "findom": 36463,
+ "finds": 6680,
+ "findyour": 25936,
+ "findyourpark": 38924,
+ "fine": 12042,
+ "fine": 3797,
+ "fineart": 7484,
+ "fineart": 16005,
+ "fineartamerica": 7724,
+ "fined": 20094,
+ "finely": 46120,
+ "finer": 36681,
+ "fines": 25053,
+ "finesse": 46047,
+ "finest": 7707,
+ "fing": 6485,
+ "fing": 17955,
+ "finger": 13480,
+ "finger": 8895,
+ "fingerprint": 39579,
+ "fingers": 9690,
+ "fini": 2405,
+ "finish": 42178,
+ "finish": 3958,
+ "finished": 3078,
+ "finisher": 38636,
+ "finishers": 48661,
+ "finishes": 13078,
+ "finishing": 7912,
+ "finite": 48312,
+ "finity": 41463,
+ "finity": 21273,
+ "fink": 40158,
+ "finland": 10775,
+ "finley": 41652,
+ "finn": 28479,
+ "finn": 16925,
+ "finna": 35180,
+ "finnish": 19616,
+ "fino": 30083,
+ "fins": 32810,
+ "fintech": 48929,
+ "fintech": 8899,
+ "fion": 27476,
+ "fiona": 20099,
+ "fior": 37086,
+ "fiore": 44997,
+ "fioren": 33188,
+ "fiorentina": 43713,
+ "fios": 42521,
+ "fir": 770,
+ "fir": 16233,
+ "fire": 2951,
+ "fire": 1769,
+ "firearm": 40311,
+ "firearms": 23960,
+ "fireball": 40543,
+ "firec": 42806,
+ "fired": 8846,
+ "firefighter": 20498,
+ "firefighters": 12600,
+ "firefly": 33997,
+ "firefox": 35372,
+ "fireman": 46085,
+ "firen": 34752,
+ "firenze": 38445,
+ "fireplace": 23050,
+ "fires": 8749,
+ "fireside": 36185,
+ "firework": 40750,
+ "fireworks": 10641,
+ "firing": 15105,
+ "firm": 16936,
+ "firm": 7705,
+ "firmly": 29156,
+ "firms": 13655,
+ "firmware": 42691,
+ "first": 6853,
+ "first": 874,
+ "firstdayof": 44297,
+ "firsth": 48512,
+ "firsts": 47884,
+ "firth": 26078,
+ "fis": 7846,
+ "fis": 47683,
+ "fiscal": 20825,
+ "fischer": 26532,
+ "fish": 6431,
+ "fish": 2759,
+ "fisher": 11175,
+ "fisher": 9176,
+ "fisheries": 24612,
+ "fisherman": 25055,
+ "fishermen": 28547,
+ "fishers": 42065,
+ "fishery": 49057,
+ "fishes": 35470,
+ "fishing": 31703,
+ "fishing": 4935,
+ "fishy": 35665,
+ "fist": 48340,
+ "fist": 17085,
+ "fit": 2366,
+ "fit": 2478,
+ "fitbit": 33768,
+ "fitch": 44614,
+ "fitfam": 20662,
+ "fitnes": 47285,
+ "fitness": 20044,
+ "fitness": 4838,
+ "fits": 6401,
+ "fitt": 32994,
+ "fitted": 14863,
+ "fitter": 42096,
+ "fitters": 32364,
+ "fitting": 11769,
+ "fittings": 45787,
+ "fitz": 11120,
+ "fitz": 25913,
+ "fitzgerald": 20606,
+ "fitzpatrick": 37141,
+ "fiu": 38374,
+ "five": 19508,
+ "five": 3127,
+ "fives": 44066,
+ "fix": 4596,
+ "fix": 6028,
+ "fixed": 9393,
+ "fixes": 25473,
+ "fixing": 17423,
+ "fixture": 17317,
+ "fixtures": 19904,
+ "fizz": 31242,
+ "fj": 43183,
+ "fj": 46447,
+ "fjor": 31260,
+ "fk": 12410,
+ "fl": 1082,
+ "fl": 2685,
+ "fla": 1577,
+ "fla": 20292,
+ "flag": 11536,
+ "flag": 4859,
+ "flagged": 45012,
+ "flags": 12221,
+ "flagship": 19779,
+ "flagstaff": 40406,
+ "flair": 24938,
+ "flake": 21221,
+ "flakes": 20934,
+ "flam": 10559,
+ "flame": 40351,
+ "flame": 13484,
+ "flamen": 28826,
+ "flamenco": 37362,
+ "flames": 13441,
+ "flamin": 42693,
+ "flaming": 34782,
+ "flamingo": 30323,
+ "flan": 14572,
+ "flanagan": 28641,
+ "flanders": 34837,
+ "flank": 44553,
+ "flann": 39510,
+ "flannel": 37807,
+ "flap": 35253,
+ "flappy": 40241,
+ "flare": 21185,
+ "flares": 46088,
+ "flash": 6089,
+ "flash": 5815,
+ "flashback": 14616,
+ "flashback": 11988,
+ "flashbackfriday": 15014,
+ "flashbacks": 47056,
+ "flashes": 31259,
+ "flashing": 31764,
+ "flashlight": 37256,
+ "flask": 36194,
+ "flat": 8986,
+ "flat": 6313,
+ "flats": 17228,
+ "flatt": 45498,
+ "flattering": 43267,
+ "flaun": 41421,
+ "flav": 7191,
+ "flavo": 28895,
+ "flavor": 31835,
+ "flavor": 11818,
+ "flavored": 29350,
+ "flavorful": 49135,
+ "flavors": 16930,
+ "flavour": 17026,
+ "flavoured": 42397,
+ "flavours": 21083,
+ "flaw": 14268,
+ "flaw": 34978,
+ "flawed": 35136,
+ "flawless": 15531,
+ "flaws": 30492,
+ "flax": 43443,
+ "fle": 2428,
+ "fle": 44964,
+ "flea": 24883,
+ "fleck": 28143,
+ "fled": 26731,
+ "flee": 19427,
+ "flee": 30167,
+ "fleece": 25038,
+ "fleeing": 30543,
+ "fleek": 43513,
+ "fleet": 35922,
+ "fleet": 9147,
+ "fleetwood": 28883,
+ "fleming": 25769,
+ "fler": 48789,
+ "flesh": 17495,
+ "flet": 16102,
+ "fletcher": 19810,
+ "fleur": 28593,
+ "flew": 13768,
+ "flex": 16426,
+ "flex": 12038,
+ "flexi": 10032,
+ "flexibility": 22547,
+ "flexible": 14502,
+ "flexing": 48483,
+ "fli": 2472,
+ "flick": 13746,
+ "flick": 23414,
+ "flickr": 17755,
+ "flies": 8070,
+ "flight": 24701,
+ "flight": 3795,
+ "flights": 10515,
+ "flin": 24730,
+ "flin": 43816,
+ "flinders": 44647,
+ "fling": 22768,
+ "flint": 28306,
+ "flint": 18324,
+ "flip": 20385,
+ "flip": 11035,
+ "flipk": 30829,
+ "flipkart": 33154,
+ "flipped": 28144,
+ "flipping": 25881,
+ "flips": 35089,
+ "flir": 24330,
+ "flirt": 38352,
+ "flirting": 35243,
+ "flix": 40663,
+ "flo": 1945,
+ "flo": 20711,
+ "float": 16123,
+ "floating": 12619,
+ "floats": 33272,
+ "flock": 36297,
+ "flock": 21822,
+ "flondon": 47366,
+ "floo": 4062,
+ "flood": 23793,
+ "flood": 7148,
+ "flooded": 19706,
+ "flooding": 10204,
+ "floods": 16369,
+ "floor": 23657,
+ "floor": 4125,
+ "flooring": 19227,
+ "floors": 15671,
+ "flop": 22994,
+ "floppy": 38267,
+ "flops": 29146,
+ "flor": 15784,
+ "flor": 41669,
+ "flora": 18906,
+ "floral": 10732,
+ "florals": 48331,
+ "floren": 37706,
+ "florence": 11617,
+ "flores": 21537,
+ "flori": 3482,
+ "florian": 41861,
+ "florida": 34264,
+ "florida": 3966,
+ "florist": 38403,
+ "floss": 36453,
+ "flotus": 35181,
+ "flour": 18592,
+ "flouri": 23239,
+ "flourish": 36038,
+ "flow": 2180,
+ "flow": 5608,
+ "flower": 12772,
+ "flower": 4055,
+ "flowering": 19953,
+ "flowers": 4023,
+ "flowing": 14922,
+ "flown": 25659,
+ "flows": 16715,
+ "floyd": 46369,
+ "floyd": 13656,
+ "flu": 3698,
+ "flu": 13528,
+ "fluctu": 40181,
+ "fluence": 38169,
+ "fluent": 30025,
+ "fluff": 31174,
+ "fluffy": 40346,
+ "fluffy": 17054,
+ "fluid": 43803,
+ "fluid": 16717,
+ "fluids": 41490,
+ "fluor": 45127,
+ "fluore": 26974,
+ "fluorescent": 35036,
+ "fluori": 45611,
+ "flur": 31591,
+ "flush": 25777,
+ "flushing": 43754,
+ "flute": 23746,
+ "flux": 25249,
+ "flwx": 30907,
+ "fly": 5666,
+ "fly": 3228,
+ "flye": 30873,
+ "flyeagles": 39927,
+ "flyeaglesfly": 39931,
+ "flyer": 11875,
+ "flyers": 14181,
+ "flyfishing": 31800,
+ "flying": 20782,
+ "flying": 4610,
+ "flyn": 40676,
+ "flynn": 15721,
+ "flyo": 33506,
+ "flyover": 38083,
+ "fm": 13715,
+ "fm": 3689,
+ "fman": 25152,
+ "fml": 26730,
+ "fmr": 32875,
+ "fn": 22773,
+ "fn": 21763,
+ "fnc": 46506,
+ "fo": 898,
+ "fo": 6157,
+ "foal": 40386,
+ "foam": 30039,
+ "foam": 14587,
+ "foamed": 26711,
+ "fob": 40315,
+ "focal": 30934,
+ "focu": 5827,
+ "focus": 4353,
+ "focused": 9319,
+ "focuses": 20093,
+ "focusing": 15551,
+ "fod": 31015,
+ "fod": 43299,
+ "fodils": 44411,
+ "foe": 22952,
+ "foes": 46279,
+ "fog": 9417,
+ "foggy": 19770,
+ "foil": 17302,
+ "fol": 1106,
+ "fol": 48616,
+ "fold": 35201,
+ "fold": 11021,
+ "foldable": 48307,
+ "folded": 25233,
+ "folder": 25717,
+ "folding": 15464,
+ "folds": 24266,
+ "foley": 22850,
+ "foli": 7713,
+ "folia": 48964,
+ "foliage": 26350,
+ "folio": 10772,
+ "folk": 10665,
+ "folk": 6032,
+ "folke": 47190,
+ "folkl": 27273,
+ "folklore": 22133,
+ "folklore": 28620,
+ "folklorethursday": 23270,
+ "folks": 5422,
+ "follo": 41417,
+ "follow": 1964,
+ "follow": 1979,
+ "followart": 40957,
+ "followback": 33863,
+ "followed": 6499,
+ "follower": 17039,
+ "followers": 4856,
+ "following": 3473,
+ "followme": 29668,
+ "followparty": 44757,
+ "follows": 11287,
+ "followthe": 30747,
+ "folly": 41408,
+ "folsom": 42108,
+ "fom": 34540,
+ "fon": 5017,
+ "fon": 38318,
+ "fond": 19964,
+ "fonda": 44609,
+ "fondue": 48321,
+ "fone": 40672,
+ "font": 37610,
+ "font": 16248,
+ "fontaine": 37864,
+ "fontana": 43643,
+ "fontein": 45062,
+ "fonts": 32801,
+ "foo": 1183,
+ "foo": 23435,
+ "food": 4586,
+ "food": 1559,
+ "foodand": 38317,
+ "foodbank": 31926,
+ "foodie": 30762,
+ "foodie": 9847,
+ "foodies": 22416,
+ "foodnetwork": 46793,
+ "foods": 7057,
+ "foodsecurity": 49329,
+ "foodtruck": 47682,
+ "fool": 23959,
+ "fool": 12212,
+ "fooled": 28761,
+ "fooling": 47964,
+ "foolish": 33824,
+ "fools": 15946,
+ "foot": 6702,
+ "foot": 4738,
+ "footage": 11130,
+ "footb": 33466,
+ "football": 9376,
+ "football": 1882,
+ "footballer": 20646,
+ "footballers": 30269,
+ "footed": 38040,
+ "footh": 25951,
+ "foothills": 37020,
+ "footpath": 48858,
+ "footprint": 23206,
+ "footprints": 39640,
+ "footsteps": 27289,
+ "footwear": 22772,
+ "footy": 39866,
+ "footy": 18922,
+ "for": 645,
+ "for": 556,
+ "forage": 46871,
+ "foraging": 39056,
+ "forall": 17824,
+ "forbe": 49098,
+ "forbes": 13925,
+ "forbi": 24754,
+ "forbidden": 25164,
+ "force": 12068,
+ "force": 2869,
+ "forced": 8201,
+ "forces": 5381,
+ "forchange": 35848,
+ "forcing": 21573,
+ "ford": 3751,
+ "ford": 1623,
+ "fordfc": 28581,
+ "fordham": 48792,
+ "fords": 29351,
+ "fordshire": 14645,
+ "fore": 1484,
+ "fore": 1332,
+ "forec": 34155,
+ "forecast": 7361,
+ "forecasting": 38133,
+ "forecasts": 27696,
+ "foreclo": 44916,
+ "forefront": 37679,
+ "foreground": 35186,
+ "forehead": 25394,
+ "foreig": 26497,
+ "foreign": 42255,
+ "foreign": 6046,
+ "foreigners": 38549,
+ "foreman": 36174,
+ "foremost": 42128,
+ "foren": 16526,
+ "forensic": 23158,
+ "forensics": 38763,
+ "forest": 18760,
+ "forest": 4167,
+ "forestation": 33939,
+ "forestry": 26281,
+ "forests": 14095,
+ "forever": 14748,
+ "forever": 3225,
+ "forevery": 40605,
+ "forex": 40200,
+ "forex": 17395,
+ "forfe": 44871,
+ "forge": 19232,
+ "forged": 28105,
+ "forget": 46153,
+ "forget": 2678,
+ "forgets": 35613,
+ "forgetting": 25452,
+ "forgi": 22080,
+ "forgive": 15332,
+ "forgiven": 44894,
+ "forgiveness": 23585,
+ "forgood": 39169,
+ "forgot": 6483,
+ "forgotten": 7994,
+ "fork": 24501,
+ "fork": 13700,
+ "forkids": 48571,
+ "forklift": 43202,
+ "forks": 28769,
+ "forlife": 17624,
+ "form": 1157,
+ "form": 1907,
+ "forma": 38829,
+ "formal": 12978,
+ "formally": 24867,
+ "format": 16252,
+ "format": 11874,
+ "formation": 2510,
+ "formations": 37715,
+ "formative": 48882,
+ "formats": 32085,
+ "forme": 42085,
+ "formed": 6528,
+ "former": 2276,
+ "formerly": 20866,
+ "formid": 38599,
+ "formidable": 39834,
+ "forming": 15443,
+ "formity": 42290,
+ "forms": 5161,
+ "formu": 8689,
+ "formul": 23923,
+ "formula": 24485,
+ "formula": 10776,
+ "formulae": 34586,
+ "formulated": 45066,
+ "forre": 38876,
+ "forrest": 25205,
+ "forrester": 45338,
+ "forsa": 48958,
+ "forsale": 13303,
+ "forster": 42923,
+ "forsy": 29629,
+ "forsyth": 40952,
+ "fort": 12300,
+ "fort": 2921,
+ "forte": 44350,
+ "forte": 27367,
+ "forth": 17068,
+ "forth": 11932,
+ "forthcoming": 19989,
+ "forthe": 12521,
+ "forti": 26984,
+ "fortified": 46486,
+ "fortn": 14428,
+ "fortnight": 39235,
+ "fortnite": 38734,
+ "fortnite": 17890,
+ "fortress": 19988,
+ "fortun": 6950,
+ "fortunate": 19898,
+ "fortunately": 34358,
+ "fortune": 40931,
+ "fortune": 11451,
+ "fortunes": 41989,
+ "forty": 24399,
+ "forum": 37851,
+ "forum": 4538,
+ "forums": 31518,
+ "forwar": 34364,
+ "forward": 47031,
+ "forward": 2342,
+ "forwards": 38974,
+ "foryou": 35150,
+ "forz": 46056,
+ "forza": 33293,
+ "forza": 28089,
+ "fos": 36925,
+ "fos": 22081,
+ "foss": 14240,
+ "foss": 37911,
+ "fossil": 20419,
+ "fossil": 15202,
+ "fossilfriday": 26079,
+ "fossils": 30652,
+ "foster": 26778,
+ "foster": 8139,
+ "fostering": 35996,
+ "fosters": 37644,
+ "foto": 15908,
+ "foto": 12823,
+ "fotogra": 23687,
+ "fotografia": 40256,
+ "fotos": 26124,
+ "fou": 14516,
+ "fought": 10844,
+ "foul": 19784,
+ "foun": 3154,
+ "found": 3454,
+ "found": 1546,
+ "foundation": 4058,
+ "foundations": 25219,
+ "founded": 12240,
+ "founder": 5145,
+ "founders": 14602,
+ "founding": 15317,
+ "foundry": 31426,
+ "fountain": 44863,
+ "fountain": 13405,
+ "fountains": 37411,
+ "four": 5113,
+ "four": 2721,
+ "foursquare": 34484,
+ "fourteen": 46255,
+ "fourth": 7516,
+ "fourthofjuly": 47805,
+ "fow": 17084,
+ "fowl": 31685,
+ "fowler": 20980,
+ "fox": 5007,
+ "fox": 3240,
+ "foxandfriends": 45841,
+ "foxes": 24145,
+ "foxnews": 18830,
+ "foxsports": 39267,
+ "foxtv": 49396,
+ "foxx": 32993,
+ "foxy": 27945,
+ "foy": 30284,
+ "foyer": 38011,
+ "foyle": 47902,
+ "fp": 28058,
+ "fp": 8941,
+ "fpl": 27970,
+ "fpp": 36464,
+ "fps": 25300,
+ "fpv": 43175,
+ "fr": 936,
+ "fr": 5512,
+ "fra": 3368,
+ "fra": 15644,
+ "frac": 15607,
+ "fracking": 21894,
+ "fractal": 46471,
+ "fraction": 26788,
+ "fractu": 25847,
+ "fracture": 28995,
+ "fractured": 37421,
+ "fractures": 46213,
+ "frag": 13093,
+ "fragile": 23579,
+ "fragment": 39209,
+ "fragments": 41424,
+ "fragr": 15403,
+ "fragrance": 17874,
+ "fragrances": 44567,
+ "fragrant": 37030,
+ "fram": 27987,
+ "frame": 11029,
+ "frame": 6481,
+ "framed": 13135,
+ "frames": 15479,
+ "framework": 13195,
+ "frameworks": 43136,
+ "framing": 24539,
+ "frampton": 41733,
+ "fran": 2118,
+ "fran": 18878,
+ "franc": 3872,
+ "franc": 42340,
+ "franca": 48952,
+ "france": 12045,
+ "france": 3552,
+ "frances": 20803,
+ "francesca": 32327,
+ "francesco": 25816,
+ "franch": 11756,
+ "franchi": 46438,
+ "franchise": 13664,
+ "franci": 46458,
+ "francis": 22187,
+ "francis": 7660,
+ "francisco": 6887,
+ "franco": 17934,
+ "franco": 17052,
+ "francois": 29317,
+ "frank": 5390,
+ "frank": 5229,
+ "franken": 20487,
+ "franken": 48252,
+ "frankenstein": 26410,
+ "frankfur": 17442,
+ "frankfurt": 18598,
+ "franki": 39227,
+ "frankie": 38373,
+ "frankie": 16215,
+ "franklin": 40935,
+ "franklin": 9999,
+ "frankly": 38015,
+ "franks": 42855,
+ "frans": 47892,
+ "franz": 25449,
+ "franç": 38381,
+ "fraser": 39082,
+ "fraser": 16754,
+ "frat": 15225,
+ "frat": 39292,
+ "fraternity": 24433,
+ "frau": 23063,
+ "fraud": 40647,
+ "fraud": 9961,
+ "fraudul": 42655,
+ "fraudulent": 47408,
+ "fray": 41154,
+ "frazier": 32841,
+ "frc": 41507,
+ "fre": 821,
+ "fre": 43165,
+ "freak": 20352,
+ "freak": 13701,
+ "freaked": 43511,
+ "freakin": 23900,
+ "freaking": 11992,
+ "freaks": 27009,
+ "freaky": 31583,
+ "freck": 33328,
+ "freckles": 48036,
+ "fred": 9486,
+ "fred": 6678,
+ "freddie": 41890,
+ "freddie": 17014,
+ "freddy": 24394,
+ "freder": 10745,
+ "frederic": 41165,
+ "frederick": 37103,
+ "frederick": 18570,
+ "fredo": 48241,
+ "free": 2065,
+ "free": 1139,
+ "freebie": 35865,
+ "freebies": 28630,
+ "freec": 46569,
+ "freed": 12585,
+ "freed": 23392,
+ "freedom": 17992,
+ "freedom": 4511,
+ "freedoms": 32500,
+ "freef": 48678,
+ "freel": 14174,
+ "freelance": 21942,
+ "freely": 24436,
+ "freeman": 16450,
+ "freep": 32499,
+ "freepalestine": 39242,
+ "freer": 44676,
+ "frees": 27455,
+ "freestyle": 15594,
+ "freeway": 24927,
+ "freeze": 14187,
+ "freezer": 25390,
+ "freezing": 12499,
+ "frei": 30183,
+ "freight": 17023,
+ "fremantle": 48012,
+ "fremont": 34578,
+ "fren": 2919,
+ "french": 13118,
+ "french": 3461,
+ "frenzy": 30084,
+ "frequ": 9211,
+ "frequencies": 45319,
+ "frequency": 18825,
+ "frequent": 19836,
+ "frequently": 22434,
+ "fresco": 31609,
+ "fresh": 4065,
+ "fresh": 2975,
+ "fresher": 49284,
+ "freshers": 35810,
+ "freshest": 46809,
+ "freshly": 16081,
+ "freshman": 9381,
+ "freshmen": 21292,
+ "freshness": 45872,
+ "freshwater": 24803,
+ "fresno": 40879,
+ "fresno": 20995,
+ "fret": 40510,
+ "freud": 40787,
+ "frey": 22136,
+ "frey": 9082,
+ "fri": 815,
+ "fri": 6882,
+ "friars": 30513,
+ "fric": 18981,
+ "frick": 46304,
+ "friction": 38563,
+ "frid": 46388,
+ "frida": 36001,
+ "friday": 6350,
+ "friday": 1461,
+ "fridayfeeling": 11952,
+ "fridaymotivation": 38544,
+ "fridaynight": 44858,
+ "fridayreads": 37736,
+ "fridays": 15589,
+ "fridaythe": 47642,
+ "fridge": 13491,
+ "fridges": 40734,
+ "frie": 36999,
+ "fried": 13743,
+ "fried": 7310,
+ "friedman": 29402,
+ "friedrich": 34171,
+ "friend": 3017,
+ "friend": 1625,
+ "friendly": 44612,
+ "friendly": 4681,
+ "friends": 38875,
+ "friends": 1574,
+ "friendship": 42674,
+ "friendship": 7679,
+ "friendships": 28840,
+ "fries": 11369,
+ "frifotos": 40493,
+ "friger": 20785,
+ "friggin": 48300,
+ "frigh": 34831,
+ "fright": 24277,
+ "fright": 40207,
+ "frightened": 47136,
+ "frightening": 39290,
+ "fringe": 10640,
+ "fris": 37252,
+ "frisbee": 45768,
+ "frisco": 35945,
+ "frit": 34614,
+ "fritz": 29860,
+ "friyay": 38887,
+ "frm": 12951,
+ "fro": 626,
+ "fro": 26603,
+ "frock": 45306,
+ "frog": 26494,
+ "frog": 11438,
+ "frogs": 20781,
+ "from": 8330,
+ "from": 633,
+ "frome": 48691,
+ "fromhome": 41477,
+ "fromthe": 18756,
+ "fron": 1847,
+ "fron": 18036,
+ "front": 10996,
+ "front": 2184,
+ "frontal": 35794,
+ "frontier": 18253,
+ "frontiers": 38396,
+ "frontline": 29589,
+ "frontman": 36775,
+ "fronts": 26846,
+ "froome": 48560,
+ "frosh": 47069,
+ "frost": 39420,
+ "frost": 11619,
+ "frosted": 35988,
+ "frosting": 33872,
+ "frosty": 22760,
+ "froze": 47788,
+ "frozen": 42464,
+ "frozen": 8507,
+ "frs": 26216,
+ "fru": 3248,
+ "fruit": 16771,
+ "fruit": 5190,
+ "fruitful": 31494,
+ "fruits": 13282,
+ "fruity": 22320,
+ "frustr": 16046,
+ "frustrated": 25111,
+ "frustrating": 31342,
+ "frustration": 30535,
+ "fry": 33914,
+ "fry": 13686,
+ "fryer": 49217,
+ "frying": 38516,
+ "fs": 23699,
+ "fs": 3854,
+ "fsa": 33373,
+ "fsu": 44185,
+ "fsu": 19317,
+ "ft": 3391,
+ "ft": 981,
+ "fta": 41975,
+ "ftc": 33752,
+ "fted": 5612,
+ "fter": 25063,
+ "fthe": 22886,
+ "ftheday": 9823,
+ "fting": 6174,
+ "fton": 26605,
+ "ftp": 42649,
+ "fts": 3767,
+ "ftse": 46717,
+ "ftw": 19298,
+ "fty": 17494,
+ "fu": 665,
+ "fu": 9098,
+ "fuch": 42617,
+ "fudge": 24270,
+ "fue": 43723,
+ "fuego": 41500,
+ "fuel": 21113,
+ "fuel": 5945,
+ "fueled": 28792,
+ "fueling": 38793,
+ "fuelled": 48357,
+ "fuels": 19365,
+ "fuentes": 44393,
+ "fuer": 29645,
+ "fug": 29227,
+ "fugitive": 39257,
+ "fuji": 15573,
+ "fuji": 21634,
+ "fujifilm": 24765,
+ "fuk": 31051,
+ "fuku": 20728,
+ "fukushima": 33929,
+ "ful": 1814,
+ "ful": 857,
+ "fulbright": 41834,
+ "fulfill": 43675,
+ "fulfill": 27467,
+ "fulfilled": 29919,
+ "fulfilling": 30621,
+ "fulfillment": 45573,
+ "fulham": 25574,
+ "full": 9407,
+ "full": 1476,
+ "fuller": 20225,
+ "fullerton": 42822,
+ "fullest": 35603,
+ "fully": 39142,
+ "fully": 2401,
+ "fulness": 10526,
+ "fuls": 41606,
+ "fulton": 26725,
+ "fum": 38393,
+ "fumble": 49373,
+ "fun": 1229,
+ "fun": 1499,
+ "func": 8679,
+ "function": 8093,
+ "functional": 12885,
+ "functionality": 33316,
+ "functioning": 25479,
+ "functions": 18001,
+ "fund": 19089,
+ "fund": 4877,
+ "fundam": 11670,
+ "fundament": 18852,
+ "fundamental": 17627,
+ "fundamentally": 45378,
+ "fundamentals": 27887,
+ "funday": 15439,
+ "funded": 10588,
+ "funding": 5588,
+ "fundra": 6201,
+ "fundraiser": 10049,
+ "fundraising": 10755,
+ "funds": 7066,
+ "funer": 40693,
+ "funeral": 10606,
+ "funfact": 31596,
+ "funfactfriday": 40710,
+ "fungal": 38838,
+ "fungi": 27837,
+ "fungus": 30677,
+ "funk": 37353,
+ "funk": 13372,
+ "funko": 49402,
+ "funko": 23697,
+ "funky": 16492,
+ "funnel": 27862,
+ "funnier": 42232,
+ "funniest": 15557,
+ "funny": 19124,
+ "funny": 3789,
+ "funrun": 34185,
+ "fur": 2395,
+ "fur": 9686,
+ "furi": 40816,
+ "furious": 17522,
+ "furman": 49238,
+ "furn": 21348,
+ "furnace": 31913,
+ "furnished": 37388,
+ "furnitu": 45696,
+ "furniture": 7993,
+ "furry": 33414,
+ "furry": 15351,
+ "fursuit": 25306,
+ "fursuit": 43083,
+ "fursuitfriday": 27917,
+ "further": 5583,
+ "fury": 14404,
+ "fus": 18419,
+ "fuse": 23386,
+ "fused": 38994,
+ "fusion": 44661,
+ "fusion": 9364,
+ "fuss": 26331,
+ "fut": 21460,
+ "fut": 34049,
+ "futbol": 33014,
+ "futsal": 20558,
+ "futu": 33454,
+ "futur": 38840,
+ "future": 7959,
+ "future": 1904,
+ "futureof": 22599,
+ "futureofwork": 33202,
+ "futures": 13488,
+ "futuri": 19068,
+ "futurism": 48435,
+ "futurist": 48086,
+ "futuristic": 30987,
+ "fuzz": 47128,
+ "fuzz": 40443,
+ "fuzzy": 25876,
+ "fv": 29795,
+ "fw": 23934,
+ "fw": 5277,
+ "fwd": 27052,
+ "fx": 17807,
+ "fx": 9025,
+ "fy": 8440,
+ "fy": 2702,
+ "fyi": 16014,
+ "fying": 5294,
+ "fz": 46400,
+ "fé": 34072,
+ "g": 70,
+ "g": 326,
+ "ga": 1275,
+ "ga": 1531,
+ "gaa": 10715,
+ "gaal": 40867,
+ "gaard": 24645,
+ "gab": 3927,
+ "gab": 37382,
+ "gabbana": 36272,
+ "gabby": 48115,
+ "gabby": 24567,
+ "gabe": 18916,
+ "gabi": 41931,
+ "gable": 33387,
+ "gables": 40928,
+ "gabri": 8311,
+ "gabriel": 31684,
+ "gabriel": 13244,
+ "gabrielle": 33572,
+ "gaby": 46420,
+ "gac": 32520,
+ "gad": 7786,
+ "gad": 44651,
+ "gadget": 25525,
+ "gadgets": 22840,
+ "gado": 29489,
+ "gae": 22003,
+ "gael": 35663,
+ "gaelic": 31173,
+ "gaf": 21354,
+ "gaf": 32670,
+ "gag": 14121,
+ "gag": 18844,
+ "gaga": 9782,
+ "gage": 21081,
+ "gah": 27750,
+ "gai": 24214,
+ "gai": 25153,
+ "gaia": 41269,
+ "gail": 41160,
+ "gail": 27676,
+ "gain": 21536,
+ "gain": 6202,
+ "gaine": 35747,
+ "gained": 14489,
+ "gaines": 49225,
+ "gainesville": 40427,
+ "gaining": 15260,
+ "gains": 42751,
+ "gains": 12107,
+ "gal": 2001,
+ "gal": 4488,
+ "gala": 7211,
+ "galac": 18864,
+ "galactic": 25514,
+ "galap": 41115,
+ "galapagos": 44057,
+ "galat": 39853,
+ "galatasar": 42413,
+ "galatasaray": 47787,
+ "galax": 5647,
+ "galaxies": 32435,
+ "galaxy": 32130,
+ "galaxy": 6545,
+ "gale": 37658,
+ "gale": 21380,
+ "galerie": 44539,
+ "gales": 48633,
+ "gali": 17546,
+ "gali": 30552,
+ "galicia": 47927,
+ "galileo": 39671,
+ "gall": 3011,
+ "gall": 33374,
+ "galla": 16847,
+ "gallagher": 19168,
+ "galleria": 40656,
+ "galleries": 22304,
+ "gallery": 36648,
+ "gallery": 3830,
+ "galley": 48917,
+ "galli": 22568,
+ "gallipoli": 47249,
+ "gallo": 37350,
+ "gallo": 33265,
+ "gallon": 24615,
+ "gallons": 29335,
+ "galloway": 27796,
+ "galore": 22286,
+ "gals": 20125,
+ "galvani": 46046,
+ "galve": 34328,
+ "galveston": 36003,
+ "galway": 38045,
+ "galway": 17112,
+ "gam": 1162,
+ "gam": 34195,
+ "gama": 35873,
+ "gambia": 32988,
+ "gamble": 26121,
+ "gambling": 20287,
+ "game": 2882,
+ "game": 1063,
+ "gameart": 31490,
+ "gameboy": 40951,
+ "gamecube": 44079,
+ "gameday": 9241,
+ "gamedev": 7544,
+ "gameinsight": 42626,
+ "gameof": 10987,
+ "gameofthrones": 11822,
+ "gameon": 47691,
+ "gameplay": 16794,
+ "gamer": 12595,
+ "gamer": 11598,
+ "gamergate": 25961,
+ "gamers": 16166,
+ "gamersunite": 26423,
+ "games": 18551,
+ "games": 1955,
+ "gamescom": 37003,
+ "gamestop": 39436,
+ "gametime": 45899,
+ "gami": 42025,
+ "gamification": 48908,
+ "gaming": 28803,
+ "gaming": 4017,
+ "gamma": 22180,
+ "gamo": 39325,
+ "gan": 1822,
+ "gan": 1670,
+ "gand": 8399,
+ "ganda": 27261,
+ "gander": 44508,
+ "gandhi": 12322,
+ "ganesh": 30362,
+ "ganesha": 45185,
+ "gang": 8066,
+ "gang": 5674,
+ "ganga": 36275,
+ "gangnam": 46777,
+ "gangs": 29844,
+ "gangsta": 37365,
+ "gangster": 26514,
+ "gani": 48324,
+ "gann": 45665,
+ "gannon": 45837,
+ "gano": 25304,
+ "gao": 26556,
+ "gaon": 19279,
+ "gap": 29906,
+ "gap": 7609,
+ "gaps": 25296,
+ "gar": 1099,
+ "gar": 5824,
+ "gara": 28710,
+ "garage": 8474,
+ "garbage": 13760,
+ "garci": 44658,
+ "garcia": 10529,
+ "gard": 7751,
+ "gard": 21003,
+ "garda": 31906,
+ "garde": 22649,
+ "garden": 4674,
+ "garden": 2756,
+ "gardenchat": 46292,
+ "gardener": 28554,
+ "gardeners": 38205,
+ "gardening": 10483,
+ "gardens": 6152,
+ "gardiner": 43121,
+ "gardner": 18710,
+ "gare": 5633,
+ "gare": 48402,
+ "gareth": 37140,
+ "gareth": 18175,
+ "garfield": 26728,
+ "garh": 16762,
+ "gari": 40898,
+ "gari": 43080,
+ "garis": 37839,
+ "garland": 23418,
+ "garlic": 9685,
+ "garment": 31418,
+ "garments": 43341,
+ "garmin": 39885,
+ "garner": 20340,
+ "garnet": 37669,
+ "garo": 30388,
+ "garrett": 15881,
+ "garri": 21764,
+ "garrison": 30108,
+ "garros": 40425,
+ "garry": 24398,
+ "gars": 12055,
+ "gart": 18380,
+ "gart": 18751,
+ "garten": 14684,
+ "garter": 48420,
+ "garth": 45398,
+ "garth": 24469,
+ "gartner": 43334,
+ "gartner": 29678,
+ "garty": 46383,
+ "garu": 31140,
+ "garvey": 39511,
+ "garwal": 38623,
+ "gary": 10535,
+ "gary": 4516,
+ "garza": 49393,
+ "gas": 5047,
+ "gas": 2474,
+ "gases": 36971,
+ "gasoline": 27691,
+ "gasp": 43762,
+ "gaston": 40669,
+ "gastri": 49197,
+ "gastro": 23740,
+ "gastron": 30699,
+ "gastronomy": 46987,
+ "gat": 5314,
+ "gat": 18941,
+ "gata": 44575,
+ "gate": 8071,
+ "gate": 3302,
+ "gated": 23997,
+ "gates": 9472,
+ "gateshead": 40051,
+ "gateway": 45221,
+ "gateway": 14943,
+ "gather": 36345,
+ "gather": 12602,
+ "gathered": 14646,
+ "gathering": 9197,
+ "gatherings": 48096,
+ "gathers": 39250,
+ "gating": 27561,
+ "gation": 11095,
+ "gations": 33906,
+ "gato": 44492,
+ "gator": 20216,
+ "gator": 16390,
+ "gatorade": 36354,
+ "gators": 17173,
+ "gatory": 24796,
+ "gatsby": 32586,
+ "gatwick": 37122,
+ "gau": 5919,
+ "gau": 43068,
+ "gauge": 18728,
+ "gaunt": 31862,
+ "gauntlet": 37163,
+ "gautam": 45853,
+ "gautam": 31356,
+ "gauteng": 40333,
+ "gav": 8966,
+ "gave": 3485,
+ "gavin": 32974,
+ "gavin": 16389,
+ "gaw": 15405,
+ "gawd": 43239,
+ "gawx": 43420,
+ "gay": 7460,
+ "gay": 5627,
+ "gaya": 39477,
+ "gaye": 41401,
+ "gayle": 29998,
+ "gayo": 36768,
+ "gays": 28001,
+ "gaz": 4837,
+ "gaz": 36475,
+ "gaza": 38391,
+ "gaza": 10112,
+ "gazaunderattack": 42458,
+ "gaze": 23212,
+ "gazette": 20443,
+ "gazing": 28373,
+ "gb": 8727,
+ "gb": 4619,
+ "gba": 18528,
+ "gbbo": 34474,
+ "gbc": 42993,
+ "gbp": 27391,
+ "gbr": 31984,
+ "gby": 40509,
+ "gc": 8577,
+ "gc": 6043,
+ "gcc": 26804,
+ "gcse": 28763,
+ "gcu": 34137,
+ "gd": 13264,
+ "gd": 14604,
+ "gdc": 32793,
+ "gden": 44928,
+ "gdp": 17100,
+ "gdpr": 22963,
+ "ge": 619,
+ "ge": 710,
+ "gea": 26790,
+ "gear": 15532,
+ "gear": 4802,
+ "gearbox": 42454,
+ "geared": 33903,
+ "gearing": 19027,
+ "gears": 21147,
+ "geaux": 36313,
+ "gecko": 38616,
+ "ged": 17252,
+ "ged": 3480,
+ "geddon": 31720,
+ "gedly": 13991,
+ "gee": 9806,
+ "gee": 9071,
+ "geek": 17920,
+ "geek": 7135,
+ "geeks": 20110,
+ "geeky": 47332,
+ "geel": 25906,
+ "geelong": 34555,
+ "gees": 38088,
+ "geese": 26413,
+ "geez": 42394,
+ "geh": 30320,
+ "geist": 38290,
+ "gel": 7343,
+ "gel": 5697,
+ "gelato": 29577,
+ "gels": 42552,
+ "gely": 14637,
+ "gem": 14261,
+ "gem": 7613,
+ "gement": 19495,
+ "gemini": 23086,
+ "gemma": 23952,
+ "gems": 14355,
+ "gemstone": 27747,
+ "gemstones": 43972,
+ "gen": 1024,
+ "gen": 3278,
+ "gence": 16088,
+ "gency": 5245,
+ "gend": 33247,
+ "gender": 22976,
+ "gender": 5906,
+ "gendere": 35824,
+ "genderequality": 43338,
+ "gene": 5822,
+ "gene": 7962,
+ "genealo": 24142,
+ "genealogy": 29381,
+ "gener": 1832,
+ "general": 20576,
+ "general": 3658,
+ "generally": 19256,
+ "generals": 30296,
+ "generate": 16896,
+ "generated": 19450,
+ "generates": 33938,
+ "generating": 23882,
+ "generation": 41211,
+ "generation": 4883,
+ "generational": 34506,
+ "generations": 12247,
+ "generative": 29472,
+ "generator": 19399,
+ "generators": 41917,
+ "generic": 26978,
+ "generosity": 23015,
+ "generous": 12570,
+ "generously": 35113,
+ "genes": 19683,
+ "genesis": 13518,
+ "genetic": 47746,
+ "genetic": 13578,
+ "genetically": 36745,
+ "genetics": 18276,
+ "geneva": 14799,
+ "genevie": 41633,
+ "genevieve": 46584,
+ "geni": 22334,
+ "genic": 15750,
+ "genie": 24221,
+ "genital": 32960,
+ "genius": 8235,
+ "geniuses": 41406,
+ "geno": 41544,
+ "geno": 46776,
+ "genoa": 43993,
+ "genoci": 14687,
+ "genocide": 15903,
+ "genome": 23991,
+ "genomic": 44371,
+ "genomics": 26227,
+ "genre": 14249,
+ "genres": 30340,
+ "gens": 17449,
+ "gent": 3685,
+ "gent": 7139,
+ "gente": 34325,
+ "gentle": 7262,
+ "gentle": 13577,
+ "gentleman": 13293,
+ "gentlemen": 11692,
+ "gently": 17187,
+ "gento": 28320,
+ "gentri": 41148,
+ "gentry": 47225,
+ "gents": 18862,
+ "genu": 9182,
+ "genuine": 12184,
+ "genuinely": 20006,
+ "genus": 38161,
+ "geny": 35323,
+ "geo": 5038,
+ "geo": 11604,
+ "geocaching": 47908,
+ "geof": 20629,
+ "geoff": 33697,
+ "geoff": 20386,
+ "geoffrey": 29520,
+ "geograph": 45920,
+ "geographic": 22635,
+ "geographical": 39380,
+ "geography": 17101,
+ "geological": 38380,
+ "geology": 21578,
+ "geom": 46135,
+ "geome": 12958,
+ "geometric": 22419,
+ "geometry": 21731,
+ "geon": 20844,
+ "geon": 7295,
+ "geons": 15914,
+ "geopol": 39758,
+ "geor": 2549,
+ "georg": 43126,
+ "george": 8377,
+ "george": 3296,
+ "georges": 25042,
+ "georgetown": 22970,
+ "georgie": 42115,
+ "georgina": 43892,
+ "geospatial": 46238,
+ "geothermal": 38413,
+ "geous": 3068,
+ "ger": 1291,
+ "ger": 1502,
+ "gera": 48867,
+ "gerald": 29901,
+ "gerald": 13269,
+ "gerard": 35979,
+ "gerard": 20826,
+ "gerber": 45058,
+ "gered": 40179,
+ "geri": 41664,
+ "geri": 46214,
+ "gering": 24077,
+ "germain": 38786,
+ "german": 14972,
+ "german": 4710,
+ "germans": 28400,
+ "germany": 4464,
+ "germin": 44721,
+ "germs": 47731,
+ "geronimo": 45171,
+ "gerrard": 26538,
+ "gerry": 29825,
+ "gerry": 23026,
+ "gers": 3314,
+ "gertrude": 46950,
+ "gervais": 36527,
+ "gery": 32845,
+ "ges": 3316,
+ "gest": 11843,
+ "gest": 2033,
+ "gesture": 21780,
+ "gestures": 43524,
+ "get": 5670,
+ "get": 779,
+ "geta": 13155,
+ "getaway": 16131,
+ "gether": 27224,
+ "getic": 20661,
+ "getin": 25822,
+ "getit": 44891,
+ "getit": 48315,
+ "getoutside": 35644,
+ "gets": 39448,
+ "gets": 2127,
+ "gett": 6647,
+ "gett": 27965,
+ "gettable": 15620,
+ "gette": 29800,
+ "gettin": 13428,
+ "getting": 30885,
+ "getting": 1500,
+ "getty": 31185,
+ "getty": 13965,
+ "gettys": 35189,
+ "gettysburg": 37062,
+ "getyour": 42159,
+ "gey": 29289,
+ "gf": 28953,
+ "gf": 10846,
+ "gfriend": 35245,
+ "gfs": 37553,
+ "gg": 1129,
+ "gg": 3286,
+ "gga": 26003,
+ "ggan": 25626,
+ "gge": 21521,
+ "gge": 31659,
+ "gged": 6095,
+ "gger": 12367,
+ "gger": 3493,
+ "ggers": 7480,
+ "ggg": 20143,
+ "gggg": 33513,
+ "ggi": 21662,
+ "ggin": 17160,
+ "gging": 4966,
+ "ggins": 12444,
+ "ggle": 34981,
+ "ggle": 11430,
+ "ggled": 46328,
+ "ggles": 14703,
+ "ggling": 16523,
+ "ggly": 39407,
+ "ggs": 4797,
+ "ggy": 24935,
+ "ggy": 6476,
+ "gh": 583,
+ "gh": 790,
+ "gha": 10010,
+ "gha": 25183,
+ "gham": 21456,
+ "ghan": 18945,
+ "ghan": 6624,
+ "ghana": 30330,
+ "ghana": 9731,
+ "ghanaian": 34223,
+ "ghani": 36699,
+ "ghar": 37334,
+ "ghar": 36973,
+ "ghat": 43989,
+ "ghaz": 37493,
+ "ghc": 42139,
+ "ghe": 10754,
+ "ghe": 28561,
+ "ghead": 40783,
+ "ghee": 34794,
+ "gher": 21542,
+ "gher": 14796,
+ "ghet": 18447,
+ "ghetti": 17485,
+ "ghetto": 22403,
+ "ghi": 22436,
+ "ghi": 22279,
+ "ghibli": 40555,
+ "ghj": 38439,
+ "ghlin": 24131,
+ "gho": 4307,
+ "ghorn": 38094,
+ "ghosh": 43279,
+ "ghoshal": 49134,
+ "ghost": 11417,
+ "ghost": 7108,
+ "ghostbusters": 25462,
+ "ghostly": 44901,
+ "ghosts": 16737,
+ "ghou": 35843,
+ "ghoul": 45302,
+ "ghouse": 38238,
+ "ghs": 14157,
+ "ght": 1413,
+ "ght": 630,
+ "ghted": 4963,
+ "ghter": 2427,
+ "ghters": 12994,
+ "ghtful": 8334,
+ "ghting": 3019,
+ "ghtly": 6993,
+ "ghtning": 39740,
+ "ghton": 16353,
+ "ghts": 1259,
+ "ghty": 20968,
+ "ghty": 5866,
+ "ghu": 25808,
+ "ghue": 45675,
+ "ghyun": 25010,
+ "ghz": 24325,
+ "gi": 707,
+ "gi": 4478,
+ "gia": 8864,
+ "giac": 35444,
+ "giam": 39623,
+ "gian": 17274,
+ "gian": 12866,
+ "gianni": 46752,
+ "giant": 23668,
+ "giant": 4687,
+ "giants": 7076,
+ "giar": 34241,
+ "gib": 9816,
+ "gibb": 18964,
+ "gibbons": 31974,
+ "gibbs": 26488,
+ "gibility": 33297,
+ "gible": 13159,
+ "gibr": 20206,
+ "gibraltar": 23988,
+ "gibson": 37420,
+ "gibson": 12178,
+ "gic": 27900,
+ "gic": 2570,
+ "gical": 32973,
+ "gically": 26320,
+ "gid": 36774,
+ "gid": 21413,
+ "giddy": 40894,
+ "gideon": 43867,
+ "gidi": 30603,
+ "gie": 11459,
+ "gie": 3991,
+ "gier": 28974,
+ "gies": 5505,
+ "gif": 11363,
+ "gif": 11677,
+ "gifford": 47850,
+ "gifs": 37643,
+ "gift": 20569,
+ "gift": 2733,
+ "gifted": 15110,
+ "giftide": 20152,
+ "giftideas": 23487,
+ "gifting": 39546,
+ "gifts": 5836,
+ "gig": 26981,
+ "gig": 7471,
+ "gigab": 34530,
+ "gigan": 24104,
+ "gigantic": 31507,
+ "giggle": 36426,
+ "giggles": 42731,
+ "giggs": 44692,
+ "gigi": 44106,
+ "gigi": 26171,
+ "gigs": 20316,
+ "gil": 3997,
+ "gil": 10088,
+ "gila": 46952,
+ "gilbert": 14154,
+ "gilded": 44341,
+ "giles": 24802,
+ "gill": 14280,
+ "gill": 12003,
+ "gille": 29610,
+ "gilles": 39590,
+ "gillespie": 36242,
+ "gillette": 38603,
+ "gilli": 13695,
+ "gillian": 28753,
+ "gills": 48851,
+ "gilmore": 27603,
+ "gilt": 44378,
+ "gim": 31284,
+ "gimm": 40692,
+ "gimme": 21525,
+ "gin": 3374,
+ "gin": 4941,
+ "gina": 15604,
+ "gine": 27482,
+ "ging": 10829,
+ "ging": 3905,
+ "ginger": 16287,
+ "ginger": 9718,
+ "gingerbread": 23692,
+ "gini": 35768,
+ "gino": 36521,
+ "gins": 18328,
+ "gio": 16329,
+ "gio": 8050,
+ "gion": 41226,
+ "gior": 14920,
+ "giorgio": 33271,
+ "giorno": 33310,
+ "gios": 41927,
+ "gious": 14419,
+ "giov": 21404,
+ "giovanni": 26574,
+ "gipp": 41351,
+ "gir": 1077,
+ "gir": 25481,
+ "gira": 16949,
+ "giraffe": 22826,
+ "giri": 31709,
+ "girl": 3914,
+ "girl": 1611,
+ "girlfriend": 8217,
+ "girlfriends": 30736,
+ "girlpower": 37433,
+ "girls": 15480,
+ "girls": 1917,
+ "girly": 29605,
+ "giro": 39664,
+ "giro": 26454,
+ "girona": 47842,
+ "giroud": 41177,
+ "gis": 16266,
+ "gis": 12773,
+ "gist": 21241,
+ "git": 16060,
+ "git": 20918,
+ "gita": 40838,
+ "github": 31196,
+ "giu": 17931,
+ "giuli": 29762,
+ "giuliani": 47739,
+ "giuse": 29385,
+ "giuseppe": 33563,
+ "give": 4120,
+ "give": 1781,
+ "giveaway": 5310,
+ "giveaways": 18974,
+ "giveback": 41385,
+ "given": 33323,
+ "given": 4302,
+ "givenchy": 38245,
+ "giver": 43339,
+ "gives": 3926,
+ "giveup": 35485,
+ "giving": 14673,
+ "giving": 2339,
+ "givingback": 49300,
+ "givingtuesday": 23556,
+ "giz": 29237,
+ "gk": 38953,
+ "gk": 18719,
+ "gl": 1849,
+ "gl": 14751,
+ "gla": 1523,
+ "gla": 36904,
+ "glaci": 14924,
+ "glacial": 40782,
+ "glacier": 19282,
+ "glaciers": 42528,
+ "glad": 20841,
+ "glad": 4761,
+ "glades": 37432,
+ "gladi": 21742,
+ "gladiator": 38477,
+ "gladiators": 41087,
+ "gladly": 41598,
+ "gladys": 43168,
+ "glam": 8738,
+ "glam": 16905,
+ "glamorous": 22896,
+ "glamour": 42876,
+ "glamour": 17499,
+ "glamping": 46167,
+ "glan": 40482,
+ "glan": 45844,
+ "glance": 26557,
+ "gland": 41441,
+ "glar": 48535,
+ "glar": 41702,
+ "glare": 46035,
+ "glas": 29935,
+ "glas": 43654,
+ "glasgo": 6757,
+ "glasgow": 29990,
+ "glasgow": 7363,
+ "glass": 16305,
+ "glass": 3313,
+ "glasses": 6116,
+ "glaston": 26848,
+ "glastonbury": 28233,
+ "glau": 39171,
+ "glaze": 28112,
+ "glazed": 24122,
+ "gle": 7166,
+ "gle": 2865,
+ "glee": 32379,
+ "glee": 21614,
+ "glen": 6158,
+ "glen": 11049,
+ "glend": 38332,
+ "glendale": 33043,
+ "glenn": 32004,
+ "glenn": 12861,
+ "gler": 34649,
+ "gley": 21998,
+ "gli": 5896,
+ "gli": 28791,
+ "glia": 22217,
+ "glide": 37321,
+ "glider": 41636,
+ "glimp": 12888,
+ "glimpse": 13817,
+ "glio": 29785,
+ "glit": 21079,
+ "glitch": 29563,
+ "glitter": 16528,
+ "glitz": 44542,
+ "glo": 1721,
+ "glo": 30474,
+ "glob": 13363,
+ "global": 6707,
+ "global": 2779,
+ "globalgoals": 33211,
+ "globalhealth": 46751,
+ "globalization": 47680,
+ "globally": 17775,
+ "globalwarming": 46017,
+ "globe": 19436,
+ "globe": 9368,
+ "globes": 38085,
+ "glock": 38818,
+ "glomer": 43689,
+ "gloom": 48594,
+ "gloomy": 32199,
+ "glori": 7270,
+ "gloria": 19244,
+ "glorious": 9171,
+ "glory": 36107,
+ "glory": 7285,
+ "glos": 40633,
+ "gloss": 38258,
+ "gloss": 22014,
+ "glossy": 29802,
+ "glou": 15989,
+ "gloucester": 28133,
+ "gloucester": 23835,
+ "gloucestershire": 33789,
+ "glove": 16078,
+ "glover": 21594,
+ "gloves": 12363,
+ "glow": 30472,
+ "glow": 10111,
+ "glowing": 18437,
+ "glows": 48107,
+ "glu": 5952,
+ "glu": 32281,
+ "glucose": 34642,
+ "glue": 22103,
+ "glued": 38135,
+ "gluten": 15482,
+ "gluten": 15524,
+ "glutenfree": 16138,
+ "gly": 13027,
+ "glycer": 48914,
+ "gm": 18743,
+ "gm": 5918,
+ "gma": 18155,
+ "gmail": 11119,
+ "gman": 41043,
+ "gman": 36936,
+ "gmb": 35934,
+ "gmb": 31799,
+ "gmbh": 46877,
+ "gmc": 27257,
+ "gmo": 23486,
+ "gms": 36987,
+ "gmt": 13803,
+ "gn": 2455,
+ "gn": 9831,
+ "gna": 23009,
+ "gnation": 45912,
+ "gne": 25407,
+ "gni": 5104,
+ "gnment": 25110,
+ "gno": 23376,
+ "gno": 43686,
+ "gnocchi": 48299,
+ "gnome": 33643,
+ "gnon": 20561,
+ "go": 650,
+ "go": 861,
+ "goa": 14399,
+ "goal": 9003,
+ "goal": 3321,
+ "goalie": 20723,
+ "goalkeeper": 16601,
+ "goals": 3295,
+ "goalscorer": 43547,
+ "goaltender": 44151,
+ "goat": 34082,
+ "goat": 9530,
+ "goats": 18393,
+ "gob": 29559,
+ "gobeavs": 48285,
+ "goblin": 26223,
+ "goblue": 25232,
+ "gobucks": 29175,
+ "gocougs": 34202,
+ "god": 4190,
+ "god": 1731,
+ "godawgs": 40436,
+ "godbless": 46616,
+ "godbless": 44007,
+ "godd": 16589,
+ "goddamn": 28495,
+ "goddard": 37827,
+ "goddess": 10808,
+ "godfather": 26222,
+ "godfrey": 40148,
+ "godis": 38521,
+ "godly": 42438,
+ "gods": 33620,
+ "gods": 10328,
+ "goducks": 35889,
+ "godzilla": 23369,
+ "goe": 22084,
+ "goers": 27784,
+ "goes": 43581,
+ "goes": 2635,
+ "gof": 17537,
+ "goff": 34399,
+ "goftheday": 39360,
+ "gofund": 34445,
+ "gofundme": 34686,
+ "gog": 42949,
+ "goggles": 31027,
+ "gogh": 19697,
+ "gogo": 22688,
+ "gogreen": 36279,
+ "gohawks": 34884,
+ "goi": 24917,
+ "goin": 13939,
+ "going": 25787,
+ "going": 1245,
+ "goku": 29550,
+ "gol": 1537,
+ "gol": 18257,
+ "gola": 41090,
+ "gold": 4999,
+ "gold": 2209,
+ "goldberg": 25161,
+ "goldcoast": 34634,
+ "golden": 10763,
+ "golden": 3878,
+ "goldeng": 20650,
+ "goldenglobes": 26842,
+ "goldfish": 40293,
+ "goldie": 42805,
+ "goldman": 27164,
+ "golds": 30526,
+ "golds": 40283,
+ "goldsmith": 40214,
+ "gole": 41297,
+ "golf": 9096,
+ "golf": 3096,
+ "golfclub": 45742,
+ "golfer": 24579,
+ "golfers": 28441,
+ "golfing": 31379,
+ "goli": 29265,
+ "goliath": 41602,
+ "gom": 7051,
+ "goma": 46198,
+ "gomes": 39128,
+ "gomez": 16433,
+ "gon": 1854,
+ "gon": 3379,
+ "gona": 34835,
+ "gone": 35135,
+ "gone": 3601,
+ "gong": 28486,
+ "gonna": 2562,
+ "gonz": 10587,
+ "gonzaga": 36241,
+ "gonzale": 17512,
+ "gonzales": 31265,
+ "gonzalez": 18198,
+ "goo": 1381,
+ "goo": 17882,
+ "good": 2185,
+ "good": 886,
+ "goodbye": 6968,
+ "goodday": 46284,
+ "goode": 42076,
+ "goodfood": 46844,
+ "goodfriday": 40360,
+ "goodie": 29213,
+ "goodies": 13308,
+ "goodluck": 19718,
+ "goodman": 24146,
+ "goodmorning": 14421,
+ "goodness": 10531,
+ "goodnight": 8540,
+ "goodreads": 31629,
+ "goods": 9340,
+ "goodtimes": 22570,
+ "goodvibes": 43146,
+ "goodwill": 24902,
+ "goodwin": 28080,
+ "goodwood": 30008,
+ "goody": 35937,
+ "goodyear": 42858,
+ "goofy": 26879,
+ "goog": 18581,
+ "google": 12195,
+ "google": 3460,
+ "googled": 40345,
+ "googleplay": 37309,
+ "goon": 15267,
+ "goons": 30440,
+ "goooo": 35876,
+ "goooo": 48957,
+ "goose": 21445,
+ "goose": 13822,
+ "goosebumps": 32254,
+ "gop": 18942,
+ "gop": 6250,
+ "gopack": 46995,
+ "gopackgo": 47719,
+ "gopal": 47268,
+ "gopdebate": 39806,
+ "gopher": 47750,
+ "gopher": 48905,
+ "gophers": 31957,
+ "gopro": 17511,
+ "gor": 1747,
+ "gor": 29827,
+ "gordo": 47707,
+ "gordon": 20485,
+ "gordon": 8244,
+ "gore": 30311,
+ "gore": 17872,
+ "gorg": 46815,
+ "gorge": 35548,
+ "gorge": 20038,
+ "gorgeous": 3241,
+ "gori": 12461,
+ "goria": 43359,
+ "gorilla": 37910,
+ "gorilla": 21994,
+ "gorman": 35741,
+ "goro": 44977,
+ "gory": 7160,
+ "gos": 20517,
+ "gos": 5693,
+ "gosh": 15395,
+ "gosling": 35320,
+ "gosp": 9617,
+ "gospel": 11313,
+ "goss": 39734,
+ "goss": 36924,
+ "gossi": 15684,
+ "gossip": 18963,
+ "got": 10125,
+ "got": 1005,
+ "gota": 36693,
+ "gotcha": 43275,
+ "gote": 49345,
+ "goth": 48465,
+ "goth": 20437,
+ "gotham": 46123,
+ "gotham": 18299,
+ "gothic": 15426,
+ "goti": 9497,
+ "goto": 39715,
+ "gots": 35215,
+ "gott": 5089,
+ "gott": 36466,
+ "gotta": 4633,
+ "gotten": 5889,
+ "gotti": 41881,
+ "gotv": 36089,
+ "gou": 10520,
+ "gou": 36555,
+ "gouache": 43314,
+ "goul": 33187,
+ "gould": 31087,
+ "gour": 13580,
+ "gourmet": 19111,
+ "gov": 4022,
+ "gov": 4564,
+ "gove": 36997,
+ "govegan": 38886,
+ "gover": 10471,
+ "gover": 16759,
+ "govern": 2351,
+ "govern": 32404,
+ "governance": 13386,
+ "governing": 30946,
+ "government": 3149,
+ "governmental": 42609,
+ "governments": 19582,
+ "governor": 17459,
+ "governor": 6630,
+ "governors": 26881,
+ "govin": 42451,
+ "govt": 5345,
+ "govuk": 28830,
+ "gow": 21885,
+ "gow": 33788,
+ "gowan": 31307,
+ "gower": 43448,
+ "gown": 13719,
+ "gowns": 38029,
+ "goyal": 35105,
+ "gp": 19329,
+ "gp": 5051,
+ "gpa": 24098,
+ "gps": 13639,
+ "gpu": 38561,
+ "gq": 40286,
+ "gq": 31324,
+ "gr": 709,
+ "gr": 6062,
+ "gra": 782,
+ "gra": 15276,
+ "grab": 4646,
+ "grabbed": 22856,
+ "grabbing": 26440,
+ "grabs": 17076,
+ "grac": 11323,
+ "grace": 13225,
+ "grace": 5142,
+ "graced": 31894,
+ "graceful": 25242,
+ "graces": 38629,
+ "graci": 11174,
+ "gracias": 16463,
+ "gracie": 23235,
+ "gracing": 37263,
+ "gracious": 29044,
+ "grad": 19869,
+ "grad": 7291,
+ "gradable": 41529,
+ "grade": 45435,
+ "grade": 3394,
+ "graded": 13823,
+ "grader": 23930,
+ "graders": 10930,
+ "grades": 10838,
+ "gradient": 36885,
+ "grading": 19016,
+ "grads": 17811,
+ "gradu": 3230,
+ "gradual": 45210,
+ "gradually": 32192,
+ "graduate": 6675,
+ "graduated": 15128,
+ "graduates": 12236,
+ "graduating": 14819,
+ "graduation": 8060,
+ "grady": 33980,
+ "graeme": 30192,
+ "graf": 46478,
+ "graf": 39765,
+ "graff": 10656,
+ "graffiti": 11676,
+ "graft": 32698,
+ "grafton": 47347,
+ "graham": 19805,
+ "graham": 7711,
+ "grail": 37184,
+ "grain": 44003,
+ "grain": 12109,
+ "grains": 25791,
+ "gral": 25631,
+ "gram": 2949,
+ "gram": 2338,
+ "grammar": 16077,
+ "grammy": 15388,
+ "grammys": 18121,
+ "grams": 6294,
+ "gran": 3892,
+ "gran": 14493,
+ "granada": 31172,
+ "grand": 3058,
+ "grand": 2991,
+ "grandad": 29148,
+ "grandchildren": 36856,
+ "granddaughter": 29460,
+ "grande": 37514,
+ "grande": 10757,
+ "grandes": 36382,
+ "grandfather": 15346,
+ "grandma": 10525,
+ "grandmother": 17469,
+ "grandpa": 14582,
+ "grandparents": 21311,
+ "grandprix": 39358,
+ "grandson": 20766,
+ "grandstand": 43172,
+ "grange": 45027,
+ "grange": 23850,
+ "granger": 42968,
+ "granite": 18813,
+ "grann": 45585,
+ "granny": 22710,
+ "granola": 34271,
+ "grant": 18682,
+ "grant": 5442,
+ "granted": 14156,
+ "granth": 41283,
+ "grants": 15123,
+ "grape": 19131,
+ "grape": 15959,
+ "grapefruit": 28347,
+ "grapes": 18580,
+ "grapevine": 47619,
+ "graph": 1349,
+ "graph": 4407,
+ "graphene": 38387,
+ "grapher": 14987,
+ "graphers": 32088,
+ "graphic": 15653,
+ "graphic": 4245,
+ "graphical": 20878,
+ "graphicdesign": 21907,
+ "graphics": 9492,
+ "graphies": 40164,
+ "graphite": 29447,
+ "graphs": 24670,
+ "graphy": 4897,
+ "grapp": 30843,
+ "gras": 31517,
+ "gras": 17584,
+ "grasp": 34975,
+ "grass": 11584,
+ "grass": 5922,
+ "grasses": 46807,
+ "grasshopper": 48894,
+ "grassi": 42294,
+ "grasso": 34808,
+ "grassroots": 21991,
+ "grassy": 44140,
+ "grat": 9221,
+ "grate": 32463,
+ "grateful": 45659,
+ "grateful": 5730,
+ "grati": 36402,
+ "gratis": 33638,
+ "gratitude": 12614,
+ "grav": 20663,
+ "grave": 16606,
+ "grave": 9981,
+ "gravel": 27054,
+ "graves": 17665,
+ "graveyard": 31176,
+ "gravit": 26150,
+ "gravitational": 45268,
+ "gravity": 47426,
+ "gravity": 15160,
+ "gravy": 21225,
+ "gray": 12703,
+ "gray": 7048,
+ "grays": 46848,
+ "grayson": 45831,
+ "grayson": 25471,
+ "grazi": 42427,
+ "grazie": 38698,
+ "grazing": 29889,
+ "grc": 44069,
+ "gre": 689,
+ "gre": 17878,
+ "grease": 24132,
+ "greasy": 44376,
+ "great": 3265,
+ "great": 830,
+ "greate": 31930,
+ "greater": 32725,
+ "greater": 7033,
+ "greatest": 39080,
+ "greatest": 4153,
+ "greatly": 13978,
+ "greatness": 14189,
+ "greats": 21855,
+ "greaves": 42350,
+ "greco": 39103,
+ "gree": 9987,
+ "gree": 30774,
+ "greece": 6965,
+ "greed": 26147,
+ "greedy": 33301,
+ "greek": 23844,
+ "greek": 6842,
+ "greeks": 35866,
+ "green": 2762,
+ "green": 1901,
+ "greenberg": 46662,
+ "greene": 16383,
+ "greener": 31169,
+ "greenery": 42493,
+ "greenfield": 39924,
+ "greeng": 42077,
+ "greenhouse": 20819,
+ "greening": 48673,
+ "greenland": 27345,
+ "greenpeace": 44755,
+ "greens": 10235,
+ "greensboro": 33436,
+ "greenville": 25156,
+ "greenway": 35205,
+ "greenwich": 18658,
+ "greenwood": 25782,
+ "greer": 34345,
+ "greet": 11042,
+ "greet": 11997,
+ "greeted": 24546,
+ "greeting": 17754,
+ "greetings": 11569,
+ "greets": 25464,
+ "greg": 6894,
+ "greg": 7943,
+ "gregation": 20131,
+ "gregg": 39422,
+ "gregg": 22929,
+ "gregor": 33856,
+ "gregor": 16177,
+ "gregory": 16253,
+ "gren": 13941,
+ "gren": 20119,
+ "grenade": 33679,
+ "grenfell": 42107,
+ "gres": 39670,
+ "gress": 2752,
+ "gret": 30041,
+ "greta": 33443,
+ "gretchen": 45516,
+ "grette": 38774,
+ "grew": 10451,
+ "grey": 9190,
+ "grey": 5046,
+ "greyhound": 27363,
+ "greyhounds": 45718,
+ "greys": 44311,
+ "greysanatomy": 36833,
+ "gri": 2169,
+ "gri": 18484,
+ "grid": 29067,
+ "grid": 9882,
+ "gridi": 41063,
+ "gridiron": 47786,
+ "grids": 46500,
+ "grief": 21058,
+ "grier": 22016,
+ "griev": 36400,
+ "grieving": 42383,
+ "griez": 47962,
+ "griezmann": 48396,
+ "griff": 17855,
+ "griff": 35551,
+ "griffi": 28676,
+ "griffin": 46612,
+ "griffin": 13161,
+ "griffith": 24375,
+ "griffiths": 34182,
+ "gril": 49091,
+ "grill": 44083,
+ "grill": 9519,
+ "grille": 34748,
+ "grilled": 10691,
+ "grilling": 28324,
+ "grills": 39464,
+ "grim": 20383,
+ "grim": 23635,
+ "grime": 37101,
+ "grimes": 25057,
+ "grimm": 27865,
+ "grims": 34861,
+ "grimsby": 41513,
+ "grin": 11033,
+ "grin": 28697,
+ "grinch": 40527,
+ "grind": 25730,
+ "grind": 11810,
+ "grinder": 31733,
+ "grinding": 21541,
+ "gring": 40135,
+ "grip": 15521,
+ "gripping": 34567,
+ "grips": 27819,
+ "gris": 29150,
+ "grit": 22037,
+ "grit": 22087,
+ "grits": 44307,
+ "gritty": 33704,
+ "grizz": 14877,
+ "grizz": 44088,
+ "grizzlies": 25594,
+ "grizzly": 29676,
+ "grl": 48005,
+ "gro": 1464,
+ "gro": 12691,
+ "grocer": 11633,
+ "groceries": 32409,
+ "grocery": 13826,
+ "grom": 45284,
+ "gron": 22345,
+ "groningen": 45639,
+ "groo": 9015,
+ "groom": 39883,
+ "groom": 22813,
+ "grooming": 25575,
+ "groot": 37708,
+ "groove": 39484,
+ "groove": 17680,
+ "grooves": 43954,
+ "groovy": 30143,
+ "gros": 26834,
+ "gros": 32639,
+ "gross": 31080,
+ "gross": 11541,
+ "grosven": 46911,
+ "grote": 47207,
+ "grotto": 45260,
+ "grou": 1582,
+ "groun": 45110,
+ "ground": 9558,
+ "ground": 2461,
+ "groundbreaking": 21006,
+ "grounded": 27799,
+ "grounds": 8454,
+ "groundwater": 39457,
+ "group": 19045,
+ "group": 1771,
+ "groupe": 47654,
+ "groups": 6776,
+ "grouse": 36327,
+ "grove": 31756,
+ "grove": 7463,
+ "grover": 31345,
+ "groves": 27306,
+ "grow": 3179,
+ "grow": 4559,
+ "grower": 44925,
+ "growers": 25689,
+ "growing": 28429,
+ "growing": 4425,
+ "growingup": 43433,
+ "growler": 47096,
+ "grown": 41762,
+ "grown": 7120,
+ "grows": 13352,
+ "growth": 17925,
+ "growth": 4026,
+ "growthhacking": 25963,
+ "grp": 27321,
+ "grt": 28557,
+ "gru": 5957,
+ "grub": 34019,
+ "grue": 42047,
+ "gruesome": 47111,
+ "grum": 45454,
+ "grump": 49015,
+ "grumpy": 23610,
+ "grun": 16203,
+ "grunge": 33745,
+ "gry": 16140,
+ "gry": 5364,
+ "gs": 25818,
+ "gs": 1345,
+ "gsa": 40433,
+ "gsc": 47751,
+ "gshore": 43392,
+ "gsm": 32181,
+ "gsp": 49173,
+ "gst": 22239,
+ "gt": 16151,
+ "gt": 4725,
+ "gta": 14826,
+ "gta": 15338,
+ "gtaonline": 27292,
+ "gtav": 27283,
+ "gti": 39954,
+ "gto": 39071,
+ "gtr": 33407,
+ "gts": 37338,
+ "gtx": 35230,
+ "gu": 700,
+ "gu": 12916,
+ "gua": 23751,
+ "guacam": 37477,
+ "guacamole": 40115,
+ "guad": 22966,
+ "guadal": 46097,
+ "guadalu": 36994,
+ "guadalupe": 38360,
+ "guam": 37325,
+ "guan": 44191,
+ "guan": 42406,
+ "guang": 27019,
+ "guangzhou": 37857,
+ "guar": 4119,
+ "guaran": 9242,
+ "guarantee": 17421,
+ "guaranteed": 14731,
+ "guarantees": 40154,
+ "guard": 30776,
+ "guard": 4901,
+ "guarded": 40602,
+ "guardi": 12008,
+ "guardia": 43628,
+ "guardian": 23713,
+ "guardian": 9498,
+ "guardians": 21479,
+ "guarding": 24966,
+ "guardiola": 32100,
+ "guards": 12810,
+ "guatem": 19423,
+ "guatemala": 21670,
+ "guay": 48591,
+ "guay": 24247,
+ "gubernat": 41400,
+ "gubernatorial": 41618,
+ "gucci": 16779,
+ "gud": 48061,
+ "gud": 22378,
+ "gue": 2030,
+ "gue": 2917,
+ "gued": 38893,
+ "guel": 23146,
+ "guelph": 27660,
+ "guer": 10391,
+ "guern": 29277,
+ "guernsey": 33982,
+ "guerra": 38215,
+ "guerrero": 31967,
+ "guerrilla": 36715,
+ "gues": 39971,
+ "gues": 12601,
+ "guess": 35506,
+ "guess": 3135,
+ "guessed": 28005,
+ "guesses": 30623,
+ "guessing": 21891,
+ "guest": 27349,
+ "guest": 3781,
+ "guests": 6212,
+ "guet": 36797,
+ "guetta": 45904,
+ "guez": 12313,
+ "gug": 31358,
+ "guggen": 35086,
+ "guggenheim": 37135,
+ "gui": 2587,
+ "gui": 25746,
+ "guid": 11437,
+ "guidance": 12508,
+ "guide": 21845,
+ "guide": 3555,
+ "guided": 13194,
+ "guidelines": 16591,
+ "guides": 14375,
+ "guiding": 22759,
+ "guido": 41818,
+ "guil": 5008,
+ "guild": 19755,
+ "guild": 16597,
+ "guildford": 34450,
+ "guildhall": 47224,
+ "guillau": 41123,
+ "guillaume": 45394,
+ "guiller": 33660,
+ "guillermo": 39524,
+ "guilt": 26354,
+ "guilty": 9761,
+ "guin": 13284,
+ "guin": 47863,
+ "guine": 13759,
+ "guinea": 18537,
+ "guinness": 16648,
+ "guire": 18209,
+ "guise": 42024,
+ "guit": 3759,
+ "guitar": 21746,
+ "guitar": 5084,
+ "guitarist": 13035,
+ "guitars": 15023,
+ "guj": 34935,
+ "gujar": 12698,
+ "gujarat": 14714,
+ "guk": 20280,
+ "gul": 5530,
+ "gul": 21350,
+ "gula": 27426,
+ "gular": 34969,
+ "gulf": 22101,
+ "gulf": 11279,
+ "gull": 48764,
+ "gull": 28778,
+ "gulls": 37501,
+ "gully": 46112,
+ "gum": 22041,
+ "gum": 11235,
+ "gumb": 40147,
+ "gumbo": 47126,
+ "gummy": 34276,
+ "gums": 46609,
+ "gun": 2748,
+ "gun": 3496,
+ "guna": 43333,
+ "gundam": 26087,
+ "gundy": 21162,
+ "gunman": 32743,
+ "gunmen": 44738,
+ "gunn": 27473,
+ "gunna": 24002,
+ "gunnar": 45301,
+ "gunner": 35285,
+ "gunners": 37788,
+ "guns": 7591,
+ "gunsense": 44781,
+ "gunshot": 49250,
+ "gunsn": 49028,
+ "gup": 38632,
+ "gup": 47335,
+ "gupta": 15905,
+ "gur": 3218,
+ "gur": 30224,
+ "gura": 46836,
+ "gurgaon": 33240,
+ "guri": 43888,
+ "gurl": 25445,
+ "gurmee": 35482,
+ "gurmeetramrahim": 36549,
+ "guru": 18629,
+ "guru": 10800,
+ "gurudev": 48647,
+ "gus": 8018,
+ "gust": 24629,
+ "gusta": 23024,
+ "gusta": 44196,
+ "gustav": 32062,
+ "gustav": 37921,
+ "gustave": 43170,
+ "gustavo": 45943,
+ "gusto": 37937,
+ "gusts": 20896,
+ "gusty": 27589,
+ "gut": 24780,
+ "gut": 13486,
+ "guter": 44963,
+ "guterres": 48738,
+ "guth": 31696,
+ "guthrie": 33164,
+ "gutier": 32773,
+ "gutierrez": 33739,
+ "guts": 25983,
+ "gutted": 26524,
+ "gutter": 40537,
+ "guwa": 43063,
+ "guwahati": 45045,
+ "guy": 10008,
+ "guy": 2149,
+ "guyana": 45215,
+ "guyen": 28031,
+ "guys": 43588,
+ "guys": 1791,
+ "guyz": 48170,
+ "guzman": 37960,
+ "gv": 15462,
+ "gv": 17336,
+ "gw": 7172,
+ "gw": 15717,
+ "gwen": 32165,
+ "gwen": 24182,
+ "gwin": 43005,
+ "gwy": 32226,
+ "gwyne": 36923,
+ "gx": 40227,
+ "gy": 2168,
+ "gy": 1164,
+ "gya": 43214,
+ "gyan": 43814,
+ "gye": 21728,
+ "gyllen": 49348,
+ "gym": 9902,
+ "gym": 5222,
+ "gymna": 13517,
+ "gymnasium": 42847,
+ "gymnast": 42658,
+ "gymnastics": 20116,
+ "gyn": 39603,
+ "gyne": 45836,
+ "gyp": 40053,
+ "gypsy": 22354,
+ "gypt": 41921,
+ "gz": 45937,
+ "gz": 35841,
+ "gö": 40778,
+ "gü": 31907,
+ "h": 71,
+ "h": 327,
+ "ha": 560,
+ "ha": 1429,
+ "haa": 26814,
+ "haal": 35869,
+ "haan": 36284,
+ "haar": 45247,
+ "haar": 35859,
+ "haas": 27443,
+ "haasan": 26601,
+ "hab": 20573,
+ "hab": 20002,
+ "haban": 46225,
+ "haber": 44737,
+ "habit": 8491,
+ "habit": 17215,
+ "habitat": 11747,
+ "habitats": 35344,
+ "habits": 14540,
+ "habs": 27489,
+ "hac": 20343,
+ "hace": 43623,
+ "haci": 40674,
+ "hack": 6610,
+ "hack": 11182,
+ "hackathon": 25182,
+ "hacked": 19575,
+ "hacker": 22376,
+ "hackers": 21498,
+ "hacking": 12939,
+ "hackney": 48811,
+ "hackney": 24928,
+ "hacks": 19965,
+ "had": 10660,
+ "had": 1100,
+ "hadi": 39058,
+ "hadid": 26415,
+ "hadith": 46907,
+ "hadley": 44995,
+ "hadn": 21480,
+ "hadoop": 43868,
+ "hae": 30723,
+ "hae": 27193,
+ "hafi": 39914,
+ "hag": 26855,
+ "hag": 43207,
+ "hagan": 47489,
+ "hagen": 14664,
+ "hager": 48773,
+ "hagg": 26324,
+ "hague": 28988,
+ "hah": 18108,
+ "hah": 13680,
+ "haha": 1913,
+ "haha": 3060,
+ "hahah": 27253,
+ "hahah": 15441,
+ "hahaha": 4722,
+ "hahahah": 37513,
+ "hahahah": 20096,
+ "hahahaha": 8058,
+ "hahahaha": 9501,
+ "hahahahah": 33334,
+ "hahahahaha": 16347,
+ "hahahahahaha": 26487,
+ "hahahahahahaha": 43653,
+ "hahahahahahahaha": 36126,
+ "hahahha": 49205,
+ "hahn": 35596,
+ "hai": 8734,
+ "hai": 5234,
+ "haider": 42200,
+ "haiku": 19542,
+ "hail": 15272,
+ "hail": 8634,
+ "hailed": 44604,
+ "hailey": 27703,
+ "hailing": 47288,
+ "hails": 32571,
+ "hailstate": 35063,
+ "hain": 23861,
+ "hair": 4658,
+ "hair": 2225,
+ "haircare": 43682,
+ "haircut": 14711,
+ "hairdresser": 47468,
+ "haired": 27202,
+ "hairs": 27951,
+ "hairstyle": 22324,
+ "hairstyles": 40627,
+ "hairy": 26513,
+ "haiti": 17368,
+ "haitian": 37577,
+ "haj": 27885,
+ "haj": 43191,
+ "haji": 41889,
+ "hajj": 35576,
+ "hak": 25142,
+ "hak": 40671,
+ "haka": 44011,
+ "hake": 41663,
+ "hal": 1296,
+ "hal": 8708,
+ "hala": 25918,
+ "halal": 34216,
+ "halam": 29061,
+ "halamadrid": 31132,
+ "halder": 32201,
+ "hale": 37038,
+ "hale": 14701,
+ "halen": 39204,
+ "halep": 49017,
+ "haley": 37330,
+ "haley": 16839,
+ "half": 7453,
+ "half": 2349,
+ "halftime": 13742,
+ "halfway": 16736,
+ "hali": 9860,
+ "hali": 43030,
+ "halibut": 49030,
+ "halifax": 13411,
+ "hall": 6850,
+ "hall": 2140,
+ "halla": 29569,
+ "halle": 27763,
+ "halle": 32239,
+ "hallelujah": 36993,
+ "halli": 32665,
+ "hallmark": 31040,
+ "hallmark": 32053,
+ "hallmarkchannel": 36840,
+ "hallo": 3463,
+ "halloffame": 48578,
+ "halloween": 28537,
+ "halloween": 3739,
+ "halls": 18052,
+ "hallucin": 35385,
+ "hallway": 26845,
+ "halo": 33331,
+ "halo": 11918,
+ "halsey": 34256,
+ "halt": 25640,
+ "halter": 47194,
+ "halton": 45445,
+ "ham": 1522,
+ "ham": 1714,
+ "hama": 17944,
+ "hamas": 14818,
+ "hamburg": 18409,
+ "hamburger": 33928,
+ "hamid": 32377,
+ "hamil": 6725,
+ "hamill": 45784,
+ "hamill": 48729,
+ "hamillhimself": 47324,
+ "hamilton": 22448,
+ "hamilton": 7684,
+ "hamlet": 27722,
+ "hamlin": 49326,
+ "hamm": 46110,
+ "hammer": 15331,
+ "hammer": 9401,
+ "hammered": 37251,
+ "hammers": 35649,
+ "hammersmith": 42127,
+ "hammock": 33682,
+ "hammond": 21761,
+ "hamont": 18518,
+ "hamp": 6665,
+ "hamper": 27692,
+ "hampshire": 16006,
+ "hampstead": 37340,
+ "hampton": 36582,
+ "hampton": 12285,
+ "hamptons": 42415,
+ "hamr": 47979,
+ "hamradio": 36712,
+ "hams": 25619,
+ "hamster": 33313,
+ "hamstring": 39990,
+ "hamza": 45762,
+ "han": 1545,
+ "han": 3565,
+ "hana": 16801,
+ "hand": 1722,
+ "hand": 2463,
+ "handbag": 22654,
+ "handbags": 35667,
+ "handball": 27988,
+ "handbook": 25147,
+ "handcrafted": 22185,
+ "handed": 10881,
+ "handedly": 48656,
+ "handel": 40072,
+ "handful": 23725,
+ "handheld": 26812,
+ "handic": 17812,
+ "handicap": 27063,
+ "handicapp": 42349,
+ "handing": 19196,
+ "handle": 43681,
+ "handle": 7245,
+ "handled": 26824,
+ "handler": 29097,
+ "handles": 22124,
+ "handling": 14071,
+ "handmade": 18054,
+ "handmade": 6737,
+ "handmadehour": 25724,
+ "handover": 46922,
+ "hands": 3500,
+ "handshake": 38418,
+ "handsome": 7438,
+ "handwriting": 29986,
+ "handwritten": 35192,
+ "handy": 13479,
+ "hane": 28411,
+ "hang": 3351,
+ "hang": 5592,
+ "hangar": 33439,
+ "hanged": 40807,
+ "hanger": 28905,
+ "hangin": 22670,
+ "hanging": 4850,
+ "hangout": 17572,
+ "hangover": 20755,
+ "hangs": 21785,
+ "hani": 39944,
+ "hani": 18374,
+ "hank": 35993,
+ "hank": 17655,
+ "hanks": 29943,
+ "hanley": 47284,
+ "hann": 5584,
+ "hanna": 10075,
+ "hannah": 18622,
+ "hannah": 9142,
+ "hannel": 43477,
+ "hanni": 19493,
+ "hannibal": 25149,
+ "hannity": 24569,
+ "hannover": 39976,
+ "hanoi": 36134,
+ "hanover": 33246,
+ "hans": 35172,
+ "hans": 16628,
+ "hansen": 19729,
+ "hanson": 24602,
+ "hant": 40641,
+ "hanuk": 32774,
+ "hanukkah": 34247,
+ "hanuman": 46975,
+ "hao": 27184,
+ "hap": 44981,
+ "hap": 47988,
+ "happ": 784,
+ "happen": 21486,
+ "happen": 4506,
+ "happened": 4402,
+ "happening": 4284,
+ "happeningnow": 43107,
+ "happenings": 41998,
+ "happens": 4988,
+ "happier": 14118,
+ "happiest": 13811,
+ "happily": 17316,
+ "happiness": 5096,
+ "happy": 2952,
+ "happy": 900,
+ "happybirthday": 9651,
+ "happybirthday": 12207,
+ "happydays": 25106,
+ "happye": 33922,
+ "happyeaster": 38745,
+ "happyfathersday": 43534,
+ "happyfriday": 33340,
+ "happyhalloween": 28750,
+ "happyholidays": 32186,
+ "happyhour": 32036,
+ "happymonday": 47364,
+ "happymothersday": 42425,
+ "happynewyear": 18655,
+ "happythanksgiving": 40593,
+ "happyvalentinesday": 42403,
+ "haps": 9114,
+ "haq": 32445,
+ "har": 915,
+ "har": 5888,
+ "hara": 10367,
+ "haram": 35732,
+ "haram": 22950,
+ "haran": 27921,
+ "harare": 43562,
+ "haras": 26644,
+ "harass": 16481,
+ "harassed": 43067,
+ "harassment": 16641,
+ "harat": 28984,
+ "harb": 5856,
+ "harbaugh": 45220,
+ "harbor": 40686,
+ "harbor": 10202,
+ "harbour": 35430,
+ "harbour": 10011,
+ "harcourt": 48093,
+ "hard": 3312,
+ "hard": 1626,
+ "hardcover": 31123,
+ "harden": 27350,
+ "harder": 12274,
+ "hardest": 15258,
+ "hardin": 43802,
+ "harding": 24382,
+ "hardly": 17363,
+ "hardro": 28126,
+ "hardrock": 48365,
+ "hardrock": 40739,
+ "hards": 44048,
+ "hardship": 45085,
+ "hardt": 17922,
+ "hardware": 11957,
+ "hardwell": 45572,
+ "hardwick": 46864,
+ "hardwood": 28167,
+ "hardwork": 42554,
+ "hardwork": 27404,
+ "hardworking": 28095,
+ "hardworkpaysoff": 49193,
+ "hardy": 48179,
+ "hardy": 14113,
+ "hare": 27903,
+ "hare": 18464,
+ "harga": 39738,
+ "hari": 25472,
+ "hari": 8981,
+ "harlan": 49133,
+ "harle": 29096,
+ "harlem": 17771,
+ "harley": 24702,
+ "harley": 13632,
+ "harleydavidson": 39183,
+ "harlow": 34113,
+ "harm": 16656,
+ "harm": 14452,
+ "harman": 42434,
+ "harmed": 39637,
+ "harmful": 21725,
+ "harmless": 44369,
+ "harmon": 10828,
+ "harmon": 28729,
+ "harmony": 10785,
+ "harms": 46703,
+ "harne": 43323,
+ "harness": 23205,
+ "harold": 16917,
+ "harp": 27339,
+ "harper": 31288,
+ "harper": 12634,
+ "harri": 6639,
+ "harrier": 37372,
+ "harriet": 27154,
+ "harrington": 34340,
+ "harris": 25356,
+ "harris": 6925,
+ "harrisburg": 40590,
+ "harrison": 34389,
+ "harrison": 10540,
+ "harro": 18939,
+ "harrogate": 30842,
+ "harrow": 38807,
+ "harry": 11094,
+ "harry": 3600,
+ "harrypotter": 23375,
+ "harsh": 30596,
+ "harsh": 16944,
+ "hart": 9335,
+ "hart": 7752,
+ "hartford": 23434,
+ "harth": 35619,
+ "hartle": 47482,
+ "hartley": 31268,
+ "hartman": 43294,
+ "haru": 35099,
+ "harvard": 28118,
+ "harvard": 12848,
+ "harve": 6405,
+ "harvest": 44495,
+ "harvest": 8971,
+ "harvested": 35899,
+ "harvesting": 26674,
+ "harvey": 33289,
+ "harvey": 9586,
+ "harvick": 46983,
+ "haryana": 27661,
+ "has": 13855,
+ "has": 791,
+ "hasan": 30049,
+ "hasbro": 37405,
+ "hash": 6338,
+ "hash": 19199,
+ "hashi": 41831,
+ "hashmi": 35852,
+ "hashtag": 34015,
+ "hashtag": 9238,
+ "hashtags": 23514,
+ "haskell": 48550,
+ "hasn": 9143,
+ "hass": 9298,
+ "hassan": 15829,
+ "hassee": 37117,
+ "hassel": 32204,
+ "hassle": 35762,
+ "hast": 18146,
+ "hasta": 36623,
+ "hastings": 22035,
+ "hat": 3447,
+ "hat": 3801,
+ "hatch": 24202,
+ "hatch": 17809,
+ "hatchback": 42348,
+ "hatched": 42158,
+ "hate": 23546,
+ "hate": 3753,
+ "hated": 21298,
+ "hateful": 36418,
+ "hater": 36917,
+ "haters": 14027,
+ "hates": 14957,
+ "hatfield": 38448,
+ "hath": 27894,
+ "hath": 34416,
+ "hathaway": 31801,
+ "hati": 26045,
+ "hating": 25668,
+ "hatred": 19046,
+ "hats": 9812,
+ "hatt": 8747,
+ "hatton": 44861,
+ "hau": 5152,
+ "hauer": 48751,
+ "haul": 23743,
+ "haul": 12332,
+ "hauled": 46620,
+ "hauling": 43132,
+ "haun": 9676,
+ "haunt": 31039,
+ "haunted": 14944,
+ "haunting": 24034,
+ "haunts": 48035,
+ "haus": 41755,
+ "haus": 16478,
+ "hausen": 33338,
+ "hauser": 46586,
+ "haute": 28854,
+ "hav": 13443,
+ "hav": 20447,
+ "havan": 36304,
+ "havana": 23357,
+ "havas": 46261,
+ "have": 18053,
+ "have": 720,
+ "haven": 33074,
+ "haven": 3871,
+ "havent": 29130,
+ "haver": 27876,
+ "haves": 49088,
+ "havin": 31937,
+ "having": 1977,
+ "havoc": 24447,
+ "haw": 2788,
+ "haw": 26954,
+ "hawa": 6067,
+ "hawa": 46278,
+ "hawai": 15800,
+ "hawaii": 32413,
+ "hawaii": 8265,
+ "hawaiian": 17734,
+ "hawan": 27765,
+ "hawk": 14704,
+ "hawk": 8218,
+ "hawke": 38178,
+ "hawker": 39051,
+ "hawkeye": 38666,
+ "hawkeyes": 34266,
+ "hawking": 33437,
+ "hawkins": 19740,
+ "hawks": 44806,
+ "hawks": 5841,
+ "hawthorn": 45372,
+ "hawthorne": 36730,
+ "hay": 4871,
+ "hay": 11367,
+ "haya": 41325,
+ "hayat": 49360,
+ "hayden": 19806,
+ "haydn": 48207,
+ "haye": 36583,
+ "hayes": 13555,
+ "hayley": 39986,
+ "hayley": 22204,
+ "haynes": 30496,
+ "hays": 41524,
+ "hayward": 29400,
+ "haz": 5040,
+ "haz": 39921,
+ "hazard": 26174,
+ "hazard": 15178,
+ "hazardous": 27102,
+ "hazards": 30639,
+ "haze": 22785,
+ "hazel": 19838,
+ "hazel": 21882,
+ "hazelnut": 35816,
+ "hazi": 22740,
+ "hazmat": 48887,
+ "hazrat": 45775,
+ "hazy": 32655,
+ "hb": 6854,
+ "hb": 12576,
+ "hbcu": 40008,
+ "hbd": 25277,
+ "hbd": 13594,
+ "hbo": 15252,
+ "hc": 15831,
+ "hc": 7821,
+ "hcs": 46850,
+ "hd": 11601,
+ "hd": 4414,
+ "hdd": 40508,
+ "hdmi": 33302,
+ "hdr": 28065,
+ "he": 651,
+ "he": 797,
+ "hea": 27150,
+ "hea": 32790,
+ "head": 1603,
+ "head": 1375,
+ "headache": 23849,
+ "headaches": 38025,
+ "headband": 28556,
+ "headed": 6153,
+ "header": 11077,
+ "heading": 4409,
+ "headless": 45219,
+ "headlights": 42422,
+ "headline": 10891,
+ "headliner": 38880,
+ "headlines": 14706,
+ "headlining": 26971,
+ "headphone": 37524,
+ "headphones": 14906,
+ "headquarters": 13041,
+ "heads": 5174,
+ "headset": 23883,
+ "headshot": 34890,
+ "heal": 1231,
+ "heal": 13833,
+ "healed": 31456,
+ "healer": 38328,
+ "healey": 38985,
+ "healing": 9295,
+ "heals": 32384,
+ "health": 2145,
+ "health": 1728,
+ "healthand": 43704,
+ "healthcare": 42500,
+ "healthcare": 6023,
+ "healthier": 18242,
+ "healthtech": 42694,
+ "healthy": 10330,
+ "healthy": 3782,
+ "healthye": 31532,
+ "healthyeating": 33761,
+ "healthyfood": 39996,
+ "healthylifestyle": 46254,
+ "healthyliving": 27293,
+ "healy": 34299,
+ "heap": 34781,
+ "heaps": 44446,
+ "hear": 2749,
+ "hear": 2584,
+ "heard": 4063,
+ "hearing": 46353,
+ "hearing": 5541,
+ "hearings": 33175,
+ "hearn": 36613,
+ "hears": 25395,
+ "heart": 4975,
+ "heart": 1936,
+ "heartbeat": 29154,
+ "heartbreak": 29281,
+ "heartbreaking": 21322,
+ "heartbroken": 35383,
+ "hearted": 21679,
+ "heartfelt": 22904,
+ "hearth": 31563,
+ "hearthstone": 34054,
+ "hearti": 29345,
+ "hearties": 44572,
+ "heartland": 31923,
+ "heartless": 47022,
+ "heartnews": 40426,
+ "hearts": 5516,
+ "heartw": 30002,
+ "heartwarming": 34080,
+ "hearty": 26994,
+ "heat": 12175,
+ "heat": 4403,
+ "heated": 17057,
+ "heater": 23246,
+ "heath": 12794,
+ "heath": 11719,
+ "heather": 20230,
+ "heather": 12470,
+ "heathrow": 24171,
+ "heating": 12478,
+ "heaton": 34557,
+ "heats": 36106,
+ "heatwave": 25726,
+ "heav": 2409,
+ "heaven": 15520,
+ "heaven": 5545,
+ "heavenly": 19117,
+ "heavens": 26026,
+ "heavier": 31253,
+ "heaviest": 33268,
+ "heavily": 14123,
+ "heavy": 12048,
+ "heavy": 4200,
+ "heavymetal": 39804,
+ "heavyweight": 17448,
+ "heb": 24700,
+ "heb": 34515,
+ "hebdo": 41817,
+ "hebrew": 27298,
+ "hebrides": 45121,
+ "hebron": 45725,
+ "hec": 18932,
+ "heck": 22985,
+ "heck": 14427,
+ "hectares": 44162,
+ "hectic": 37245,
+ "hector": 25852,
+ "hed": 18271,
+ "hedge": 16229,
+ "hedge": 20294,
+ "hedgehog": 21940,
+ "hedges": 41345,
+ "hee": 18364,
+ "hee": 15773,
+ "heechul": 42487,
+ "heed": 15118,
+ "heel": 33646,
+ "heel": 16861,
+ "heels": 10909,
+ "heem": 30061,
+ "heer": 40473,
+ "hef": 29473,
+ "heff": 48756,
+ "hefty": 48584,
+ "heg": 41995,
+ "heh": 25834,
+ "hehe": 48723,
+ "hehe": 10658,
+ "hehehe": 24138,
+ "hei": 6101,
+ "hei": 29051,
+ "heidel": 42927,
+ "heidelberg": 48445,
+ "heidi": 44860,
+ "heidi": 23867,
+ "heifer": 48219,
+ "heigh": 43883,
+ "height": 10788,
+ "heights": 8418,
+ "heim": 10931,
+ "heim": 9768,
+ "heimer": 39517,
+ "hein": 15487,
+ "hein": 43206,
+ "heine": 28742,
+ "heineken": 36874,
+ "heinrich": 47877,
+ "heinz": 32359,
+ "heir": 27083,
+ "heir": 34007,
+ "heirloom": 34232,
+ "heirs": 43834,
+ "heis": 21849,
+ "heisman": 34537,
+ "heist": 31035,
+ "heit": 37255,
+ "hel": 919,
+ "hel": 11579,
+ "hela": 48212,
+ "held": 4042,
+ "hele": 46129,
+ "helen": 17576,
+ "helen": 11291,
+ "helena": 23109,
+ "helene": 41591,
+ "helens": 45940,
+ "heli": 33874,
+ "heli": 40183,
+ "helicop": 10035,
+ "helicopter": 11956,
+ "helicopters": 26922,
+ "helium": 46505,
+ "helix": 35247,
+ "hell": 8410,
+ "hell": 4141,
+ "hella": 19800,
+ "hellboy": 48428,
+ "helle": 48600,
+ "helle": 46968,
+ "hellenic": 42544,
+ "heller": 44464,
+ "hello": 12887,
+ "hello": 3306,
+ "hells": 47989,
+ "helly": 48690,
+ "helm": 47970,
+ "helm": 19520,
+ "helmet": 11122,
+ "helmets": 21843,
+ "help": 8641,
+ "help": 1318,
+ "helped": 4845,
+ "helper": 29321,
+ "helpers": 36316,
+ "helpful": 12695,
+ "helping": 3875,
+ "helpless": 47638,
+ "helpline": 43101,
+ "helps": 5144,
+ "helsin": 17842,
+ "helsinki": 19626,
+ "hem": 20270,
+ "hem": 11148,
+ "hemi": 14256,
+ "hemi": 46856,
+ "heming": 30819,
+ "hemingway": 33470,
+ "hemisphere": 32767,
+ "hemmings": 34882,
+ "hemo": 43788,
+ "hemp": 28225,
+ "hemp": 18467,
+ "hems": 32451,
+ "hemsworth": 39428,
+ "hen": 2385,
+ "hen": 8047,
+ "hence": 23640,
+ "hend": 11560,
+ "hender": 49248,
+ "henderson": 14348,
+ "hendrick": 45296,
+ "hendricks": 37588,
+ "hendrix": 23605,
+ "henge": 33104,
+ "henley": 27853,
+ "henna": 39455,
+ "hennessy": 42667,
+ "henri": 19431,
+ "henri": 21610,
+ "henrik": 35772,
+ "henry": 16018,
+ "henry": 5508,
+ "hens": 31742,
+ "henson": 32935,
+ "hep": 17724,
+ "hep": 48791,
+ "hepat": 23767,
+ "hepatitis": 32169,
+ "hepburn": 26348,
+ "her": 1223,
+ "her": 899,
+ "hera": 38724,
+ "heral": 37809,
+ "herald": 27625,
+ "herald": 12851,
+ "herb": 26116,
+ "herb": 15302,
+ "herbal": 21868,
+ "herbali": 44087,
+ "herbalife": 48364,
+ "herbert": 19935,
+ "herbs": 17320,
+ "hercules": 26539,
+ "herd": 36142,
+ "herd": 18589,
+ "here": 9134,
+ "here": 763,
+ "hered": 47976,
+ "hereford": 35543,
+ "heres": 13566,
+ "hereto": 47673,
+ "heri": 31392,
+ "herit": 4720,
+ "heritag": 38273,
+ "heritage": 20962,
+ "heritage": 5455,
+ "herman": 31890,
+ "herman": 21568,
+ "hermann": 40942,
+ "hermes": 34563,
+ "hermi": 35265,
+ "hermione": 45502,
+ "hermit": 43953,
+ "hermitage": 47706,
+ "hermo": 40967,
+ "hermosa": 42531,
+ "hern": 30571,
+ "hern": 43576,
+ "hernandez": 17707,
+ "hero": 7338,
+ "hero": 3756,
+ "heroes": 38010,
+ "heroes": 5506,
+ "heroic": 24255,
+ "heroin": 23841,
+ "heroine": 27420,
+ "heron": 22593,
+ "heros": 37642,
+ "herr": 38537,
+ "herrera": 27755,
+ "herring": 30211,
+ "hers": 25359,
+ "herself": 9207,
+ "hersh": 20379,
+ "hershey": 29734,
+ "hert": 26744,
+ "hertfordshire": 41070,
+ "herts": 35784,
+ "herty": 23454,
+ "hertz": 49383,
+ "hes": 30553,
+ "hes": 12784,
+ "hesit": 23933,
+ "hesitate": 34967,
+ "hess": 41888,
+ "hester": 31105,
+ "het": 37527,
+ "het": 19678,
+ "hetero": 26405,
+ "heu": 20105,
+ "heughan": 32298,
+ "hew": 48141,
+ "hew": 43051,
+ "hewitt": 28871,
+ "hex": 16255,
+ "hex": 31241,
+ "hey": 10759,
+ "hey": 2189,
+ "hez": 34591,
+ "hezbollah": 37636,
+ "hf": 26606,
+ "hf": 20603,
+ "hfx": 47297,
+ "hg": 23986,
+ "hg": 26237,
+ "hgtv": 47657,
+ "hh": 3280,
+ "hh": 5180,
+ "hhh": 8281,
+ "hhhh": 19391,
+ "hhhh": 13121,
+ "hhhhh": 24246,
+ "hhhhhh": 37278,
+ "hhs": 27006,
+ "hi": 677,
+ "hi": 1883,
+ "hia": 20672,
+ "hiatus": 27823,
+ "hib": 15922,
+ "hiber": 38799,
+ "hibis": 36226,
+ "hibiscus": 36460,
+ "hibition": 24658,
+ "hibs": 42814,
+ "hic": 3549,
+ "hic": 38079,
+ "hick": 14813,
+ "hickman": 49148,
+ "hickory": 29905,
+ "hicks": 23429,
+ "hid": 15552,
+ "hid": 14451,
+ "hidalgo": 47464,
+ "hidden": 28305,
+ "hidden": 7029,
+ "hiddleston": 31444,
+ "hide": 17725,
+ "hide": 9379,
+ "hideous": 46588,
+ "hides": 30800,
+ "hiding": 11371,
+ "hie": 15763,
+ "hier": 23433,
+ "hier": 29913,
+ "hierarchy": 44442,
+ "hifi": 38168,
+ "hig": 38108,
+ "higgins": 21783,
+ "high": 1487,
+ "high": 1400,
+ "higher": 5321,
+ "highered": 27072,
+ "highest": 5317,
+ "highland": 32244,
+ "highland": 16062,
+ "highlander": 46251,
+ "highlanders": 40445,
+ "highlands": 16883,
+ "highlight": 8264,
+ "highlighted": 22252,
+ "highlighter": 45460,
+ "highlighting": 17344,
+ "highlights": 6173,
+ "highly": 5302,
+ "highness": 38694,
+ "highs": 15144,
+ "highschool": 23102,
+ "highway": 45344,
+ "highway": 7620,
+ "highways": 28007,
+ "higu": 39115,
+ "hihi": 36240,
+ "hii": 42315,
+ "hijab": 31407,
+ "hika": 41356,
+ "hikari": 44624,
+ "hike": 9404,
+ "hiked": 36471,
+ "hiker": 40947,
+ "hikers": 46090,
+ "hikes": 27076,
+ "hiking": 9118,
+ "hiko": 48708,
+ "hil": 3508,
+ "hil": 17927,
+ "hila": 38837,
+ "hilar": 37337,
+ "hilari": 7784,
+ "hilarious": 8358,
+ "hilariously": 43476,
+ "hilary": 45898,
+ "hilary": 25415,
+ "hilde": 45382,
+ "hill": 3671,
+ "hill": 2682,
+ "hillary": 13257,
+ "hillary": 7074,
+ "hillaryclinton": 15357,
+ "hilli": 32513,
+ "hills": 24178,
+ "hills": 5289,
+ "hillsborough": 32157,
+ "hillside": 37194,
+ "hilltop": 45858,
+ "hilly": 32483,
+ "hilton": 33621,
+ "hilton": 14012,
+ "him": 4128,
+ "him": 1269,
+ "himach": 29132,
+ "himachal": 35461,
+ "himalay": 17552,
+ "himalayan": 30318,
+ "himalayas": 32872,
+ "hime": 45892,
+ "himself": 4530,
+ "himss": 41730,
+ "hin": 1676,
+ "hin": 37930,
+ "hina": 40571,
+ "hinakhan": 45518,
+ "hinch": 49320,
+ "hind": 34460,
+ "hind": 23293,
+ "hindi": 14967,
+ "hinds": 47859,
+ "hindu": 17587,
+ "hindu": 12053,
+ "hinduism": 40592,
+ "hindus": 25701,
+ "hindustan": 46553,
+ "hines": 37462,
+ "hing": 37968,
+ "hini": 33564,
+ "hino": 45343,
+ "hint": 11868,
+ "hinton": 47165,
+ "hints": 20594,
+ "hio": 32897,
+ "hip": 11725,
+ "hip": 6584,
+ "hipho": 8819,
+ "hiphop": 26598,
+ "hiphop": 10914,
+ "hipp": 13607,
+ "hippie": 28637,
+ "hippo": 28398,
+ "hippo": 36729,
+ "hips": 30191,
+ "hipstamatic": 31002,
+ "hipster": 19987,
+ "hipsters": 48265,
+ "hir": 4959,
+ "hir": 14728,
+ "hira": 42577,
+ "hire": 32356,
+ "hire": 8243,
+ "hired": 17602,
+ "hires": 24133,
+ "hiring": 7835,
+ "hiro": 17396,
+ "hiro": 20588,
+ "hiroshima": 33867,
+ "hirsch": 46967,
+ "his": 15211,
+ "his": 787,
+ "hism": 23502,
+ "hispan": 16843,
+ "hispanic": 22676,
+ "hist": 21710,
+ "hist": 13779,
+ "histo": 33479,
+ "histor": 2993,
+ "historia": 46010,
+ "historian": 20697,
+ "historians": 35200,
+ "historic": 30195,
+ "historic": 5726,
+ "historical": 34154,
+ "historical": 8039,
+ "historically": 30445,
+ "histories": 34736,
+ "history": 11142,
+ "history": 1695,
+ "historymonth": 19356,
+ "historyof": 35905,
+ "hit": 5453,
+ "hit": 2341,
+ "hitch": 22937,
+ "hitch": 36203,
+ "hitler": 16518,
+ "hitman": 33290,
+ "hits": 4712,
+ "hitter": 23538,
+ "hitters": 39724,
+ "hitting": 7957,
+ "hiv": 44410,
+ "hiv": 11018,
+ "hive": 38162,
+ "hive": 18521,
+ "hiya": 42393,
+ "hk": 22648,
+ "hk": 12307,
+ "hl": 8297,
+ "hl": 5956,
+ "hle": 32389,
+ "hler": 35418,
+ "hm": 17913,
+ "hm": 7631,
+ "hmm": 13725,
+ "hmmm": 17032,
+ "hmmmm": 34598,
+ "hms": 14625,
+ "hmu": 21630,
+ "hmv": 49288,
+ "hn": 22905,
+ "hn": 7478,
+ "hns": 48412,
+ "ho": 606,
+ "ho": 2971,
+ "hoa": 37517,
+ "hoar": 31628,
+ "hoax": 33438,
+ "hob": 18212,
+ "hobart": 31646,
+ "hobb": 16175,
+ "hobbies": 36370,
+ "hobbit": 23207,
+ "hobbs": 34343,
+ "hobby": 41120,
+ "hobby": 17557,
+ "hobo": 34613,
+ "hobo": 41334,
+ "hoboken": 41568,
+ "hoc": 35880,
+ "hoch": 43772,
+ "hock": 34914,
+ "hock": 46574,
+ "hockey": 16499,
+ "hockey": 4111,
+ "hoco": 34771,
+ "hod": 31062,
+ "hodg": 23660,
+ "hodge": 40585,
+ "hodges": 35061,
+ "hodgson": 37044,
+ "hoe": 32502,
+ "hoe": 11262,
+ "hoek": 40073,
+ "hoes": 21164,
+ "hof": 20186,
+ "hof": 12789,
+ "hofer": 38654,
+ "hoff": 32860,
+ "hoff": 22751,
+ "hofficial": 41949,
+ "hoffman": 22026,
+ "hog": 12075,
+ "hog": 13255,
+ "hogan": 19757,
+ "hogg": 42005,
+ "hogs": 23242,
+ "hogwarts": 29168,
+ "hoh": 43947,
+ "hoi": 39295,
+ "hok": 26942,
+ "hok": 47167,
+ "hokies": 35168,
+ "hokkaido": 49145,
+ "hol": 1187,
+ "hol": 7349,
+ "hola": 28724,
+ "hold": 36496,
+ "hold": 3254,
+ "holden": 21869,
+ "holder": 7862,
+ "holders": 10074,
+ "holding": 5050,
+ "holdings": 24832,
+ "holds": 7286,
+ "hole": 47242,
+ "hole": 5341,
+ "holes": 11266,
+ "holi": 2093,
+ "holi": 21926,
+ "holic": 16348,
+ "holics": 29782,
+ "holiday": 13168,
+ "holiday": 2878,
+ "holidays": 5372,
+ "holiness": 37259,
+ "holistic": 26300,
+ "holl": 27699,
+ "holla": 26500,
+ "holland": 31608,
+ "holland": 9978,
+ "hollande": 47690,
+ "holler": 49047,
+ "holli": 24019,
+ "holliday": 41624,
+ "hollow": 41221,
+ "hollow": 16691,
+ "holloway": 29435,
+ "holly": 12731,
+ "holly": 11923,
+ "hollyo": 41525,
+ "hollyoaks": 43352,
+ "hollywood": 24655,
+ "hollywood": 5518,
+ "holm": 34758,
+ "holm": 12739,
+ "holme": 46149,
+ "holmes": 12756,
+ "holo": 10317,
+ "holocau": 14688,
+ "holocaust": 16476,
+ "hols": 33344,
+ "holt": 18868,
+ "holtz": 44743,
+ "holy": 13910,
+ "holy": 4874,
+ "hom": 906,
+ "hom": 47397,
+ "homa": 9557,
+ "homage": 17746,
+ "home": 2143,
+ "home": 1137,
+ "homebrew": 35046,
+ "homec": 33869,
+ "homecoming": 9008,
+ "homedecor": 15695,
+ "homedepot": 38707,
+ "homegrown": 32554,
+ "homeitems": 42972,
+ "homeland": 21633,
+ "homeless": 18403,
+ "homeless": 9661,
+ "homelessness": 19851,
+ "homemade": 7889,
+ "homeof": 48856,
+ "homeowner": 37267,
+ "homeowners": 29882,
+ "homepage": 29828,
+ "homer": 29307,
+ "homer": 16931,
+ "homers": 38333,
+ "homes": 19480,
+ "homes": 5416,
+ "homeschool": 40994,
+ "homestead": 32609,
+ "homeswee": 46298,
+ "hometown": 12238,
+ "homework": 12495,
+ "homicide": 21520,
+ "homie": 12540,
+ "homies": 18893,
+ "homme": 26193,
+ "homo": 18129,
+ "homo": 30504,
+ "homophobia": 37875,
+ "homophobic": 40975,
+ "homosexual": 44288,
+ "homosexuality": 46720,
+ "homs": 45413,
+ "hon": 1279,
+ "hon": 10296,
+ "honda": 8553,
+ "honduras": 29715,
+ "hone": 38640,
+ "honest": 7814,
+ "honest": 9602,
+ "honestly": 9155,
+ "honesty": 24939,
+ "honey": 9843,
+ "honey": 6406,
+ "honeycomb": 48583,
+ "honeymoon": 22527,
+ "hong": 12144,
+ "hong": 8598,
+ "hongkong": 16659,
+ "honi": 17918,
+ "honolulu": 28096,
+ "honor": 9206,
+ "honor": 3402,
+ "honorable": 19498,
+ "honorary": 15675,
+ "honore": 25868,
+ "honored": 5494,
+ "honoree": 38993,
+ "honorees": 43012,
+ "honoring": 10771,
+ "honors": 10248,
+ "honour": 8240,
+ "honourable": 29855,
+ "honoured": 11945,
+ "honouring": 37754,
+ "honours": 22558,
+ "hoo": 2300,
+ "hoo": 7920,
+ "hood": 18681,
+ "hood": 3222,
+ "hooded": 33631,
+ "hoodie": 13444,
+ "hoodies": 25974,
+ "hoods": 16664,
+ "hoof": 44555,
+ "hook": 30488,
+ "hook": 10395,
+ "hookah": 34214,
+ "hooked": 18138,
+ "hookem": 31465,
+ "hooker": 37891,
+ "hooking": 35240,
+ "hooks": 25068,
+ "hooligans": 48176,
+ "hoon": 21368,
+ "hooo": 44538,
+ "hoop": 31516,
+ "hoop": 19573,
+ "hooper": 35221,
+ "hoops": 9351,
+ "hoor": 22155,
+ "hooray": 24940,
+ "hoos": 46462,
+ "hoosier": 48886,
+ "hoosiers": 42780,
+ "hoot": 29164,
+ "hoover": 25691,
+ "hop": 10848,
+ "hop": 5833,
+ "hope": 5263,
+ "hope": 1683,
+ "hoped": 30628,
+ "hopeful": 21453,
+ "hopefully": 7602,
+ "hopeless": 35586,
+ "hopes": 10018,
+ "hoping": 7207,
+ "hopkins": 17821,
+ "hopp": 48839,
+ "hopped": 34220,
+ "hopper": 21748,
+ "hopping": 27606,
+ "hoppy": 38359,
+ "hops": 21137,
+ "hor": 1407,
+ "hor": 33847,
+ "hora": 26013,
+ "horace": 39282,
+ "horan": 26857,
+ "horde": 44947,
+ "hore": 15380,
+ "horiz": 8144,
+ "horizon": 17924,
+ "horizon": 11920,
+ "horizons": 29685,
+ "horizontal": 25775,
+ "hormon": 27096,
+ "hormone": 31283,
+ "hormones": 35162,
+ "horn": 15771,
+ "horn": 9607,
+ "horne": 38143,
+ "horned": 34526,
+ "hornet": 28739,
+ "hornets": 20124,
+ "horns": 22109,
+ "horny": 32622,
+ "horo": 21500,
+ "horoscope": 38453,
+ "horowitz": 44669,
+ "horri": 8656,
+ "horrible": 13726,
+ "horribly": 45484,
+ "horrific": 25314,
+ "horrifying": 38901,
+ "horror": 13787,
+ "horror": 5032,
+ "horrormovies": 46682,
+ "horrors": 33321,
+ "horse": 8562,
+ "horse": 4558,
+ "horseback": 43673,
+ "horseman": 48885,
+ "horsepower": 36882,
+ "horser": 23096,
+ "horseracing": 30693,
+ "horses": 8809,
+ "horseshoe": 29242,
+ "horst": 37182,
+ "hort": 19482,
+ "horticul": 27141,
+ "horticulture": 39998,
+ "horton": 25945,
+ "hortons": 38422,
+ "horus": 29794,
+ "hos": 44320,
+ "hos": 25008,
+ "hosa": 44618,
+ "hose": 19662,
+ "hoseok": 38817,
+ "hosp": 2847,
+ "hosp": 37853,
+ "hospice": 20533,
+ "hospit": 7180,
+ "hospital": 29399,
+ "hospital": 3851,
+ "hospitality": 11657,
+ "hospitalized": 36915,
+ "hospitals": 13816,
+ "host": 17403,
+ "host": 3953,
+ "hostage": 26119,
+ "hoste": 31700,
+ "hosted": 6017,
+ "hostel": 27225,
+ "hostess": 39692,
+ "hostile": 28074,
+ "hosting": 4857,
+ "hosts": 8718,
+ "hot": 2851,
+ "hot": 2069,
+ "hota": 43289,
+ "hotdog": 43758,
+ "hotel": 14591,
+ "hotel": 2738,
+ "hotels": 8654,
+ "hotline": 30516,
+ "hotmail": 46427,
+ "hotness": 39803,
+ "hotra": 27109,
+ "hotro": 47823,
+ "hotspot": 36606,
+ "hotspur": 35176,
+ "hotter": 23591,
+ "hottest": 8279,
+ "hottie": 22804,
+ "hotties": 46027,
+ "hou": 1011,
+ "hou": 10122,
+ "hough": 44529,
+ "houghton": 36133,
+ "houn": 39273,
+ "houn": 33607,
+ "hound": 33996,
+ "hound": 13561,
+ "hounds": 21178,
+ "hounews": 48373,
+ "hour": 14930,
+ "hour": 2232,
+ "hourly": 30918,
+ "hours": 2382,
+ "house": 4107,
+ "house": 1212,
+ "housed": 37518,
+ "household": 12412,
+ "households": 27167,
+ "housel": 48685,
+ "housemusic": 28468,
+ "houseof": 19928,
+ "houses": 7791,
+ "housewives": 38523,
+ "housing": 32924,
+ "housing": 5734,
+ "houston": 16564,
+ "houston": 5663,
+ "hov": 40291,
+ "hove": 29674,
+ "hoven": 35559,
+ "hover": 36252,
+ "hover": 49016,
+ "hovering": 43437,
+ "how": 7470,
+ "how": 829,
+ "howar": 37672,
+ "howard": 25447,
+ "howard": 7632,
+ "howdy": 42216,
+ "howe": 8179,
+ "howe": 24614,
+ "howell": 25297,
+ "hower": 32920,
+ "however": 8467,
+ "howi": 47883,
+ "howie": 42939,
+ "howl": 40332,
+ "howling": 41771,
+ "howto": 38191,
+ "howto": 44060,
+ "hoy": 39625,
+ "hoy": 13278,
+ "hoya": 40978,
+ "hp": 23753,
+ "hp": 6371,
+ "hpa": 30983,
+ "hpc": 39936,
+ "hpe": 33787,
+ "hpv": 45765,
+ "hq": 33571,
+ "hq": 4693,
+ "hr": 4810,
+ "hr": 4086,
+ "hra": 21320,
+ "hra": 17212,
+ "hrc": 18139,
+ "hrh": 29103,
+ "hri": 21068,
+ "hrithik": 45371,
+ "hrs": 7157,
+ "hru": 24127,
+ "hrw": 25064,
+ "hs": 9343,
+ "hs": 2466,
+ "hsbc": 31508,
+ "hsc": 43510,
+ "hse": 34057,
+ "hsfb": 29539,
+ "hsv": 47311,
+ "ht": 11123,
+ "ht": 7801,
+ "hta": 23452,
+ "hta": 49384,
+ "htafc": 42821,
+ "htc": 48942,
+ "htc": 17635,
+ "html": 18231,
+ "hts": 43710,
+ "htt": 10620,
+ "http": 15066,
+ "https": 30901,
+ "httr": 49372,
+ "httweets": 43198,
+ "hu": 845,
+ "hu": 5949,
+ "hua": 22138,
+ "huan": 41405,
+ "huang": 32013,
+ "huar": 46916,
+ "huawe": 17709,
+ "huawei": 21128,
+ "hub": 18775,
+ "hub": 7028,
+ "hubb": 23183,
+ "hubbard": 33288,
+ "hubble": 30421,
+ "hubby": 16947,
+ "hubert": 40699,
+ "hubs": 29327,
+ "huck": 22909,
+ "huckabee": 43666,
+ "hud": 7169,
+ "hud": 28563,
+ "hudder": 22629,
+ "huddersfield": 24220,
+ "huddle": 33435,
+ "hudson": 25873,
+ "hudson": 11260,
+ "hue": 48380,
+ "hue": 21465,
+ "hues": 38003,
+ "huey": 39663,
+ "huff": 18746,
+ "huff": 44999,
+ "huffpost": 45887,
+ "hug": 40790,
+ "hug": 10359,
+ "huge": 2699,
+ "hugely": 24648,
+ "hugged": 41333,
+ "hugging": 27058,
+ "hugh": 8723,
+ "hugh": 15385,
+ "hughes": 11418,
+ "hugo": 43935,
+ "hugo": 17132,
+ "hugs": 14248,
+ "huh": 13348,
+ "huhu": 32134,
+ "hui": 29978,
+ "hul": 7911,
+ "hula": 40145,
+ "hulk": 17637,
+ "hull": 25154,
+ "hull": 10375,
+ "hulu": 24666,
+ "hum": 5823,
+ "hum": 16283,
+ "human": 3175,
+ "human": 2751,
+ "humane": 20220,
+ "humanitarian": 14170,
+ "humanities": 24949,
+ "humanity": 9420,
+ "humanright": 44385,
+ "humanrights": 14148,
+ "humans": 8324,
+ "humb": 9988,
+ "humber": 30602,
+ "humber": 38063,
+ "humble": 38703,
+ "humble": 10889,
+ "humbled": 19682,
+ "humbling": 39757,
+ "humbold": 24739,
+ "humboldt": 31389,
+ "hume": 38197,
+ "humid": 14778,
+ "humid": 27447,
+ "humidi": 47666,
+ "humidity": 15469,
+ "humil": 27205,
+ "humili": 25332,
+ "humility": 28535,
+ "humming": 26515,
+ "hummingbird": 33072,
+ "hummus": 31785,
+ "humor": 29369,
+ "humor": 11186,
+ "humorous": 38173,
+ "humour": 19161,
+ "hump": 16673,
+ "hump": 24529,
+ "humpback": 47662,
+ "humpday": 27693,
+ "humph": 19767,
+ "humphrey": 31549,
+ "hun": 1616,
+ "hun": 10795,
+ "hundre": 8505,
+ "hundred": 11898,
+ "hundreds": 8879,
+ "hung": 13825,
+ "hungar": 19420,
+ "hungarian": 23325,
+ "hungary": 17232,
+ "hunger": 25565,
+ "hunger": 10184,
+ "hungergames": 47507,
+ "hungover": 41110,
+ "hungry": 44845,
+ "hungry": 8451,
+ "hunk": 33912,
+ "hunt": 16498,
+ "hunt": 5774,
+ "hunted": 37373,
+ "hunter": 16531,
+ "hunter": 6099,
+ "hunters": 16115,
+ "hunting": 27830,
+ "hunting": 7507,
+ "huntington": 23521,
+ "hunts": 34041,
+ "huntsville": 34544,
+ "hur": 2305,
+ "hur": 34523,
+ "hurd": 44915,
+ "hurdle": 27486,
+ "hurdles": 25440,
+ "huri": 42486,
+ "hurley": 30166,
+ "hurling": 24738,
+ "huron": 36147,
+ "hurrah": 40599,
+ "hurric": 6543,
+ "hurrican": 36105,
+ "hurricane": 24051,
+ "hurricane": 8782,
+ "hurricanes": 22357,
+ "hurry": 10921,
+ "hurst": 44742,
+ "hurst": 11760,
+ "hurt": 7413,
+ "hurting": 24017,
+ "hurts": 13059,
+ "hus": 5111,
+ "hus": 35853,
+ "husband": 6179,
+ "husbands": 33612,
+ "hush": 28728,
+ "husk": 19246,
+ "huskers": 26946,
+ "huskies": 20988,
+ "husky": 20421,
+ "huss": 13733,
+ "hussain": 17940,
+ "hussein": 31336,
+ "hust": 27279,
+ "hustle": 15709,
+ "huston": 46480,
+ "hut": 20924,
+ "hut": 16503,
+ "hutch": 31018,
+ "hutch": 33203,
+ "hutchinson": 35721,
+ "hutto": 27662,
+ "hutton": 38321,
+ "hv": 17209,
+ "hv": 18593,
+ "hvac": 27492,
+ "hw": 27491,
+ "hw": 18876,
+ "hwa": 32352,
+ "hwan": 44390,
+ "hwang": 46775,
+ "hwy": 13812,
+ "hy": 1441,
+ "hy": 17827,
+ "hya": 31600,
+ "hyacin": 47263,
+ "hyatt": 44856,
+ "hyatt": 25146,
+ "hybri": 9084,
+ "hybrid": 10156,
+ "hyd": 42382,
+ "hyde": 46484,
+ "hyde": 16343,
+ "hyder": 13960,
+ "hyderabad": 14801,
+ "hydr": 8031,
+ "hydra": 44414,
+ "hydra": 40420,
+ "hydrange": 43298,
+ "hydrate": 29628,
+ "hydrated": 23300,
+ "hydrating": 47653,
+ "hydration": 24174,
+ "hydrau": 26017,
+ "hydraulic": 26189,
+ "hydro": 8368,
+ "hydro": 22595,
+ "hydrogen": 20974,
+ "hye": 32724,
+ "hye": 25792,
+ "hygi": 16277,
+ "hygiene": 19591,
+ "hymn": 41350,
+ "hyo": 38960,
+ "hyo": 35078,
+ "hyp": 16964,
+ "hype": 30353,
+ "hype": 11111,
+ "hyped": 22507,
+ "hyper": 7997,
+ "hyper": 22146,
+ "hypertension": 40698,
+ "hypno": 23355,
+ "hypnosis": 48138,
+ "hypnoti": 40440,
+ "hypo": 10252,
+ "hypocr": 30711,
+ "hypocri": 25606,
+ "hypocrisy": 26296,
+ "hypocrite": 44125,
+ "hypothe": 46966,
+ "hypothesis": 44956,
+ "hyster": 24235,
+ "hysteria": 45965,
+ "hysterical": 48627,
+ "hyuk": 20452,
+ "hyun": 11831,
+ "hyun": 8589,
+ "hyundai": 17094,
+ "hyung": 46901,
+ "hyung": 16551,
+ "hz": 32533,
+ "i": 72,
+ "i": 328,
+ "ia": 12486,
+ "ia": 1073,
+ "iac": 32838,
+ "iac": 44063,
+ "iaf": 40789,
+ "iah": 35052,
+ "iain": 30103,
+ "ial": 11530,
+ "ial": 1974,
+ "ials": 20940,
+ "iam": 3579,
+ "iam": 11415,
+ "iambic": 43668,
+ "iambicpent": 43891,
+ "iamsrk": 15103,
+ "ian": 7723,
+ "ian": 1800,
+ "ians": 6451,
+ "iansomerhalder": 47077,
+ "iart": 18413,
+ "iartg": 18669,
+ "ias": 32303,
+ "ias": 14620,
+ "ib": 3962,
+ "ib": 13554,
+ "iba": 39763,
+ "ibadan": 44691,
+ "iban": 47145,
+ "ibc": 49014,
+ "ibd": 40732,
+ "iber": 23814,
+ "ibi": 12337,
+ "ibis": 47048,
+ "ibiza": 13853,
+ "ible": 37792,
+ "ibles": 44102,
+ "ibm": 23415,
+ "ibm": 13918,
+ "ibn": 25729,
+ "ibooks": 46887,
+ "ibra": 15476,
+ "ibrahi": 40350,
+ "ibrahim": 20816,
+ "ibrox": 46883,
+ "ibs": 41993,
+ "ibu": 43587,
+ "ibu": 46117,
+ "ic": 535,
+ "ic": 1029,
+ "ica": 2576,
+ "icago": 37492,
+ "ical": 6082,
+ "ical": 1110,
+ "ically": 3161,
+ "icals": 13999,
+ "ican": 17653,
+ "ican": 5246,
+ "icans": 20511,
+ "icar": 37211,
+ "ication": 21629,
+ "icc": 12945,
+ "ice": 2739,
+ "ice": 733,
+ "iceberg": 33662,
+ "icec": 13636,
+ "icecream": 21334,
+ "iced": 8049,
+ "icelan": 34114,
+ "iceland": 46716,
+ "iceland": 11935,
+ "icelandic": 34705,
+ "ices": 1931,
+ "ich": 5333,
+ "ich": 1232,
+ "icha": 31453,
+ "iche": 28972,
+ "iche": 21143,
+ "ichi": 21669,
+ "ichi": 14647,
+ "ichick": 45022,
+ "ichiro": 43787,
+ "ici": 948,
+ "ici": 22189,
+ "icia": 11774,
+ "icial": 17543,
+ "icial": 6397,
+ "ician": 40522,
+ "ician": 5374,
+ "icians": 6264,
+ "iciary": 21329,
+ "icic": 46006,
+ "icide": 6558,
+ "icides": 28253,
+ "icing": 7676,
+ "icio": 24207,
+ "icion": 45905,
+ "icious": 3325,
+ "icist": 21165,
+ "icists": 42171,
+ "icity": 7243,
+ "ick": 1168,
+ "ick": 1068,
+ "icked": 39799,
+ "icker": 40357,
+ "ickers": 30701,
+ "icki": 35468,
+ "icking": 6619,
+ "icks": 3727,
+ "icky": 11587,
+ "icn": 44516,
+ "ico": 13697,
+ "ico": 3040,
+ "icom": 17693,
+ "icom": 29796,
+ "icon": 13843,
+ "icon": 5646,
+ "iconic": 6959,
+ "icons": 15553,
+ "icop": 9389,
+ "icos": 32002,
+ "ics": 1324,
+ "ict": 6349,
+ "icted": 36515,
+ "iction": 40560,
+ "icton": 36548,
+ "icu": 45118,
+ "icu": 30443,
+ "icular": 40660,
+ "icus": 31459,
+ "icy": 28780,
+ "icy": 3495,
+ "icymi": 5315,
+ "icz": 46387,
+ "id": 1568,
+ "id": 1014,
+ "ida": 11032,
+ "ida": 11600,
+ "idad": 22462,
+ "idaho": 48817,
+ "idaho": 15165,
+ "idal": 39684,
+ "idan": 17929,
+ "idc": 22386,
+ "ide": 1909,
+ "ide": 14104,
+ "idea": 3612,
+ "ideal": 8789,
+ "ideally": 48247,
+ "ideals": 45096,
+ "ideas": 4452,
+ "ident": 7113,
+ "identi": 6009,
+ "identical": 25587,
+ "identification": 23337,
+ "identified": 15217,
+ "identifies": 35712,
+ "identify": 10949,
+ "identifying": 23589,
+ "identities": 34292,
+ "identity": 8892,
+ "ideology": 25840,
+ "iders": 8980,
+ "ides": 31791,
+ "idf": 28987,
+ "idge": 35567,
+ "idh": 44325,
+ "idi": 9611,
+ "idi": 14264,
+ "idio": 15994,
+ "idiot": 14087,
+ "idiots": 20856,
+ "idk": 8972,
+ "idle": 34754,
+ "idlib": 36199,
+ "ido": 6763,
+ "ido": 29641,
+ "idol": 24866,
+ "idol": 8884,
+ "idols": 21398,
+ "idr": 10106,
+ "idri": 46435,
+ "idris": 41312,
+ "ids": 6111,
+ "idu": 28655,
+ "idy": 33058,
+ "idyl": 44879,
+ "idyllic": 46632,
+ "ie": 6789,
+ "ie": 1718,
+ "iec": 44773,
+ "ied": 10059,
+ "ieee": 39860,
+ "iel": 27875,
+ "iel": 22729,
+ "ience": 1542,
+ "ient": 13115,
+ "ier": 33173,
+ "ier": 5912,
+ "iers": 45060,
+ "ies": 27912,
+ "ies": 963,
+ "iest": 10818,
+ "if": 8063,
+ "if": 878,
+ "ifa": 37574,
+ "ifc": 36524,
+ "ife": 41172,
+ "ife": 19590,
+ "iff": 35753,
+ "ification": 35755,
+ "ified": 41403,
+ "ift": 31143,
+ "iftar": 35153,
+ "ifu": 41523,
+ "ify": 32807,
+ "ig": 1089,
+ "ig": 3072,
+ "iga": 16493,
+ "igan": 27468,
+ "igans": 25419,
+ "igbo": 44591,
+ "ige": 10806,
+ "igen": 33070,
+ "iger": 30758,
+ "iger": 20685,
+ "igers": 40755,
+ "igers": 48928,
+ "iggy": 46219,
+ "iggy": 27604,
+ "igh": 2712,
+ "igh": 5451,
+ "ight": 14571,
+ "ight": 897,
+ "ighton": 35292,
+ "igi": 21901,
+ "igle": 29912,
+ "iglesias": 39432,
+ "ign": 7303,
+ "ign": 2326,
+ "ignati": 37573,
+ "ignatius": 48318,
+ "igne": 45843,
+ "ignite": 25210,
+ "ignition": 36115,
+ "igno": 15375,
+ "ignor": 7653,
+ "ignorance": 22735,
+ "ignorant": 26933,
+ "ignore": 12304,
+ "ignored": 20428,
+ "ignores": 40129,
+ "ignoring": 23969,
+ "igor": 33024,
+ "igs": 31344,
+ "igu": 21279,
+ "ih": 12162,
+ "ih": 34135,
+ "ihear": 13043,
+ "iheart": 30332,
+ "iheartawards": 18811,
+ "iheartradio": 25934,
+ "ihop": 45511,
+ "ihri": 39108,
+ "ihrithik": 39326,
+ "ii": 5103,
+ "ii": 2329,
+ "iii": 46236,
+ "iii": 6572,
+ "iiii": 20133,
+ "iiii": 45393,
+ "iiot": 30704,
+ "iit": 39330,
+ "iit": 33238,
+ "ij": 7337,
+ "ija": 42802,
+ "ik": 3903,
+ "ik": 10177,
+ "ika": 18188,
+ "ike": 12329,
+ "ike": 19696,
+ "ikea": 20528,
+ "iker": 38653,
+ "ikh": 44655,
+ "ikh": 12758,
+ "iklan": 32028,
+ "iklan": 29584,
+ "iko": 35659,
+ "iko": 39272,
+ "ikon": 38543,
+ "ikon": 19156,
+ "iku": 17780,
+ "il": 543,
+ "il": 958,
+ "ila": 4344,
+ "ilah": 32211,
+ "ilan": 13889,
+ "ilan": 28076,
+ "iland": 20957,
+ "ilation": 16180,
+ "ilay": 45093,
+ "ild": 22278,
+ "ild": 17164,
+ "ile": 18398,
+ "ile": 989,
+ "iled": 3358,
+ "iler": 22446,
+ "iler": 3615,
+ "ilers": 8975,
+ "iles": 42274,
+ "ili": 2076,
+ "ili": 19601,
+ "ilia": 14855,
+ "ilian": 10272,
+ "iliary": 32585,
+ "ilife": 42835,
+ "ilike": 44989,
+ "ilinan": 48497,
+ "iling": 3299,
+ "ilio": 47256,
+ "ilion": 12561,
+ "ilis": 43442,
+ "ilit": 11178,
+ "ilities": 5446,
+ "ility": 1787,
+ "ilive": 26478,
+ "ill": 828,
+ "ill": 660,
+ "illa": 8877,
+ "illa": 3043,
+ "illac": 17218,
+ "illage": 48922,
+ "illard": 21920,
+ "illary": 33667,
+ "illas": 23404,
+ "ille": 18213,
+ "ille": 5559,
+ "illed": 2527,
+ "illeg": 35808,
+ "illegal": 7983,
+ "illegally": 24466,
+ "illegals": 40490,
+ "iller": 23341,
+ "iller": 2956,
+ "illers": 30547,
+ "illery": 14514,
+ "illes": 20037,
+ "illi": 1086,
+ "illi": 25187,
+ "illia": 48776,
+ "illiams": 30301,
+ "illian": 48775,
+ "illian": 17355,
+ "illic": 37152,
+ "illicit": 40998,
+ "illie": 26083,
+ "illin": 35868,
+ "illing": 2803,
+ "illini": 28957,
+ "illino": 8920,
+ "illinois": 9414,
+ "illion": 35542,
+ "illion": 2035,
+ "illness": 11145,
+ "illnesses": 33861,
+ "illo": 34153,
+ "illo": 7588,
+ "illon": 20516,
+ "ills": 1900,
+ "illu": 3025,
+ "illumin": 11446,
+ "illuminate": 43261,
+ "illuminated": 28814,
+ "illuminati": 34551,
+ "illuminating": 46601,
+ "illumination": 43680,
+ "illus": 41386,
+ "illusion": 20318,
+ "illusions": 47429,
+ "illustr": 6268,
+ "illustrate": 37468,
+ "illustrated": 13151,
+ "illustrates": 38129,
+ "illustrating": 43322,
+ "illustration": 6052,
+ "illustrations": 17852,
+ "illustrator": 16649,
+ "illustri": 43116,
+ "illustrious": 44304,
+ "illy": 11707,
+ "illy": 9532,
+ "ilm": 36326,
+ "ilo": 4220,
+ "ilo": 14835,
+ "ilove": 7183,
+ "ilove": 32914,
+ "iloveart": 41114,
+ "ilovemy": 28863,
+ "iloveyou": 28829,
+ "ils": 1543,
+ "ilt": 25334,
+ "ilton": 28494,
+ "ilu": 27337,
+ "ilwx": 43777,
+ "ily": 4881,
+ "ily": 1026,
+ "ilya": 33377,
+ "ilysm": 29228,
+ "im": 732,
+ "im": 1496,
+ "ima": 2414,
+ "ima": 6432,
+ "imac": 40675,
+ "imacele": 47281,
+ "imag": 2316,
+ "image": 24101,
+ "image": 2867,
+ "imagery": 22828,
+ "images": 4952,
+ "imagin": 18178,
+ "imaginary": 30417,
+ "imagination": 13783,
+ "imaginative": 47233,
+ "imagine": 35752,
+ "imagine": 4826,
+ "imagined": 18478,
+ "imagines": 47379,
+ "imaging": 14231,
+ "imagining": 27384,
+ "imam": 37552,
+ "imam": 19024,
+ "iman": 45684,
+ "iman": 16247,
+ "imation": 44566,
+ "imax": 32066,
+ "imc": 45616,
+ "imdanielpadilla": 36357,
+ "imdb": 30407,
+ "ime": 44937,
+ "ime": 31151,
+ "imel": 31594,
+ "iment": 37157,
+ "imer": 21802,
+ "imes": 47744,
+ "imf": 28403,
+ "img": 24157,
+ "imi": 23559,
+ "imin": 23942,
+ "imit": 23462,
+ "imitation": 41630,
+ "imma": 19487,
+ "immac": 25085,
+ "immaculate": 29649,
+ "immature": 45531,
+ "immedi": 7366,
+ "immediate": 14440,
+ "immediately": 10108,
+ "immen": 17278,
+ "immense": 22722,
+ "immensely": 35013,
+ "immer": 13954,
+ "immerse": 46240,
+ "immersion": 31861,
+ "immersive": 27521,
+ "immigr": 5851,
+ "immigrant": 16474,
+ "immigrants": 14460,
+ "immigration": 9588,
+ "imminent": 27299,
+ "immort": 39244,
+ "immortal": 24717,
+ "immun": 8961,
+ "immune": 15606,
+ "immuni": 44571,
+ "immunity": 26254,
+ "immuno": 24361,
+ "immunology": 44483,
+ "immunotherapy": 39185,
+ "imo": 26349,
+ "imo": 13738,
+ "imp": 3335,
+ "imp": 31037,
+ "impac": 7573,
+ "impact": 33036,
+ "impact": 3844,
+ "impacted": 21424,
+ "impactful": 41631,
+ "impacting": 29359,
+ "impacts": 15069,
+ "impair": 36451,
+ "impaired": 28028,
+ "impairment": 44501,
+ "impala": 36641,
+ "impe": 23612,
+ "impeach": 16874,
+ "impeach": 43497,
+ "impeachment": 32979,
+ "impeachtrump": 38006,
+ "impecc": 34511,
+ "impeccable": 40111,
+ "impending": 34486,
+ "imper": 7727,
+ "imperative": 39833,
+ "imperfect": 46034,
+ "imperi": 30911,
+ "imperial": 32425,
+ "imperial": 12361,
+ "imperialism": 48855,
+ "imperson": 25551,
+ "implant": 33106,
+ "implants": 32202,
+ "imple": 7423,
+ "implement": 17966,
+ "implementation": 15102,
+ "implemented": 24315,
+ "implementing": 22862,
+ "implic": 15269,
+ "implications": 19229,
+ "implo": 40337,
+ "impo": 45704,
+ "import": 2336,
+ "import": 16294,
+ "importance": 6821,
+ "important": 2829,
+ "importantly": 21580,
+ "imported": 28798,
+ "imports": 25286,
+ "impose": 35879,
+ "imposed": 25871,
+ "imposing": 42289,
+ "impossible": 9815,
+ "impre": 3763,
+ "impress": 20015,
+ "impressed": 9689,
+ "impression": 14468,
+ "impressionism": 36114,
+ "impressionist": 44904,
+ "impressions": 22276,
+ "impressive": 6634,
+ "imprint": 43863,
+ "imprison": 22141,
+ "imprisoned": 32999,
+ "imprisonment": 39024,
+ "impro": 2531,
+ "impromp": 28100,
+ "impromptu": 28611,
+ "improv": 22868,
+ "improve": 4971,
+ "improved": 9446,
+ "improvement": 10790,
+ "improvements": 16320,
+ "improves": 18035,
+ "improving": 10381,
+ "improvis": 32343,
+ "improvised": 40886,
+ "impulse": 29683,
+ "impy": 42690,
+ "imran": 19647,
+ "imran": 19212,
+ "imrankhan": 25956,
+ "imrankhanpti": 26688,
+ "ims": 17800,
+ "imsa": 37262,
+ "imv": 35731,
+ "imvkohli": 37136,
+ "imwith": 26822,
+ "imwithher": 32651,
+ "in": 512,
+ "in": 530,
+ "ina": 18026,
+ "ina": 1366,
+ "inability": 47517,
+ "inaccurate": 49192,
+ "inaction": 41916,
+ "inactive": 49274,
+ "inadequate": 43403,
+ "inak": 46549,
+ "inal": 19178,
+ "inals": 26438,
+ "inan": 26204,
+ "inappropriate": 26722,
+ "inari": 48620,
+ "inary": 11337,
+ "inas": 36731,
+ "inas": 12362,
+ "inated": 38530,
+ "ination": 4706,
+ "inau": 10832,
+ "inaugu": 11309,
+ "inaugur": 11448,
+ "inaugural": 11340,
+ "inaugurated": 29011,
+ "inauguration": 16805,
+ "inbound": 24420,
+ "inbox": 18683,
+ "inc": 14570,
+ "inc": 4438,
+ "incan": 45964,
+ "incar": 18070,
+ "incarcer": 26334,
+ "incarcerated": 49178,
+ "incarceration": 39887,
+ "incase": 30463,
+ "ince": 44303,
+ "incen": 13259,
+ "incense": 35059,
+ "incentive": 29024,
+ "incentives": 29813,
+ "inception": 36653,
+ "inch": 6523,
+ "incheon": 30645,
+ "inches": 10809,
+ "inci": 5747,
+ "incidence": 43371,
+ "incident": 10103,
+ "incidents": 22120,
+ "incindia": 26161,
+ "inciner": 46434,
+ "incl": 27857,
+ "incl": 13338,
+ "inclined": 45470,
+ "inclu": 1738,
+ "include": 5942,
+ "included": 7414,
+ "includes": 6197,
+ "including": 2814,
+ "inclusion": 12079,
+ "inclusive": 13393,
+ "income": 8044,
+ "incoming": 15416,
+ "incomparable": 36027,
+ "incompetent": 45069,
+ "incomplete": 34040,
+ "incon": 42372,
+ "inconvenience": 40563,
+ "incorpor": 19335,
+ "incorporate": 34168,
+ "incorporated": 29494,
+ "incorporating": 40303,
+ "incorrect": 31872,
+ "incre": 1870,
+ "increase": 5230,
+ "increased": 9156,
+ "increases": 13797,
+ "increasing": 10270,
+ "increasingly": 16106,
+ "incredi": 2883,
+ "incredible": 22128,
+ "incredible": 3457,
+ "incredibleindia": 24680,
+ "incredibles": 48641,
+ "incredibly": 9513,
+ "incu": 38830,
+ "incub": 24587,
+ "incubator": 35736,
+ "incumb": 32246,
+ "incumbent": 38038,
+ "incur": 42356,
+ "ind": 5386,
+ "ind": 4655,
+ "inda": 15710,
+ "inde": 2645,
+ "indeed": 10031,
+ "indefin": 29501,
+ "indefinitely": 43750,
+ "independ": 4147,
+ "independence": 23117,
+ "independence": 7955,
+ "independenceday": 25971,
+ "independent": 33844,
+ "independent": 7088,
+ "independently": 39831,
+ "inder": 29225,
+ "index": 35209,
+ "index": 9458,
+ "indhoven": 44229,
+ "indi": 1098,
+ "indi": 46536,
+ "india": 27067,
+ "india": 1762,
+ "indian": 7685,
+ "indian": 3606,
+ "indiana": 8615,
+ "indianapolis": 17196,
+ "indianfootball": 45979,
+ "indians": 10271,
+ "indic": 7136,
+ "indicate": 26679,
+ "indicated": 39416,
+ "indicates": 29412,
+ "indication": 38539,
+ "indicator": 24776,
+ "indicators": 30054,
+ "indicted": 34992,
+ "indictment": 42278,
+ "indie": 5260,
+ "indie": 9383,
+ "indiedev": 10863,
+ "indiefilm": 22588,
+ "indiegame": 17969,
+ "indiegamedev": 40466,
+ "indiegames": 35864,
+ "indiegogo": 38057,
+ "indies": 23618,
+ "indiffe": 41372,
+ "indigen": 8348,
+ "indigenous": 9303,
+ "indigo": 21002,
+ "indira": 43887,
+ "indirec": 26398,
+ "indirect": 35416,
+ "indivi": 5649,
+ "individu": 9574,
+ "individual": 8512,
+ "individually": 33782,
+ "individuals": 11990,
+ "indo": 26303,
+ "indo": 18297,
+ "indom": 42926,
+ "indone": 6180,
+ "indonesia": 7229,
+ "indonesian": 19593,
+ "indoor": 44478,
+ "indoor": 9546,
+ "indoors": 22973,
+ "indore": 46143,
+ "indu": 2298,
+ "induc": 7973,
+ "induced": 24103,
+ "inducted": 20596,
+ "inductee": 39558,
+ "inductees": 44796,
+ "induction": 18338,
+ "indul": 19402,
+ "indulg": 28388,
+ "indulge": 24851,
+ "indulgence": 40856,
+ "indulgent": 49147,
+ "industri": 5082,
+ "industrial": 30853,
+ "industrial": 7520,
+ "industries": 11700,
+ "industry": 47407,
+ "industry": 3318,
+ "indv": 16942,
+ "indy": 9821,
+ "indy": 10098,
+ "indycar": 20484,
+ "indyref": 22569,
+ "ine": 855,
+ "ine": 715,
+ "ineau": 38122,
+ "inec": 45214,
+ "ined": 2038,
+ "inee": 43252,
+ "inee": 7986,
+ "inees": 13056,
+ "ineffe": 47202,
+ "inely": 18234,
+ "inem": 48876,
+ "inema": 29232,
+ "inen": 44365,
+ "inequalities": 45507,
+ "inequality": 17372,
+ "iner": 17438,
+ "iner": 5155,
+ "iners": 41863,
+ "ines": 2137,
+ "inese": 35966,
+ "iness": 1463,
+ "inet": 8121,
+ "inette": 38911,
+ "inev": 19527,
+ "inevit": 45871,
+ "inevitable": 25004,
+ "inews": 24300,
+ "inexpensive": 38614,
+ "iney": 30254,
+ "inez": 12700,
+ "inf": 1529,
+ "inf": 35241,
+ "infamous": 18688,
+ "infan": 17219,
+ "infant": 19192,
+ "infantry": 21655,
+ "infants": 34726,
+ "infe": 7164,
+ "infec": 26088,
+ "infected": 26136,
+ "infection": 14774,
+ "infections": 22227,
+ "infectious": 29157,
+ "infeld": 25035,
+ "infer": 16258,
+ "inferno": 31290,
+ "infertility": 40701,
+ "infield": 48933,
+ "infiltr": 28683,
+ "infin": 6246,
+ "infinite": 12748,
+ "infiniti": 34644,
+ "infinity": 34863,
+ "infinity": 12895,
+ "infl": 7627,
+ "inflam": 16080,
+ "inflammation": 24893,
+ "inflammatory": 26831,
+ "inflatable": 30135,
+ "inflation": 17497,
+ "inflicted": 48188,
+ "influ": 4835,
+ "influen": 13229,
+ "influence": 9199,
+ "influenced": 21183,
+ "influencer": 25013,
+ "influencers": 29891,
+ "influences": 24926,
+ "influencing": 45126,
+ "influential": 17553,
+ "influenza": 39897,
+ "info": 5680,
+ "info": 2222,
+ "infographic": 10076,
+ "infographics": 33172,
+ "infor": 31773,
+ "inform": 10241,
+ "inform": 19449,
+ "informal": 25705,
+ "informat": 29625,
+ "informatics": 35685,
+ "information": 3204,
+ "informative": 19364,
+ "informed": 13876,
+ "informing": 45388,
+ "informs": 48440,
+ "infosec": 17863,
+ "infr": 29718,
+ "infra": 7312,
+ "infra": 45877,
+ "infrared": 22867,
+ "infrastructure": 9034,
+ "infringe": 44882,
+ "infringement": 48712,
+ "infront": 37668,
+ "infu": 15048,
+ "infuri": 48461,
+ "infused": 21461,
+ "infusion": 43464,
+ "ing": 653,
+ "ing": 519,
+ "inga": 15233,
+ "ingco": 40444,
+ "ingday": 16561,
+ "ingdon": 38731,
+ "inge": 11790,
+ "inge": 7071,
+ "inged": 30046,
+ "ingen": 19088,
+ "ingeni": 36884,
+ "inger": 33883,
+ "inger": 3541,
+ "ingfor": 33430,
+ "ingh": 9170,
+ "ingh": 30495,
+ "ingham": 24497,
+ "ingham": 4291,
+ "inghamshire": 39289,
+ "inghour": 42728,
+ "inging": 4066,
+ "ingl": 45662,
+ "ingle": 22228,
+ "ingle": 17005,
+ "ingles": 24490,
+ "ingley": 44428,
+ "inglis": 46327,
+ "ingly": 4796,
+ "ingnow": 34766,
+ "ingo": 30175,
+ "ingo": 9012,
+ "ingra": 45165,
+ "ingrad": 44124,
+ "ingram": 26998,
+ "ingredi": 9272,
+ "ingredient": 19799,
+ "ingredients": 11788,
+ "ingrid": 33496,
+ "ings": 895,
+ "ingthe": 20170,
+ "ingtips": 39373,
+ "ington": 11846,
+ "ington": 2156,
+ "ingu": 8714,
+ "ingual": 22795,
+ "ingue": 36838,
+ "ingui": 12788,
+ "inguish": 36146,
+ "inha": 32612,
+ "inhabit": 36189,
+ "inhabitants": 44968,
+ "inhal": 30786,
+ "inhe": 32617,
+ "inher": 24611,
+ "inherent": 47327,
+ "inherit": 34322,
+ "inheritance": 39341,
+ "inherited": 39111,
+ "inhi": 25557,
+ "inhibit": 32196,
+ "inho": 12984,
+ "ini": 6154,
+ "ini": 3581,
+ "inian": 36638,
+ "inim": 38717,
+ "inindia": 34021,
+ "ining": 1389,
+ "inist": 30976,
+ "init": 42670,
+ "initi": 4580,
+ "initial": 13980,
+ "initially": 28123,
+ "initials": 48794,
+ "initiated": 27756,
+ "initiation": 41009,
+ "initiative": 8152,
+ "initiatives": 16549,
+ "inity": 22126,
+ "inj": 5112,
+ "injec": 13688,
+ "injection": 21438,
+ "inju": 5006,
+ "injured": 7505,
+ "injuries": 9481,
+ "injury": 6223,
+ "injustice": 20541,
+ "ink": 4547,
+ "ink": 967,
+ "inka": 40685,
+ "inked": 29356,
+ "inki": 46176,
+ "inkigayo": 47882,
+ "inking": 37586,
+ "inks": 20966,
+ "inktober": 9387,
+ "inland": 21943,
+ "inlet": 35161,
+ "inline": 45004,
+ "inlove": 28415,
+ "inmate": 32341,
+ "inmates": 28216,
+ "inmy": 42657,
+ "inn": 27260,
+ "inn": 5569,
+ "inna": 35088,
+ "inner": 24512,
+ "inner": 6955,
+ "inning": 4415,
+ "innings": 11580,
+ "innis": 44059,
+ "inno": 7961,
+ "innocence": 26383,
+ "innocent": 11241,
+ "innov": 2890,
+ "innovate": 24549,
+ "innovation": 33063,
+ "innovation": 4272,
+ "innovations": 18817,
+ "innovative": 8494,
+ "innovator": 34735,
+ "innovators": 27834,
+ "ino": 4211,
+ "ino": 2691,
+ "inoa": 25649,
+ "inos": 21828,
+ "inous": 47801,
+ "inox": 22698,
+ "input": 16952,
+ "inputs": 48763,
+ "inqu": 10628,
+ "inqui": 18527,
+ "inquirer": 45172,
+ "inquiries": 29469,
+ "inquiry": 15865,
+ "inquis": 31171,
+ "inr": 36325,
+ "ins": 12786,
+ "ins": 1041,
+ "insan": 7875,
+ "insane": 10260,
+ "insanely": 27846,
+ "insanity": 26645,
+ "inscribed": 49168,
+ "inscription": 41127,
+ "insec": 15744,
+ "insect": 21297,
+ "insects": 18714,
+ "insecure": 35112,
+ "insecurity": 36964,
+ "inser": 13830,
+ "insert": 18807,
+ "insi": 3453,
+ "inside": 19141,
+ "inside": 2912,
+ "insider": 13300,
+ "insiders": 32171,
+ "insig": 40503,
+ "insight": 8795,
+ "insightful": 20354,
+ "insights": 8729,
+ "insignia": 48864,
+ "insist": 35504,
+ "insisted": 40423,
+ "insists": 27255,
+ "inski": 32630,
+ "insky": 24607,
+ "insol": 42366,
+ "insom": 21755,
+ "insomni": 42040,
+ "insomnia": 30598,
+ "inson": 21007,
+ "insp": 1597,
+ "inspec": 7915,
+ "inspect": 40815,
+ "inspecting": 40565,
+ "inspection": 15142,
+ "inspections": 39513,
+ "inspector": 20514,
+ "inspir": 2573,
+ "inspiration": 4195,
+ "inspirational": 41936,
+ "inspirational": 9855,
+ "inspirations": 35093,
+ "inspire": 27901,
+ "inspire": 8583,
+ "inspired": 39849,
+ "inspired": 3516,
+ "inspires": 17245,
+ "inspiring": 41847,
+ "inspiring": 5705,
+ "inspo": 26897,
+ "inst": 1264,
+ "inst": 1581,
+ "insta": 22411,
+ "insta": 11694,
+ "instability": 41377,
+ "instac": 46678,
+ "instaf": 33800,
+ "instag": 14612,
+ "instagood": 23718,
+ "instagram": 27910,
+ "instagram": 2659,
+ "instal": 38805,
+ "install": 6940,
+ "install": 11168,
+ "installation": 9358,
+ "installations": 27909,
+ "installed": 8807,
+ "installing": 18301,
+ "installment": 25315,
+ "installs": 45568,
+ "instalment": 47766,
+ "instance": 34572,
+ "instant": 38810,
+ "instant": 10635,
+ "instantly": 17703,
+ "instap": 23758,
+ "instapic": 34378,
+ "instaweather": 43078,
+ "instaweatherpro": 43150,
+ "inste": 3571,
+ "instead": 4191,
+ "instein": 13421,
+ "instem": 27030,
+ "instin": 23382,
+ "instinct": 30544,
+ "institu": 4257,
+ "institute": 5861,
+ "institutes": 43674,
+ "institution": 18823,
+ "institutional": 27442,
+ "institutions": 15207,
+ "instore": 41679,
+ "instru": 4544,
+ "instruc": 19648,
+ "instruction": 19407,
+ "instructional": 31022,
+ "instructions": 17040,
+ "instructor": 16087,
+ "instructors": 31998,
+ "instrument": 42196,
+ "instrument": 15806,
+ "instrumental": 23041,
+ "instruments": 14793,
+ "instyle": 41321,
+ "insu": 8805,
+ "insul": 9615,
+ "insulated": 42051,
+ "insulation": 28194,
+ "insulin": 29311,
+ "insult": 26673,
+ "insulting": 39646,
+ "insults": 40451,
+ "insur": 5024,
+ "insurance": 5870,
+ "insured": 31321,
+ "insurers": 43142,
+ "insurtech": 28716,
+ "int": 1828,
+ "int": 1207,
+ "inta": 38314,
+ "intact": 26870,
+ "intake": 19539,
+ "intan": 47695,
+ "inte": 1598,
+ "inte": 41900,
+ "intech": 26504,
+ "inted": 6147,
+ "integr": 5151,
+ "integral": 27018,
+ "integrate": 25735,
+ "integrated": 12797,
+ "integrating": 31555,
+ "integration": 12583,
+ "integrity": 14791,
+ "intel": 11778,
+ "intel": 11426,
+ "intellec": 13281,
+ "intellect": 47828,
+ "intellectu": 31966,
+ "intellectual": 18069,
+ "intelli": 5324,
+ "intellig": 5632,
+ "intelligence": 6846,
+ "intelligent": 14063,
+ "inten": 2967,
+ "intend": 36674,
+ "intended": 16812,
+ "intense": 10258,
+ "intensi": 22928,
+ "intensity": 19956,
+ "intensive": 21049,
+ "intent": 18881,
+ "intention": 26786,
+ "intentional": 29536,
+ "intentionally": 31215,
+ "intentions": 26710,
+ "inter": 1006,
+ "inter": 10093,
+ "interact": 21736,
+ "interacting": 35045,
+ "interaction": 17650,
+ "interactions": 22162,
+ "interactive": 9456,
+ "intercep": 23676,
+ "interception": 48762,
+ "interceptions": 45313,
+ "interchange": 34222,
+ "intercontinental": 31983,
+ "interdisciplinary": 38132,
+ "intere": 2008,
+ "interest": 5095,
+ "interested": 4620,
+ "interesting": 3628,
+ "interests": 16425,
+ "interface": 18753,
+ "interfaith": 38399,
+ "interference": 29099,
+ "interim": 19509,
+ "interior": 10700,
+ "interior": 7305,
+ "interiordesign": 12902,
+ "interiors": 14836,
+ "intermedi": 20246,
+ "intermediate": 24304,
+ "intermission": 44805,
+ "intermitt": 44946,
+ "intern": 9976,
+ "intern": 14068,
+ "internal": 11285,
+ "internally": 41134,
+ "internation": 42534,
+ "international": 8566,
+ "international": 2436,
+ "internationaldayof": 41518,
+ "internationally": 24059,
+ "internationalwomensday": 17682,
+ "interne": 32713,
+ "internet": 30180,
+ "internet": 4757,
+ "internetof": 44449,
+ "internetofthings": 45925,
+ "interns": 19902,
+ "internship": 16661,
+ "internships": 39410,
+ "interoper": 45754,
+ "interpre": 11162,
+ "interpret": 49154,
+ "interpret": 40459,
+ "interpretation": 20652,
+ "interpreted": 42157,
+ "interpreting": 46525,
+ "interro": 29548,
+ "interrup": 21609,
+ "interrupt": 48449,
+ "interrupted": 30288,
+ "intersec": 45246,
+ "intersection": 19210,
+ "interstate": 21963,
+ "interstellar": 41506,
+ "interval": 36032,
+ "intervals": 44884,
+ "interven": 18245,
+ "intervention": 16804,
+ "interventions": 28848,
+ "interview": 2885,
+ "interviewed": 11688,
+ "interviewing": 16399,
+ "interviews": 9910,
+ "intestin": 37938,
+ "intestinal": 38896,
+ "inthe": 7486,
+ "inti": 14459,
+ "intim": 38832,
+ "intimacy": 46430,
+ "intimate": 16382,
+ "intimid": 24041,
+ "intimidating": 44405,
+ "intimidation": 49258,
+ "inting": 15571,
+ "intl": 38186,
+ "intl": 14224,
+ "intment": 9020,
+ "intments": 21420,
+ "into": 35235,
+ "into": 1095,
+ "intoler": 28534,
+ "intolerance": 37808,
+ "intothe": 38511,
+ "intra": 20922,
+ "intrac": 46195,
+ "intram": 40956,
+ "intre": 29397,
+ "intrepid": 39127,
+ "intri": 15421,
+ "intric": 23763,
+ "intricate": 29616,
+ "intrigu": 18856,
+ "intrigue": 45140,
+ "intrigued": 40034,
+ "intriguing": 24334,
+ "intrin": 45181,
+ "intro": 2999,
+ "intro": 13224,
+ "introduc": 3621,
+ "introduce": 9813,
+ "introduced": 10446,
+ "introduces": 12933,
+ "introducing": 6256,
+ "introduction": 11812,
+ "introductory": 38121,
+ "intru": 22949,
+ "ints": 2514,
+ "intu": 17225,
+ "intuition": 40897,
+ "intuitive": 35224,
+ "inu": 21131,
+ "inuit": 41250,
+ "inus": 45857,
+ "inv": 2279,
+ "inv": 43786,
+ "inva": 10084,
+ "invade": 34609,
+ "invaded": 32596,
+ "invaders": 35188,
+ "invading": 40101,
+ "invali": 31592,
+ "invalid": 46998,
+ "invaluable": 33976,
+ "invasi": 38100,
+ "invasion": 13378,
+ "invasive": 19554,
+ "inve": 2024,
+ "inven": 26233,
+ "invent": 11665,
+ "invent": 23558,
+ "invented": 14100,
+ "invention": 23607,
+ "inventions": 44914,
+ "inventor": 22836,
+ "inventory": 19444,
+ "inver": 12061,
+ "inverness": 33080,
+ "inverte": 46397,
+ "inverted": 40709,
+ "invest": 4180,
+ "invest": 9716,
+ "invested": 22536,
+ "investig": 4626,
+ "investigate": 15703,
+ "investigated": 29180,
+ "investigates": 29621,
+ "investigating": 13713,
+ "investigation": 8194,
+ "investigations": 24020,
+ "investigative": 30233,
+ "investigator": 30528,
+ "investigators": 24121,
+ "investin": 40195,
+ "investing": 10554,
+ "investment": 5605,
+ "investments": 14675,
+ "investor": 15490,
+ "investors": 10486,
+ "invests": 38378,
+ "invic": 25253,
+ "invigor": 48722,
+ "invin": 30252,
+ "invincible": 38052,
+ "invisible": 16093,
+ "invit": 12454,
+ "invitation": 15032,
+ "invitational": 14511,
+ "invitations": 40120,
+ "invite": 8109,
+ "invited": 7731,
+ "invites": 16034,
+ "inviting": 14349,
+ "invo": 29417,
+ "invol": 4000,
+ "involve": 26325,
+ "involved": 5320,
+ "involvement": 19502,
+ "involves": 22652,
+ "involving": 14786,
+ "inwx": 35674,
+ "iny": 23257,
+ "inyour": 47954,
+ "io": 3167,
+ "io": 3752,
+ "ioc": 43018,
+ "iom": 33000,
+ "iom": 31135,
+ "ion": 14871,
+ "ion": 3668,
+ "ions": 26289,
+ "ior": 7354,
+ "ior": 2498,
+ "iority": 46016,
+ "iors": 6427,
+ "ios": 6614,
+ "iot": 32694,
+ "iot": 6627,
+ "iota": 37294,
+ "ious": 6994,
+ "iously": 38233,
+ "iow": 7439,
+ "iowa": 38847,
+ "iowa": 8290,
+ "ip": 1719,
+ "ip": 8600,
+ "ipa": 11199,
+ "ipad": 39067,
+ "ipad": 7491,
+ "ipads": 35281,
+ "ipc": 41981,
+ "iphone": 26030,
+ "iphone": 4314,
+ "iphones": 37561,
+ "ipl": 13440,
+ "ipment": 37824,
+ "ipo": 40218,
+ "ipo": 24090,
+ "ipod": 17889,
+ "ipp": 31706,
+ "ips": 26910,
+ "ipsw": 22221,
+ "ipswich": 24494,
+ "iq": 15554,
+ "iq": 19996,
+ "iqbal": 33553,
+ "ir": 582,
+ "ir": 742,
+ "ira": 4923,
+ "ira": 5371,
+ "irah": 35724,
+ "iran": 19273,
+ "iran": 5075,
+ "irandeal": 46533,
+ "irani": 37984,
+ "iranian": 14158,
+ "iraq": 8543,
+ "iraqi": 18617,
+ "irc": 41527,
+ "ird": 2770,
+ "ire": 3013,
+ "ire": 1454,
+ "ired": 32728,
+ "ired": 2995,
+ "ireland": 32806,
+ "ireland": 4157,
+ "irene": 21600,
+ "ires": 12435,
+ "irez": 21581,
+ "irgc": 47942,
+ "iri": 2155,
+ "iri": 13880,
+ "irical": 33366,
+ "irie": 42979,
+ "irina": 46664,
+ "iring": 10169,
+ "iris": 16437,
+ "irish": 9386,
+ "irish": 4889,
+ "irl": 34494,
+ "irl": 8570,
+ "irling": 26493,
+ "irls": 24344,
+ "irma": 22406,
+ "irn": 42603,
+ "iro": 23209,
+ "iro": 7280,
+ "iron": 7699,
+ "iron": 5391,
+ "ironic": 24518,
+ "ironically": 36779,
+ "ironing": 46655,
+ "ironman": 20330,
+ "irons": 30032,
+ "irony": 20681,
+ "irport": 27769,
+ "irr": 24641,
+ "irrational": 47413,
+ "irregular": 38692,
+ "irrelevant": 34677,
+ "irresi": 31200,
+ "irresistible": 35252,
+ "irresponsible": 44714,
+ "irri": 21484,
+ "irrigation": 23761,
+ "irrit": 24218,
+ "irs": 6086,
+ "irst": 32701,
+ "iru": 48206,
+ "irvin": 47053,
+ "irvine": 24201,
+ "irving": 19738,
+ "irwin": 23750,
+ "iry": 7239,
+ "is": 595,
+ "is": 533,
+ "isa": 11034,
+ "isa": 6536,
+ "isaac": 37544,
+ "isaac": 13659,
+ "isab": 13357,
+ "isabel": 27466,
+ "isabella": 26192,
+ "isabelle": 31072,
+ "isable": 46631,
+ "isai": 15365,
+ "isaiah": 17952,
+ "isak": 40619,
+ "isance": 46893,
+ "isation": 7194,
+ "isback": 43811,
+ "isc": 39316,
+ "isch": 47888,
+ "isco": 5736,
+ "iscoming": 26458,
+ "isd": 46816,
+ "isd": 12002,
+ "ise": 7669,
+ "ise": 1479,
+ "ised": 2861,
+ "iselle": 48491,
+ "iser": 23080,
+ "iser": 5626,
+ "isers": 34879,
+ "ises": 5153,
+ "isf": 44036,
+ "isgreat": 34595,
+ "ish": 6844,
+ "ish": 1061,
+ "isha": 28050,
+ "ishable": 37949,
+ "ished": 35341,
+ "ishere": 46053,
+ "ishi": 26224,
+ "ishq": 27996,
+ "ishqba": 32503,
+ "ishqbaaaz": 36591,
+ "isi": 7233,
+ "isi": 17880,
+ "isil": 34636,
+ "isin": 37676,
+ "ising": 3426,
+ "isis": 7531,
+ "isk": 30171,
+ "isl": 31368,
+ "isla": 22807,
+ "islam": 6003,
+ "islam": 8770,
+ "islamabad": 19959,
+ "islamic": 31627,
+ "islamic": 9552,
+ "islamist": 38798,
+ "islamophobia": 43459,
+ "island": 13408,
+ "island": 2619,
+ "islander": 45651,
+ "islanders": 27804,
+ "islands": 7145,
+ "islay": 49279,
+ "isle": 19082,
+ "isle": 11849,
+ "isleof": 24718,
+ "isles": 21816,
+ "islife": 26433,
+ "islington": 34945,
+ "ism": 47730,
+ "ism": 1935,
+ "isma": 43937,
+ "ismail": 36140,
+ "isme": 43570,
+ "ismo": 41926,
+ "isms": 18700,
+ "isn": 2923,
+ "isner": 48246,
+ "isnow": 43694,
+ "isnt": 19416,
+ "iso": 2462,
+ "iso": 12263,
+ "isol": 11414,
+ "isolated": 19044,
+ "isolation": 26400,
+ "ison": 12949,
+ "ison": 4553,
+ "isons": 33318,
+ "isoo": 35857,
+ "isp": 31397,
+ "isp": 39041,
+ "isra": 3591,
+ "israel": 20837,
+ "israel": 4779,
+ "israeli": 8994,
+ "israelis": 45713,
+ "isreal": 47147,
+ "isro": 44841,
+ "iss": 11738,
+ "iss": 4950,
+ "issa": 38579,
+ "issa": 7560,
+ "issan": 49358,
+ "issance": 40828,
+ "issant": 38828,
+ "isse": 18986,
+ "ission": 37946,
+ "issu": 2049,
+ "issue": 3202,
+ "issued": 9246,
+ "issues": 4082,
+ "issuing": 37226,
+ "ist": 9751,
+ "ist": 2304,
+ "istanbul": 12258,
+ "istandwith": 33820,
+ "iste": 32563,
+ "ister": 14555,
+ "isthe": 46748,
+ "istic": 29556,
+ "ists": 8426,
+ "isu": 17030,
+ "isu": 23328,
+ "it": 529,
+ "it": 585,
+ "ita": 36920,
+ "ita": 2864,
+ "itable": 8915,
+ "ital": 2306,
+ "ital": 1660,
+ "itali": 11644,
+ "italia": 11025,
+ "italian": 20264,
+ "italian": 5175,
+ "italians": 44744,
+ "italk": 32894,
+ "italy": 4052,
+ "itan": 18383,
+ "itans": 40711,
+ "itar": 47161,
+ "itarian": 11599,
+ "itary": 17604,
+ "itas": 31634,
+ "itas": 13436,
+ "itate": 42457,
+ "itated": 36744,
+ "itation": 5070,
+ "itative": 22892,
+ "itc": 36449,
+ "itch": 2387,
+ "itch": 8147,
+ "itchen": 32664,
+ "itchy": 41980,
+ "ite": 2732,
+ "ite": 802,
+ "iteam": 37828,
+ "itec": 3099,
+ "itec": 43936,
+ "itech": 44215,
+ "itech": 23040,
+ "ited": 8603,
+ "ited": 1108,
+ "itel": 44638,
+ "itely": 4605,
+ "item": 8532,
+ "items": 6207,
+ "iter": 7938,
+ "iter": 19773,
+ "iteracy": 39634,
+ "iterate": 43106,
+ "iteration": 38790,
+ "ites": 2454,
+ "itez": 42131,
+ "itf": 35436,
+ "itfc": 36519,
+ "ith": 6133,
+ "ith": 1757,
+ "ithaca": 46257,
+ "iti": 760,
+ "iti": 6165,
+ "itia": 22634,
+ "itian": 23365,
+ "itic": 11950,
+ "itical": 48767,
+ "itics": 33967,
+ "ities": 41423,
+ "ities": 1480,
+ "itim": 15676,
+ "itiner": 32803,
+ "itinerary": 41564,
+ "iting": 1257,
+ "ition": 25263,
+ "ition": 1104,
+ "itions": 5540,
+ "itious": 13329,
+ "itis": 33539,
+ "itis": 8388,
+ "itive": 3067,
+ "itly": 42240,
+ "ito": 22167,
+ "ito": 4661,
+ "iton": 21119,
+ "itor": 47267,
+ "itor": 4584,
+ "itors": 22005,
+ "itos": 24560,
+ "its": 7140,
+ "its": 902,
+ "itsa": 45032,
+ "itself": 7290,
+ "itsme": 41125,
+ "itss": 47040,
+ "itt": 1031,
+ "itt": 11228,
+ "itta": 21233,
+ "itte": 31962,
+ "itted": 24429,
+ "itten": 30014,
+ "itten": 4343,
+ "itter": 11456,
+ "itters": 13082,
+ "itti": 28629,
+ "ittin": 25646,
+ "itting": 3147,
+ "ittle": 24208,
+ "ittle": 21366,
+ "ittles": 38989,
+ "itton": 25707,
+ "itty": 35096,
+ "itu": 1668,
+ "itu": 32128,
+ "itude": 43382,
+ "itude": 5012,
+ "itudes": 20459,
+ "itunes": 7007,
+ "itup": 35838,
+ "iture": 25547,
+ "itus": 24364,
+ "itutes": 32883,
+ "itv": 20159,
+ "itv": 12805,
+ "ity": 2480,
+ "ity": 696,
+ "itya": 32055,
+ "itz": 14544,
+ "itz": 7807,
+ "iu": 14292,
+ "iu": 15575,
+ "ium": 10762,
+ "ius": 6740,
+ "iv": 6775,
+ "iv": 9315,
+ "iva": 42463,
+ "ivan": 15544,
+ "ivan": 15689,
+ "ivanka": 37914,
+ "ive": 26885,
+ "ive": 8653,
+ "ived": 15654,
+ "iver": 36849,
+ "iver": 44254,
+ "ives": 27333,
+ "ivf": 39159,
+ "iving": 45136,
+ "ivory": 16776,
+ "ivote": 45835,
+ "ivy": 36939,
+ "ivy": 16045,
+ "iw": 13058,
+ "iw": 46604,
+ "iwant": 42747,
+ "iwd": 16815,
+ "iwm": 44237,
+ "ix": 13272,
+ "ix": 8756,
+ "iy": 13704,
+ "iya": 18595,
+ "iyaki": 48395,
+ "iz": 2845,
+ "iz": 8407,
+ "iza": 37704,
+ "ization": 10847,
+ "ize": 10885,
+ "ized": 7690,
+ "izen": 34776,
+ "izer": 23895,
+ "izes": 45434,
+ "izing": 17354,
+ "izo": 46910,
+ "izz": 31779,
+ "izz": 46128,
+ "izzy": 28861,
+ "j": 73,
+ "j": 329,
+ "ja": 1586,
+ "ja": 2641,
+ "jaan": 25052,
+ "jab": 8059,
+ "jab": 9439,
+ "jac": 2293,
+ "jac": 30198,
+ "jace": 43286,
+ "jack": 2679,
+ "jack": 3267,
+ "jacked": 27923,
+ "jacket": 6164,
+ "jackets": 14745,
+ "jacki": 47418,
+ "jackie": 28023,
+ "jackie": 11716,
+ "jacking": 40929,
+ "jackman": 35723,
+ "jackpot": 23926,
+ "jacks": 19649,
+ "jackson": 12321,
+ "jackson": 4363,
+ "jacksonville": 19263,
+ "jaco": 6840,
+ "jacob": 14385,
+ "jacob": 9222,
+ "jacobs": 17482,
+ "jacobson": 46826,
+ "jacqu": 14495,
+ "jacqueline": 22843,
+ "jacques": 17799,
+ "jad": 12976,
+ "jad": 38691,
+ "jada": 37416,
+ "jade": 25123,
+ "jade": 14513,
+ "jaden": 37174,
+ "jadine": 37445,
+ "jae": 16869,
+ "jae": 15765,
+ "jaejoong": 43610,
+ "jaf": 19362,
+ "jag": 7984,
+ "jag": 36236,
+ "jagan": 48530,
+ "jagger": 30835,
+ "jags": 31086,
+ "jagu": 10096,
+ "jaguar": 44777,
+ "jaguar": 14757,
+ "jaguars": 21854,
+ "jah": 20067,
+ "jah": 11084,
+ "jahan": 44404,
+ "jahan": 47827,
+ "jai": 10542,
+ "jai": 13819,
+ "jail": 18574,
+ "jail": 9332,
+ "jailbreak": 45990,
+ "jailed": 19456,
+ "jails": 47833,
+ "jaime": 24716,
+ "jain": 21999,
+ "jaipur": 23593,
+ "jais": 48607,
+ "jait": 28910,
+ "jaitley": 32776,
+ "jak": 9225,
+ "jak": 30589,
+ "jakarta": 15471,
+ "jake": 13140,
+ "jake": 7419,
+ "jakob": 47358,
+ "jal": 8380,
+ "jal": 26773,
+ "jalan": 27270,
+ "jalap": 49081,
+ "jalape": 34263,
+ "jalapeño": 43017,
+ "jalen": 33548,
+ "jam": 1434,
+ "jam": 5201,
+ "jama": 8977,
+ "jama": 35366,
+ "jamaica": 13019,
+ "jamaican": 25144,
+ "jamal": 26108,
+ "jambo": 35599,
+ "jamboree": 38506,
+ "jame": 12341,
+ "james": 6963,
+ "james": 2392,
+ "jamesbond": 44704,
+ "jamesc": 47004,
+ "jameson": 31731,
+ "jami": 15092,
+ "jamie": 16454,
+ "jamie": 8078,
+ "jamiedor": 34310,
+ "jamiedornan": 34896,
+ "jammed": 35590,
+ "jammin": 35223,
+ "jamming": 25862,
+ "jammu": 25926,
+ "jams": 20243,
+ "jan": 1891,
+ "jan": 3334,
+ "jana": 18182,
+ "jane": 12389,
+ "jane": 6736,
+ "janeiro": 31740,
+ "janet": 29665,
+ "janet": 15872,
+ "jang": 41526,
+ "jang": 22074,
+ "jani": 22606,
+ "janice": 36048,
+ "janine": 46896,
+ "janis": 44233,
+ "jann": 35377,
+ "jans": 22578,
+ "jansen": 45354,
+ "janu": 3623,
+ "january": 3697,
+ "jap": 2299,
+ "jap": 49062,
+ "japan": 4502,
+ "japan": 3400,
+ "japanese": 27211,
+ "japanese": 4925,
+ "japs": 42121,
+ "jar": 5120,
+ "jar": 10837,
+ "jard": 25778,
+ "jardin": 37371,
+ "jare": 17654,
+ "jared": 35597,
+ "jared": 12571,
+ "jaredle": 36739,
+ "jaredleto": 37106,
+ "jaro": 35505,
+ "jarpad": 44497,
+ "jarre": 23385,
+ "jarrett": 30531,
+ "jars": 27583,
+ "jarvis": 29286,
+ "jas": 4492,
+ "jas": 17559,
+ "jasmin": 42989,
+ "jasmin": 47700,
+ "jasmine": 17056,
+ "jason": 10009,
+ "jason": 5395,
+ "jasper": 19827,
+ "jat": 26106,
+ "jau": 26932,
+ "jauregui": 48175,
+ "jav": 6234,
+ "java": 12918,
+ "javascri": 16289,
+ "javascript": 16423,
+ "jave": 46218,
+ "javed": 42268,
+ "javelin": 41701,
+ "javi": 47627,
+ "javier": 23307,
+ "jaw": 14804,
+ "jaw": 17307,
+ "jawa": 44790,
+ "jaws": 25491,
+ "jax": 22348,
+ "jax": 12390,
+ "jay": 3427,
+ "jay": 4155,
+ "jaya": 21960,
+ "jayanti": 37732,
+ "jaye": 45703,
+ "jayne": 35228,
+ "jays": 12393,
+ "jaz": 3465,
+ "jaz": 32874,
+ "jazeera": 38260,
+ "jazz": 11488,
+ "jazz": 4528,
+ "jazzfest": 36683,
+ "jazzy": 28191,
+ "jb": 21915,
+ "jb": 13637,
+ "jc": 14991,
+ "jc": 11517,
+ "jd": 18289,
+ "jd": 14125,
+ "jdm": 42013,
+ "je": 1013,
+ "je": 8776,
+ "jeal": 9964,
+ "jealous": 11093,
+ "jealousy": 37654,
+ "jean": 13943,
+ "jean": 6473,
+ "jeanette": 48167,
+ "jeanne": 29201,
+ "jeans": 10157,
+ "jeb": 35101,
+ "jec": 1347,
+ "ject": 6070,
+ "jed": 12166,
+ "jed": 38748,
+ "jeddah": 40982,
+ "jedi": 16681,
+ "jee": 29250,
+ "jee": 14870,
+ "jeep": 16593,
+ "jeep": 11286,
+ "jeeplife": 43100,
+ "jeet": 45542,
+ "jeet": 30944,
+ "jef": 10276,
+ "jeff": 6245,
+ "jeff": 5550,
+ "jefferson": 44711,
+ "jefferson": 13976,
+ "jeffery": 41470,
+ "jeffree": 45994,
+ "jeffrey": 32886,
+ "jeffrey": 16027,
+ "jeho": 42437,
+ "jeky": 43893,
+ "jekyll": 49405,
+ "jel": 9794,
+ "jelena": 48218,
+ "jelly": 19110,
+ "jelly": 13762,
+ "jellyfish": 30988,
+ "jem": 46326,
+ "jem": 37530,
+ "jen": 2554,
+ "jen": 12997,
+ "jenkins": 16162,
+ "jenn": 33921,
+ "jenn": 29869,
+ "jenna": 17125,
+ "jenner": 14260,
+ "jenni": 6774,
+ "jennie": 28875,
+ "jennifer": 19786,
+ "jennifer": 8613,
+ "jennings": 21564,
+ "jenny": 20165,
+ "jenny": 13414,
+ "jens": 40806,
+ "jensen": 35558,
+ "jensen": 19004,
+ "jensenackles": 41011,
+ "jeon": 45200,
+ "jeon": 43337,
+ "jeong": 47146,
+ "jeong": 39264,
+ "jeopar": 22988,
+ "jeopardy": 29613,
+ "jer": 2310,
+ "jer": 35307,
+ "jere": 5614,
+ "jeremi": 22362,
+ "jeremiah": 27301,
+ "jeremy": 14656,
+ "jeremy": 8127,
+ "jeremycorbyn": 37484,
+ "jeric": 25084,
+ "jericho": 28892,
+ "jerk": 23917,
+ "jerky": 40079,
+ "jermaine": 40722,
+ "jerome": 19876,
+ "jerry": 18163,
+ "jerry": 9164,
+ "jersey": 21921,
+ "jersey": 4471,
+ "jerseys": 15518,
+ "jerus": 12257,
+ "jerusalem": 12557,
+ "jes": 7686,
+ "jes": 35826,
+ "jess": 5313,
+ "jess": 13758,
+ "jesse": 23112,
+ "jesse": 11770,
+ "jessi": 24373,
+ "jessic": 14881,
+ "jessica": 45421,
+ "jessica": 8178,
+ "jessie": 19424,
+ "jester": 44225,
+ "jesu": 19777,
+ "jesuit": 33234,
+ "jesus": 4070,
+ "jet": 11515,
+ "jet": 6565,
+ "jetblue": 45021,
+ "jeter": 38450,
+ "jets": 38584,
+ "jets": 10025,
+ "jett": 44541,
+ "jetty": 46382,
+ "jew": 27450,
+ "jewel": 4880,
+ "jewel": 17591,
+ "jewell": 9777,
+ "jewellers": 46265,
+ "jewellery": 11192,
+ "jewelry": 28018,
+ "jewelry": 6039,
+ "jewels": 20205,
+ "jewish": 29594,
+ "jewish": 9104,
+ "jews": 14200,
+ "jf": 31130,
+ "jf": 33718,
+ "jfc": 43652,
+ "jfk": 18486,
+ "jg": 41986,
+ "jg": 35138,
+ "jh": 24858,
+ "jh": 21485,
+ "jha": 47012,
+ "jha": 38092,
+ "jhal": 45695,
+ "jhar": 31546,
+ "jharkhand": 39001,
+ "jhb": 34631,
+ "ji": 3252,
+ "ji": 2697,
+ "jia": 32907,
+ "jian": 33427,
+ "jiang": 43309,
+ "jiang": 25762,
+ "jic": 48350,
+ "jic": 40215,
+ "jid": 24403,
+ "jie": 40005,
+ "jig": 15136,
+ "jig": 47430,
+ "jigsaw": 32987,
+ "jiha": 23194,
+ "jihad": 29637,
+ "jihoon": 44765,
+ "jil": 36225,
+ "jill": 24136,
+ "jill": 15254,
+ "jillian": 37820,
+ "jim": 3190,
+ "jim": 4550,
+ "jima": 20679,
+ "jimcantore": 43950,
+ "jimenez": 35947,
+ "jimi": 30565,
+ "jimin": 16286,
+ "jimmie": 45679,
+ "jimmy": 12215,
+ "jimmy": 6817,
+ "jimmyfallon": 45265,
+ "jin": 7927,
+ "jin": 8485,
+ "jind": 40609,
+ "jing": 34933,
+ "jing": 28607,
+ "jingle": 28699,
+ "jinnah": 43141,
+ "jinping": 39308,
+ "jinx": 42977,
+ "jinyoung": 38051,
+ "jio": 40501,
+ "jis": 25988,
+ "jis": 23515,
+ "jisoo": 43070,
+ "jit": 11947,
+ "jit": 20308,
+ "jitsu": 24530,
+ "jiu": 43351,
+ "jiu": 44123,
+ "jj": 12502,
+ "jj": 12790,
+ "jk": 20189,
+ "jk": 9702,
+ "jkt": 21494,
+ "jl": 25027,
+ "jl": 22911,
+ "jlo": 31017,
+ "jm": 24044,
+ "jm": 18657,
+ "jn": 24576,
+ "jn": 21717,
+ "jnr": 37145,
+ "jnu": 47142,
+ "jo": 683,
+ "jo": 3804,
+ "joachim": 48979,
+ "joan": 28064,
+ "joan": 12710,
+ "joann": 35484,
+ "joanna": 25357,
+ "joanne": 43736,
+ "joanne": 25092,
+ "joao": 45666,
+ "joaqu": 25140,
+ "joaquin": 30745,
+ "job": 13114,
+ "job": 2075,
+ "jobs": 3735,
+ "jobsearch": 45459,
+ "joburg": 39343,
+ "jocel": 36879,
+ "jocelyn": 47259,
+ "jock": 34485,
+ "jockey": 20126,
+ "jodh": 48689,
+ "jodi": 36812,
+ "jodi": 26888,
+ "jodie": 33100,
+ "jody": 32959,
+ "joe": 9309,
+ "joe": 3305,
+ "joel": 19819,
+ "joel": 11429,
+ "joes": 34756,
+ "joey": 16281,
+ "joey": 10455,
+ "jog": 37967,
+ "jog": 31691,
+ "jogging": 37922,
+ "joh": 1201,
+ "johan": 17416,
+ "johan": 27789,
+ "johann": 31180,
+ "johanna": 41494,
+ "johannes": 37779,
+ "johannesburg": 28377,
+ "johansson": 41512,
+ "johar": 34871,
+ "john": 2004,
+ "john": 1742,
+ "johncena": 46820,
+ "johnnie": 47947,
+ "johnny": 14464,
+ "johnny": 6904,
+ "johns": 14515,
+ "johnson": 26036,
+ "johnson": 4010,
+ "johnston": 19791,
+ "johnstone": 40766,
+ "johor": 34750,
+ "join": 14737,
+ "join": 1384,
+ "joined": 4954,
+ "joining": 5118,
+ "joins": 5681,
+ "joint": 6640,
+ "jointhe": 30422,
+ "jointly": 37471,
+ "joints": 27204,
+ "jojo": 41484,
+ "jojo": 22075,
+ "joke": 7198,
+ "joker": 18200,
+ "jokers": 44101,
+ "jokes": 11336,
+ "joking": 26112,
+ "joko": 44975,
+ "jol": 9174,
+ "jol": 36470,
+ "jolie": 31633,
+ "jolla": 46109,
+ "jolly": 21516,
+ "jom": 32152,
+ "jon": 3026,
+ "jon": 6139,
+ "jona": 6629,
+ "jonah": 47934,
+ "jonah": 27556,
+ "jonas": 42373,
+ "jonas": 13650,
+ "jonathan": 19026,
+ "jonathan": 7762,
+ "jone": 33934,
+ "jones": 19091,
+ "jones": 3538,
+ "jong": 20214,
+ "jong": 14726,
+ "jonghyun": 29023,
+ "jongin": 36957,
+ "joni": 43177,
+ "jonny": 28454,
+ "jonny": 21895,
+ "joo": 25807,
+ "joo": 27680,
+ "joom": 47543,
+ "joon": 18547,
+ "joong": 26544,
+ "jop": 30486,
+ "joplin": 42688,
+ "jor": 2482,
+ "jor": 31595,
+ "jordan": 14644,
+ "jordan": 4388,
+ "jordani": 46898,
+ "jordi": 44795,
+ "jorge": 48761,
+ "jorge": 18225,
+ "jos": 20560,
+ "jos": 19661,
+ "jose": 4647,
+ "jose": 7075,
+ "josef": 36584,
+ "josel": 47800,
+ "joseph": 14163,
+ "joseph": 6478,
+ "josephine": 34866,
+ "josh": 9998,
+ "josh": 5679,
+ "joshi": 24786,
+ "joshu": 9112,
+ "joshua": 11852,
+ "josi": 33583,
+ "josie": 33167,
+ "joss": 42834,
+ "josé": 27922,
+ "jou": 19921,
+ "jou": 32029,
+ "jour": 2078,
+ "jour": 17142,
+ "journ": 4563,
+ "journal": 6626,
+ "journalism": 10123,
+ "journalist": 9914,
+ "journalists": 12249,
+ "journals": 24391,
+ "journe": 48833,
+ "journey": 32156,
+ "journey": 3749,
+ "journeys": 23329,
+ "journo": 37034,
+ "journos": 46437,
+ "jovi": 33866,
+ "joy": 6308,
+ "joy": 4273,
+ "joyce": 43753,
+ "joyce": 15275,
+ "joye": 34052,
+ "joyeux": 41876,
+ "joyful": 24139,
+ "joyous": 32245,
+ "joyride": 46949,
+ "joys": 22996,
+ "jp": 18249,
+ "jp": 10557,
+ "jpg": 36950,
+ "jpn": 36212,
+ "jr": 13973,
+ "jr": 3605,
+ "js": 46243,
+ "js": 8006,
+ "jst": 26523,
+ "jt": 39480,
+ "jt": 18119,
+ "ju": 669,
+ "ju": 9970,
+ "jual": 38720,
+ "juan": 17148,
+ "juan": 9274,
+ "juana": 9081,
+ "jubi": 15485,
+ "jubil": 47743,
+ "jubilee": 16907,
+ "juco": 31570,
+ "jud": 8363,
+ "juda": 32478,
+ "judah": 41066,
+ "judaism": 42217,
+ "judas": 39532,
+ "judd": 29770,
+ "judg": 20012,
+ "judge": 16824,
+ "judge": 5656,
+ "judged": 33453,
+ "judgement": 25246,
+ "judges": 12575,
+ "judging": 16570,
+ "judgment": 24191,
+ "judi": 42546,
+ "judice": 28032,
+ "judicial": 19579,
+ "judiciary": 24545,
+ "judith": 24047,
+ "judo": 27011,
+ "judy": 34663,
+ "judy": 16510,
+ "jug": 27619,
+ "jugg": 38628,
+ "juic": 38761,
+ "juice": 37954,
+ "juice": 6916,
+ "juices": 36757,
+ "juicy": 17623,
+ "juju": 43020,
+ "juke": 32519,
+ "jukebox": 36411,
+ "jul": 34662,
+ "jul": 15975,
+ "jule": 40819,
+ "jules": 21996,
+ "juli": 3614,
+ "juli": 49160,
+ "julia": 10207,
+ "julian": 25459,
+ "julian": 12643,
+ "juliana": 46059,
+ "julie": 22534,
+ "julie": 10505,
+ "julien": 32595,
+ "juliet": 20641,
+ "juliette": 44804,
+ "julio": 24888,
+ "julius": 20870,
+ "july": 2272,
+ "jum": 20791,
+ "jumbo": 24678,
+ "jume": 45989,
+ "jump": 5519,
+ "jump": 6423,
+ "jumped": 16901,
+ "jumper": 16558,
+ "jumpers": 36485,
+ "jumping": 11476,
+ "jumpman": 48803,
+ "jumps": 18911,
+ "jumpsuit": 31044,
+ "jun": 1637,
+ "jun": 7719,
+ "junction": 11320,
+ "june": 23188,
+ "june": 2345,
+ "jung": 13086,
+ "jung": 13031,
+ "jungkook": 20040,
+ "jungle": 42421,
+ "jungle": 10865,
+ "juni": 4029,
+ "junior": 21167,
+ "junior": 5027,
+ "juniors": 16811,
+ "juniper": 33829,
+ "junk": 16000,
+ "junkie": 27613,
+ "junkies": 41207,
+ "juno": 28845,
+ "junto": 34282,
+ "jupit": 15270,
+ "jupiter": 16212,
+ "jur": 15896,
+ "jura": 14715,
+ "jurassic": 28844,
+ "jurassic": 21255,
+ "jurgen": 39263,
+ "juris": 37010,
+ "jurisdic": 37714,
+ "jury": 12931,
+ "jus": 14999,
+ "just": 1770,
+ "just": 761,
+ "justi": 14700,
+ "justic": 30399,
+ "justice": 16904,
+ "justice": 3604,
+ "justicefor": 25812,
+ "justiceleague": 41929,
+ "justices": 44356,
+ "justified": 34546,
+ "justify": 28192,
+ "justin": 7537,
+ "justin": 4394,
+ "justinbieber": 12501,
+ "justine": 34418,
+ "justintrudeau": 32184,
+ "justsaying": 42922,
+ "juve": 47717,
+ "juve": 23092,
+ "juven": 12944,
+ "juvenile": 19333,
+ "juvent": 13908,
+ "juventus": 47378,
+ "juventus": 16208,
+ "jux": 33552,
+ "juxta": 34964,
+ "jv": 37932,
+ "jv": 11805,
+ "jw": 30221,
+ "jw": 24215,
+ "jy": 20979,
+ "jyo": 27378,
+ "jyoti": 48696,
+ "jä": 45381,
+ "k": 74,
+ "k": 330,
+ "ka": 1595,
+ "ka": 1525,
+ "kaa": 34496,
+ "kab": 6554,
+ "kab": 45134,
+ "kabaddi": 41749,
+ "kabir": 38619,
+ "kabo": 47974,
+ "kabul": 26160,
+ "kac": 21693,
+ "kach": 14341,
+ "kad": 10901,
+ "kade": 41130,
+ "kaduna": 38053,
+ "kae": 22542,
+ "kaeper": 30070,
+ "kaepernick": 30713,
+ "kaf": 19870,
+ "kag": 13666,
+ "kag": 31003,
+ "kah": 16068,
+ "kah": 15463,
+ "kahn": 35397,
+ "kai": 12752,
+ "kai": 9601,
+ "kaido": 40255,
+ "kail": 23623,
+ "kaine": 39028,
+ "kair": 33027,
+ "kaiser": 43685,
+ "kaiser": 29960,
+ "kait": 19326,
+ "kaitlyn": 34948,
+ "kaj": 44788,
+ "kaj": 40381,
+ "kak": 10401,
+ "kak": 40128,
+ "kaka": 47689,
+ "kaku": 30900,
+ "kal": 4187,
+ "kal": 18712,
+ "kala": 45453,
+ "kala": 33105,
+ "kalam": 40142,
+ "kalamaz": 42328,
+ "kalamazoo": 46264,
+ "kalb": 34483,
+ "kale": 17162,
+ "kale": 16625,
+ "kaleido": 41144,
+ "kali": 17844,
+ "kali": 26964,
+ "kalin": 42776,
+ "kalyan": 23825,
+ "kam": 4104,
+ "kam": 26011,
+ "kamal": 31371,
+ "kamal": 28619,
+ "kamala": 45003,
+ "kame": 45235,
+ "kamen": 40738,
+ "kami": 28707,
+ "kamloops": 36602,
+ "kamp": 35179,
+ "kamp": 29522,
+ "kampala": 37134,
+ "kan": 2532,
+ "kan": 8101,
+ "kana": 35178,
+ "kand": 17478,
+ "kane": 32218,
+ "kane": 9765,
+ "kang": 12226,
+ "kang": 20789,
+ "kangar": 20622,
+ "kangaroo": 25513,
+ "kani": 40907,
+ "kani": 41948,
+ "kann": 18533,
+ "kannada": 30053,
+ "kano": 28201,
+ "kans": 34012,
+ "kansas": 25507,
+ "kansas": 6539,
+ "kansascity": 46134,
+ "kant": 39923,
+ "kant": 47132,
+ "kanth": 24427,
+ "kanu": 44565,
+ "kany": 13590,
+ "kanye": 29680,
+ "kanye": 14965,
+ "kanyewest": 31943,
+ "kap": 6804,
+ "kap": 45279,
+ "kapam": 48561,
+ "kapil": 32337,
+ "kapil": 42709,
+ "kapilshar": 48978,
+ "kaplan": 37401,
+ "kapoor": 9117,
+ "kapp": 36717,
+ "kappa": 20239,
+ "kapur": 42371,
+ "kar": 1813,
+ "kar": 5933,
+ "kara": 12552,
+ "karab": 40916,
+ "karachi": 13671,
+ "karak": 40372,
+ "karan": 20077,
+ "karan": 20931,
+ "karanjohar": 47621,
+ "karao": 16262,
+ "karaoke": 16640,
+ "karate": 21211,
+ "kardashi": 13619,
+ "kardashian": 14578,
+ "kare": 14310,
+ "kare": 38354,
+ "kareem": 38885,
+ "kareena": 41569,
+ "karen": 17719,
+ "karen": 10349,
+ "kari": 15339,
+ "kari": 15161,
+ "karim": 33477,
+ "karin": 43917,
+ "karina": 40250,
+ "karl": 20967,
+ "karl": 13134,
+ "karla": 42309,
+ "karma": 17658,
+ "karnat": 13994,
+ "karnataka": 15515,
+ "karo": 45305,
+ "kart": 47841,
+ "kart": 21310,
+ "karthik": 41397,
+ "karti": 23053,
+ "kartikeyan": 32584,
+ "karting": 41655,
+ "kas": 6119,
+ "kas": 14372,
+ "kasa": 46111,
+ "kash": 6954,
+ "kash": 21371,
+ "kashi": 47945,
+ "kashmir": 20251,
+ "kashmir": 10783,
+ "kashmiri": 35331,
+ "kasi": 45870,
+ "kasi": 32819,
+ "kasich": 39666,
+ "kat": 2844,
+ "kat": 9341,
+ "kata": 14558,
+ "kate": 11620,
+ "kate": 6699,
+ "katelyn": 45963,
+ "kath": 7386,
+ "kath": 19745,
+ "katharine": 41473,
+ "katherine": 17687,
+ "kathle": 18721,
+ "kathleen": 21709,
+ "kathmandu": 34456,
+ "kathniel": 36159,
+ "kathr": 14905,
+ "kathryn": 33142,
+ "kathryn": 19999,
+ "kathy": 34775,
+ "kathy": 18795,
+ "kati": 6515,
+ "kati": 29928,
+ "katic": 48058,
+ "katie": 24117,
+ "katie": 9076,
+ "katniss": 47916,
+ "kato": 27573,
+ "katrin": 31282,
+ "katrina": 21397,
+ "katrinakaif": 45845,
+ "kats": 44213,
+ "katsu": 49296,
+ "katsu": 43712,
+ "katy": 17609,
+ "katy": 14435,
+ "katyperry": 28309,
+ "katz": 30790,
+ "kau": 9299,
+ "kau": 36895,
+ "kauai": 44050,
+ "kaufman": 37188,
+ "kaur": 30518,
+ "kav": 10228,
+ "kavan": 18576,
+ "kavanaugh": 20252,
+ "kaw": 10842,
+ "kaw": 42719,
+ "kawa": 33244,
+ "kawaii": 26891,
+ "kawasaki": 28227,
+ "kawhi": 41220,
+ "kay": 4673,
+ "kay": 9862,
+ "kaya": 22752,
+ "kayak": 27043,
+ "kayaking": 28977,
+ "kaye": 33003,
+ "kayla": 17139,
+ "kaylee": 47215,
+ "kayo": 37021,
+ "kaz": 8812,
+ "kaz": 39622,
+ "kazakh": 25451,
+ "kazakhstan": 26720,
+ "kazan": 47641,
+ "kb": 27381,
+ "kb": 19960,
+ "kbs": 27418,
+ "kc": 10869,
+ "kc": 8638,
+ "kca": 14347,
+ "kcon": 39970,
+ "kcr": 46181,
+ "kd": 21826,
+ "kd": 15597,
+ "kday": 31074,
+ "kdrama": 48628,
+ "ke": 643,
+ "ke": 618,
+ "kea": 47926,
+ "kean": 43288,
+ "keane": 28635,
+ "keanu": 40608,
+ "kear": 21562,
+ "kearney": 36435,
+ "keating": 40045,
+ "keaton": 29975,
+ "kebab": 36497,
+ "ked": 11730,
+ "ked": 1243,
+ "kee": 9724,
+ "kee": 6760,
+ "keef": 42323,
+ "keefe": 46965,
+ "keegan": 31122,
+ "keel": 48376,
+ "keen": 17714,
+ "keen": 13218,
+ "keenan": 36276,
+ "keep": 2924,
+ "keep": 1726,
+ "keeper": 7650,
+ "keepers": 16130,
+ "keepin": 41712,
+ "keeping": 38371,
+ "keeping": 4873,
+ "keepit": 28044,
+ "keeps": 6333,
+ "keer": 27412,
+ "keerth": 47500,
+ "keerthyofficial": 48185,
+ "kees": 10791,
+ "keg": 32785,
+ "keh": 41272,
+ "keh": 36983,
+ "kei": 18735,
+ "kei": 24835,
+ "keith": 18762,
+ "keith": 8252,
+ "kej": 15674,
+ "kejri": 16617,
+ "kejriwal": 17334,
+ "keke": 39195,
+ "kel": 2825,
+ "kel": 7553,
+ "kele": 41765,
+ "kell": 16082,
+ "kell": 40103,
+ "keller": 21407,
+ "kelley": 23776,
+ "kelli": 45852,
+ "kelli": 46190,
+ "kellie": 49224,
+ "kellogg": 44218,
+ "kelly": 13417,
+ "kelly": 5220,
+ "kelown": 31708,
+ "kelowna": 32963,
+ "kelsey": 42295,
+ "kelsey": 23018,
+ "kelvin": 32859,
+ "kem": 31013,
+ "kem": 17349,
+ "kemp": 18302,
+ "kemp": 25325,
+ "ken": 1838,
+ "ken": 1702,
+ "kend": 7497,
+ "kendal": 44836,
+ "kendall": 34607,
+ "kendall": 16238,
+ "kendra": 36074,
+ "kendrick": 41787,
+ "kendrick": 21953,
+ "kendricklamar": 47020,
+ "kenne": 6209,
+ "kennedy": 38631,
+ "kennedy": 9004,
+ "kennel": 39595,
+ "kenneth": 46900,
+ "kenneth": 17839,
+ "kenney": 41373,
+ "kenny": 20185,
+ "kenny": 9595,
+ "kens": 29765,
+ "kensing": 21505,
+ "kensington": 24988,
+ "kent": 13875,
+ "kent": 8214,
+ "kentu": 9045,
+ "kentucky": 32230,
+ "kentucky": 10014,
+ "keny": 17374,
+ "kenya": 6181,
+ "kenyan": 22624,
+ "kenyans": 36263,
+ "kenyatta": 31012,
+ "kenzie": 38087,
+ "keo": 43062,
+ "kept": 7737,
+ "ker": 2352,
+ "ker": 1485,
+ "keral": 35122,
+ "kerala": 11881,
+ "kered": 26690,
+ "kerel": 32232,
+ "keri": 43447,
+ "kermit": 40908,
+ "kern": 40150,
+ "kernel": 40684,
+ "kerr": 20491,
+ "kerri": 41849,
+ "kerry": 24795,
+ "kerry": 13097,
+ "kers": 30347,
+ "kers": 2880,
+ "kershaw": 40785,
+ "kerson": 42810,
+ "kerswednesday": 48152,
+ "kert": 47279,
+ "kes": 38398,
+ "kes": 1115,
+ "kesh": 19751,
+ "kesha": 36526,
+ "kest": 15080,
+ "ket": 2715,
+ "ket": 1236,
+ "ketball": 38240,
+ "ketch": 22590,
+ "ketch": 35371,
+ "ketchup": 26724,
+ "kete": 25404,
+ "keted": 41396,
+ "keting": 15951,
+ "keto": 27485,
+ "keto": 28754,
+ "kets": 1632,
+ "kett": 23124,
+ "kett": 10312,
+ "kettering": 43779,
+ "kettle": 41992,
+ "kettle": 24303,
+ "kev": 22758,
+ "kev": 29419,
+ "kevin": 9419,
+ "kevin": 4685,
+ "kew": 38014,
+ "kew": 31409,
+ "kex": 30251,
+ "key": 2891,
+ "key": 1458,
+ "keyan": 27617,
+ "keyboard": 13017,
+ "keyboards": 49237,
+ "keychain": 31050,
+ "keye": 40516,
+ "keye": 20635,
+ "keyes": 18336,
+ "keynes": 32462,
+ "keynote": 7556,
+ "keys": 48912,
+ "keys": 6355,
+ "keystone": 30688,
+ "keyword": 42284,
+ "keywords": 48122,
+ "kf": 33308,
+ "kf": 42119,
+ "kfc": 22032,
+ "kg": 36772,
+ "kg": 7817,
+ "kgs": 46629,
+ "kh": 2166,
+ "kh": 7452,
+ "kha": 7333,
+ "kha": 18929,
+ "khair": 43742,
+ "khaki": 41646,
+ "khal": 13070,
+ "khaled": 29343,
+ "khali": 11324,
+ "khalid": 27166,
+ "khalifa": 21389,
+ "khalil": 36229,
+ "kham": 24892,
+ "khan": 13318,
+ "khan": 3873,
+ "khand": 43384,
+ "khand": 31110,
+ "khanna": 29931,
+ "khar": 18340,
+ "khar": 28578,
+ "khart": 37458,
+ "khat": 43290,
+ "khe": 26360,
+ "kher": 43843,
+ "khi": 39062,
+ "khi": 42925,
+ "khil": 34101,
+ "khloe": 45312,
+ "kho": 14022,
+ "kho": 28774,
+ "khou": 30656,
+ "khs": 21239,
+ "khtar": 45593,
+ "khu": 14041,
+ "khur": 32083,
+ "khy": 40917,
+ "khz": 45604,
+ "ki": 848,
+ "ki": 2608,
+ "kia": 8712,
+ "kian": 43961,
+ "kian": 25708,
+ "kians": 44010,
+ "kib": 43108,
+ "kiba": 37207,
+ "kic": 24003,
+ "kic": 27633,
+ "kicchasu": 44665,
+ "kicchasudeep": 45560,
+ "kick": 4102,
+ "kick": 4289,
+ "kickass": 39299,
+ "kickboxing": 36041,
+ "kicked": 12479,
+ "kicker": 26338,
+ "kickin": 34597,
+ "kicking": 7802,
+ "kickoff": 10245,
+ "kicks": 6989,
+ "kickstart": 40780,
+ "kickstarter": 13228,
+ "kid": 3948,
+ "kid": 3551,
+ "kidd": 24082,
+ "kidding": 14535,
+ "kiddo": 36360,
+ "kiddos": 29205,
+ "kidlit": 39064,
+ "kidlit": 33515,
+ "kidlitart": 41600,
+ "kidman": 44931,
+ "kidnap": 45100,
+ "kidnapp": 16183,
+ "kidnapped": 24737,
+ "kidnapping": 32361,
+ "kidney": 37835,
+ "kidney": 14610,
+ "kids": 15561,
+ "kids": 1911,
+ "kidz": 41938,
+ "kie": 8544,
+ "kie": 3094,
+ "kiefer": 48026,
+ "kiel": 40940,
+ "kiel": 25509,
+ "kien": 28782,
+ "kier": 20403,
+ "kier": 35575,
+ "kieran": 29231,
+ "kies": 36601,
+ "kies": 4993,
+ "kiest": 29755,
+ "kiev": 24585,
+ "kiewicz": 47574,
+ "kigali": 40278,
+ "kii": 39340,
+ "kik": 36176,
+ "kiki": 23962,
+ "kiko": 40861,
+ "kil": 4912,
+ "kil": 39337,
+ "kildare": 45541,
+ "kili": 24386,
+ "kilig": 49172,
+ "kilimanjaro": 43470,
+ "kilkenny": 33805,
+ "kill": 6163,
+ "kill": 4367,
+ "killa": 41355,
+ "killarney": 48813,
+ "killed": 3733,
+ "killer": 28230,
+ "killer": 6613,
+ "killers": 17614,
+ "killin": 25903,
+ "killing": 37977,
+ "killing": 5923,
+ "killings": 24918,
+ "kills": 9795,
+ "kiln": 44150,
+ "kilo": 39281,
+ "kilom": 26285,
+ "kilometers": 39192,
+ "kilometres": 43278,
+ "kilt": 49319,
+ "kim": 4639,
+ "kim": 4606,
+ "kimber": 16796,
+ "kimberley": 39859,
+ "kimberly": 27465,
+ "kimchi": 41027,
+ "kimi": 31536,
+ "kimkardashian": 35400,
+ "kimmel": 27820,
+ "kimono": 40024,
+ "kin": 1442,
+ "kin": 2667,
+ "kina": 28518,
+ "kind": 7204,
+ "kind": 3044,
+ "kinda": 6612,
+ "kinder": 12711,
+ "kinder": 24159,
+ "kindergarten": 16749,
+ "kindle": 24704,
+ "kindle": 10746,
+ "kindleunlimited": 32164,
+ "kindly": 13952,
+ "kindness": 45112,
+ "kindness": 10614,
+ "kinds": 14879,
+ "kine": 17607,
+ "kineni": 49080,
+ "kinetic": 37699,
+ "king": 2365,
+ "king": 674,
+ "kingdom": 21870,
+ "kingdom": 7364,
+ "kingdomhearts": 48570,
+ "kingdoms": 43890,
+ "kingfisher": 34330,
+ "kingjames": 33153,
+ "kingly": 33642,
+ "kingof": 27878,
+ "kings": 18590,
+ "kings": 4232,
+ "kingsley": 41807,
+ "kingston": 40736,
+ "kingston": 15393,
+ "kini": 41644,
+ "kinky": 37006,
+ "kinney": 37233,
+ "kino": 39000,
+ "kins": 31060,
+ "kins": 4386,
+ "kinson": 12095,
+ "kio": 28210,
+ "kio": 39401,
+ "kiosk": 39146,
+ "kip": 27636,
+ "kip": 15986,
+ "kipp": 43329,
+ "kir": 3476,
+ "kir": 32949,
+ "kira": 33038,
+ "kiran": 43234,
+ "kiran": 36603,
+ "kirby": 17065,
+ "kiri": 34170,
+ "kiri": 45826,
+ "kirk": 10639,
+ "kirk": 11508,
+ "kirkland": 43061,
+ "kiro": 39749,
+ "kirstel": 46483,
+ "kirsten": 31813,
+ "kirsty": 37787,
+ "kis": 3199,
+ "kis": 22796,
+ "kish": 25662,
+ "kiss": 43757,
+ "kiss": 5946,
+ "kissed": 22561,
+ "kisses": 47876,
+ "kisses": 11220,
+ "kissing": 18637,
+ "kistan": 29580,
+ "kit": 4566,
+ "kit": 4274,
+ "kita": 29961,
+ "kitch": 3850,
+ "kitchen": 18131,
+ "kitchen": 4485,
+ "kitchener": 34428,
+ "kitchens": 28301,
+ "kite": 47777,
+ "kite": 19867,
+ "kites": 45829,
+ "kits": 13730,
+ "kitt": 10840,
+ "kitten": 13063,
+ "kittens": 17216,
+ "kitties": 36013,
+ "kitty": 25067,
+ "kitty": 8417,
+ "kiwan": 38709,
+ "kiwanis": 46513,
+ "kiwi": 22440,
+ "kiwis": 48108,
+ "kiya": 41610,
+ "kj": 27385,
+ "kj": 28238,
+ "kja": 41048,
+ "kjv": 37387,
+ "kk": 4390,
+ "kk": 10849,
+ "kka": 19002,
+ "kke": 44239,
+ "kker": 32399,
+ "kki": 44672,
+ "kkk": 20073,
+ "kkkk": 15834,
+ "kkkk": 47160,
+ "kkkkkkkk": 31042,
+ "kko": 43965,
+ "kkr": 40855,
+ "kl": 8498,
+ "kl": 14134,
+ "kla": 11249,
+ "klan": 46935,
+ "klar": 41374,
+ "klaus": 31788,
+ "kle": 7612,
+ "kle": 7432,
+ "klein": 33475,
+ "klein": 17579,
+ "kley": 18594,
+ "kli": 31640,
+ "klin": 44809,
+ "klin": 41647,
+ "kline": 47580,
+ "kling": 40270,
+ "klm": 38859,
+ "klo": 15296,
+ "klopp": 26446,
+ "kltu": 25978,
+ "klu": 21852,
+ "kly": 45090,
+ "km": 29954,
+ "km": 4590,
+ "kman": 33312,
+ "kms": 24996,
+ "kn": 4825,
+ "kn": 23693,
+ "knapp": 33945,
+ "kne": 6358,
+ "knee": 9897,
+ "knees": 19115,
+ "kner": 31578,
+ "knew": 5009,
+ "kni": 6312,
+ "knick": 33286,
+ "knicks": 17657,
+ "knife": 44176,
+ "knife": 8960,
+ "knigh": 43099,
+ "knight": 17949,
+ "knight": 7355,
+ "knights": 10385,
+ "knit": 18745,
+ "knit": 14313,
+ "knitted": 28151,
+ "knitting": 18863,
+ "knives": 20910,
+ "kno": 1482,
+ "kno": 25362,
+ "knob": 29736,
+ "knobs": 47504,
+ "knock": 14195,
+ "knock": 11583,
+ "knocked": 15325,
+ "knocking": 20380,
+ "knockout": 22602,
+ "knocks": 24296,
+ "knoll": 43882,
+ "knot": 18412,
+ "knots": 32428,
+ "know": 4179,
+ "know": 1038,
+ "knowing": 9267,
+ "knowledge": 27864,
+ "knowledge": 5510,
+ "knowledgeable": 43391,
+ "knowles": 32631,
+ "known": 3102,
+ "knows": 4309,
+ "knowyour": 30773,
+ "knox": 18630,
+ "knox": 21833,
+ "knoxville": 23232,
+ "knu": 14812,
+ "knuck": 21333,
+ "knuckle": 42023,
+ "knuckles": 40127,
+ "knw": 40803,
+ "ko": 1313,
+ "ko": 2448,
+ "koala": 36654,
+ "kobe": 42644,
+ "kobe": 14470,
+ "kobo": 42390,
+ "koch": 25331,
+ "kochi": 36710,
+ "kodak": 30425,
+ "kodi": 46611,
+ "kof": 17528,
+ "koff": 47303,
+ "kofi": 40400,
+ "koh": 13379,
+ "koh": 31216,
+ "kohl": 48479,
+ "kohli": 17549,
+ "koi": 28150,
+ "kojima": 46419,
+ "kok": 32045,
+ "kok": 11225,
+ "koko": 42426,
+ "koko": 40003,
+ "kol": 7142,
+ "kol": 31023,
+ "kolkata": 18011,
+ "kom": 6686,
+ "kom": 24181,
+ "kombat": 29670,
+ "kombucha": 48615,
+ "komo": 31820,
+ "kon": 5743,
+ "kon": 29519,
+ "kona": 30203,
+ "kong": 31784,
+ "kong": 6506,
+ "konstant": 46583,
+ "koo": 12225,
+ "koo": 40472,
+ "kook": 16003,
+ "kool": 36755,
+ "kool": 26444,
+ "kop": 16623,
+ "kop": 38999,
+ "kor": 6428,
+ "kor": 24175,
+ "kore": 3919,
+ "korea": 5915,
+ "korean": 31949,
+ "korean": 8034,
+ "kori": 42842,
+ "korn": 45412,
+ "korn": 31492,
+ "kors": 34535,
+ "kos": 47438,
+ "kos": 22951,
+ "kosh": 45233,
+ "kosher": 36502,
+ "koso": 23892,
+ "kosovo": 28343,
+ "kot": 23323,
+ "kot": 20701,
+ "kota": 21735,
+ "koto": 40945,
+ "koto": 29977,
+ "kou": 18502,
+ "kou": 39614,
+ "kour": 34134,
+ "kov": 17733,
+ "kov": 15156,
+ "kova": 26185,
+ "koval": 47903,
+ "kovic": 16886,
+ "kovich": 44794,
+ "kovsky": 33384,
+ "kow": 29764,
+ "kow": 23919,
+ "kowski": 17649,
+ "koz": 29598,
+ "kp": 16174,
+ "kp": 16894,
+ "kpa": 38759,
+ "kph": 41138,
+ "kpk": 42094,
+ "kpmg": 38243,
+ "kpop": 29534,
+ "kpop": 15859,
+ "kprc": 47832,
+ "kprs": 46253,
+ "kr": 7309,
+ "kr": 14107,
+ "kra": 5762,
+ "kraft": 28057,
+ "kraja": 29016,
+ "kraken": 48408,
+ "krakow": 40033,
+ "kram": 19075,
+ "kramer": 27495,
+ "kran": 33243,
+ "kranti": 47969,
+ "krat": 30470,
+ "kre": 8362,
+ "kreme": 43140,
+ "kremlin": 33979,
+ "kri": 3679,
+ "kris": 35251,
+ "kris": 12261,
+ "krish": 11487,
+ "krishna": 15863,
+ "krishnan": 46535,
+ "krispy": 49292,
+ "krist": 16490,
+ "kristen": 28881,
+ "kristen": 16644,
+ "kristi": 26895,
+ "kristin": 35408,
+ "kristin": 26785,
+ "kristina": 33180,
+ "krit": 36265,
+ "kro": 16193,
+ "kroger": 36344,
+ "kron": 25999,
+ "kru": 10609,
+ "kruger": 32948,
+ "krun": 43084,
+ "kry": 13995,
+ "krystal": 36554,
+ "ks": 10470,
+ "ks": 662,
+ "ksa": 25439,
+ "ksh": 36594,
+ "kst": 17420,
+ "kstate": 48590,
+ "ksu": 43496,
+ "kswx": 36180,
+ "kt": 17238,
+ "kt": 7792,
+ "ktm": 33989,
+ "ktn": 42170,
+ "kton": 37848,
+ "kts": 48577,
+ "ktv": 36444,
+ "ku": 1836,
+ "ku": 4827,
+ "kuala": 30336,
+ "kubball": 48995,
+ "kuber": 41336,
+ "kubernetes": 45144,
+ "kubrick": 37032,
+ "kuch": 39394,
+ "kud": 40818,
+ "kudos": 14481,
+ "kul": 11325,
+ "kul": 31514,
+ "kum": 18086,
+ "kum": 28148,
+ "kuma": 43139,
+ "kuma": 33920,
+ "kumar": 22329,
+ "kumar": 7674,
+ "kumb": 31391,
+ "kun": 6849,
+ "kun": 21842,
+ "kung": 39656,
+ "kung": 22347,
+ "kunst": 37881,
+ "kup": 39023,
+ "kups": 27240,
+ "kur": 4862,
+ "kurdi": 23504,
+ "kurdish": 21644,
+ "kurdistan": 24459,
+ "kurds": 20888,
+ "kuri": 46375,
+ "kuro": 28239,
+ "kuro": 47826,
+ "kurt": 31903,
+ "kurt": 14527,
+ "kus": 27618,
+ "kus": 27505,
+ "kush": 22264,
+ "kush": 24594,
+ "kushner": 36716,
+ "kut": 17283,
+ "kut": 36965,
+ "kuwait": 19679,
+ "kuya": 34815,
+ "kuz": 33253,
+ "kv": 27594,
+ "kv": 34249,
+ "kw": 10072,
+ "kw": 18339,
+ "kwa": 32784,
+ "kwa": 48576,
+ "kwame": 46681,
+ "kwan": 37100,
+ "kwan": 39447,
+ "kwang": 40260,
+ "kwe": 26050,
+ "kwi": 35327,
+ "kwon": 36369,
+ "kx": 28190,
+ "kx": 46442,
+ "ky": 2018,
+ "ky": 2383,
+ "kya": 29142,
+ "kyc": 37758,
+ "kyiv": 36422,
+ "kyle": 15847,
+ "kyle": 7539,
+ "kylie": 28282,
+ "kylie": 17983,
+ "kyliejenner": 47232,
+ "kylo": 47704,
+ "kyo": 13150,
+ "kyo": 6281,
+ "kyoto": 23223,
+ "kyr": 26329,
+ "kyrgy": 40013,
+ "kyrgyz": 48346,
+ "kyrie": 21857,
+ "kyu": 28296,
+ "kyu": 25490,
+ "kyuhyun": 37229,
+ "kyung": 41058,
+ "kyungsoo": 30280,
+ "kywx": 39940,
+ "kz": 48743,
+ "kz": 36848,
+ "kzn": 38264,
+ "kö": 32437,
+ "l": 75,
+ "l": 331,
+ "la": 572,
+ "la": 1210,
+ "laa": 44642,
+ "lab": 3537,
+ "lab": 4352,
+ "labe": 25749,
+ "label": 12235,
+ "label": 9093,
+ "labeled": 32720,
+ "labeling": 36825,
+ "labelled": 45188,
+ "labels": 17413,
+ "lable": 31879,
+ "labor": 11201,
+ "labor": 7878,
+ "laboratories": 43421,
+ "laboratory": 17664,
+ "laborday": 39324,
+ "labou": 32700,
+ "labour": 19586,
+ "labour": 6019,
+ "labourdoorstep": 37008,
+ "labout": 35961,
+ "labra": 37067,
+ "labrador": 25409,
+ "labs": 12021,
+ "laby": 29131,
+ "labyrin": 31782,
+ "labyrinth": 35594,
+ "lac": 4477,
+ "lac": 16189,
+ "lace": 30012,
+ "lace": 5421,
+ "laced": 36800,
+ "laces": 23281,
+ "lacey": 31754,
+ "lach": 30558,
+ "lack": 24915,
+ "lack": 8069,
+ "lacking": 30080,
+ "lacks": 34388,
+ "laco": 45882,
+ "lacrosse": 12915,
+ "lacy": 38645,
+ "lad": 15991,
+ "lad": 10707,
+ "ladak": 42312,
+ "ladakh": 45295,
+ "ladder": 16637,
+ "ladders": 47125,
+ "lade": 26447,
+ "laden": 28634,
+ "ladi": 12934,
+ "ladies": 28932,
+ "ladies": 3431,
+ "lads": 9803,
+ "lady": 7275,
+ "lady": 2909,
+ "ladybird": 43389,
+ "ladybug": 40038,
+ "ladygaga": 21232,
+ "laf": 47555,
+ "lafayette": 22683,
+ "lag": 30932,
+ "lag": 20394,
+ "laga": 30161,
+ "lage": 24369,
+ "lager": 36811,
+ "lager": 22989,
+ "lagh": 37237,
+ "laghate": 47565,
+ "laghateparth": 48780,
+ "lagi": 39786,
+ "lago": 42698,
+ "lago": 31476,
+ "lagoon": 22753,
+ "lagos": 12728,
+ "lagun": 18500,
+ "laguna": 23609,
+ "lah": 27315,
+ "lah": 4299,
+ "lahat": 42164,
+ "lahore": 16733,
+ "lai": 23947,
+ "laid": 42560,
+ "laid": 11160,
+ "lain": 46958,
+ "lain": 17151,
+ "laine": 35860,
+ "lair": 31981,
+ "lais": 34923,
+ "lak": 12890,
+ "lak": 26793,
+ "lake": 6441,
+ "lake": 2553,
+ "lakedistrict": 26437,
+ "lakel": 26133,
+ "lakeland": 34306,
+ "laker": 45717,
+ "lakers": 13570,
+ "lakes": 9265,
+ "lakeshore": 42595,
+ "lakeside": 30915,
+ "lakewood": 36417,
+ "lakh": 21487,
+ "lakhs": 37985,
+ "lakings": 34289,
+ "lakota": 45510,
+ "laksh": 24937,
+ "lakshmi": 39682,
+ "lal": 12301,
+ "lal": 19430,
+ "lala": 33661,
+ "lali": 21726,
+ "laliga": 32383,
+ "lam": 2022,
+ "lam": 5704,
+ "lama": 26049,
+ "lamar": 28678,
+ "lamar": 17284,
+ "lamb": 19863,
+ "lamb": 10034,
+ "lambda": 36687,
+ "lambert": 14574,
+ "lambeth": 43410,
+ "lambo": 45464,
+ "lamborgh": 18709,
+ "lamborghini": 19462,
+ "lambs": 30361,
+ "lame": 23192,
+ "lamin": 22337,
+ "laminated": 49079,
+ "lamo": 41461,
+ "lamont": 46719,
+ "lamp": 26700,
+ "lamp": 10725,
+ "lampard": 39989,
+ "lamps": 23424,
+ "lan": 1193,
+ "lan": 4872,
+ "lana": 15406,
+ "lanapar": 47437,
+ "lanaparrilla": 47819,
+ "lanc": 11872,
+ "lanca": 15694,
+ "lancashire": 20939,
+ "lancaster": 16446,
+ "lance": 26025,
+ "lance": 11609,
+ "lancer": 38195,
+ "lancers": 46392,
+ "lancia": 48698,
+ "lancs": 47540,
+ "land": 1567,
+ "land": 973,
+ "lande": 36556,
+ "landed": 9873,
+ "lander": 37247,
+ "lander": 9666,
+ "landers": 20019,
+ "landfall": 38465,
+ "landfill": 34947,
+ "landia": 41384,
+ "landing": 8292,
+ "landings": 46104,
+ "landlord": 28938,
+ "landlords": 35283,
+ "landmark": 15208,
+ "landmarks": 30393,
+ "lando": 25463,
+ "lando": 7065,
+ "landon": 32748,
+ "landrover": 38125,
+ "landry": 36137,
+ "lands": 40223,
+ "lands": 2961,
+ "landsc": 4384,
+ "landscape": 21123,
+ "landscape": 5727,
+ "landscapephotography": 28125,
+ "landscapes": 15344,
+ "landscaping": 25642,
+ "landslide": 31954,
+ "lane": 25534,
+ "lane": 3980,
+ "lanes": 10345,
+ "laney": 38552,
+ "lang": 7969,
+ "lang": 8578,
+ "lange": 32021,
+ "langford": 45615,
+ "langley": 28595,
+ "langu": 4095,
+ "language": 46103,
+ "language": 4781,
+ "languages": 13527,
+ "lani": 22964,
+ "lanka": 16221,
+ "lankan": 40531,
+ "lannister": 49056,
+ "lans": 43550,
+ "lansing": 30805,
+ "lant": 44504,
+ "lanta": 44768,
+ "lantern": 17185,
+ "lanterns": 33676,
+ "lantic": 32601,
+ "lantic": 27678,
+ "lants": 38425,
+ "lanyard": 46808,
+ "lao": 32475,
+ "lao": 29521,
+ "laos": 34353,
+ "lap": 7213,
+ "lap": 8639,
+ "lapd": 32557,
+ "lapel": 47961,
+ "lapland": 43633,
+ "laps": 18711,
+ "lapse": 33365,
+ "laptop": 10464,
+ "laptops": 32189,
+ "laq": 45026,
+ "lar": 1592,
+ "lar": 1652,
+ "lara": 19435,
+ "lard": 40347,
+ "lare": 22415,
+ "laredo": 48427,
+ "large": 40234,
+ "large": 3638,
+ "largely": 21418,
+ "larger": 12567,
+ "largest": 4960,
+ "largo": 44161,
+ "lari": 34676,
+ "lark": 43164,
+ "lark": 23536,
+ "larkin": 34769,
+ "larry": 18642,
+ "larry": 8242,
+ "lars": 8669,
+ "larsen": 39721,
+ "larson": 27973,
+ "larvae": 44840,
+ "las": 8295,
+ "las": 2552,
+ "lasag": 31210,
+ "lasagna": 40683,
+ "lasalle": 43866,
+ "laser": 25607,
+ "laser": 9885,
+ "lasers": 37060,
+ "lash": 31995,
+ "lash": 18480,
+ "lashes": 21015,
+ "lass": 24203,
+ "lass": 18263,
+ "lassic": 39430,
+ "last": 10600,
+ "last": 952,
+ "lasted": 25711,
+ "lasting": 13434,
+ "lastnight": 30159,
+ "lasts": 20141,
+ "lasvegas": 17789,
+ "lat": 1591,
+ "lat": 28437,
+ "lata": 47114,
+ "latam": 40012,
+ "late": 13267,
+ "late": 2325,
+ "latel": 49035,
+ "lately": 11824,
+ "latepost": 48328,
+ "later": 24109,
+ "later": 2941,
+ "lateral": 26646,
+ "latest": 46805,
+ "latest": 2053,
+ "latex": 27520,
+ "lati": 16357,
+ "latimes": 43356,
+ "latin": 16695,
+ "latin": 9888,
+ "latina": 27936,
+ "latino": 45734,
+ "latino": 19470,
+ "latinos": 40233,
+ "lation": 6191,
+ "latitude": 37392,
+ "lative": 15719,
+ "lator": 9291,
+ "lators": 28278,
+ "latt": 33561,
+ "latte": 17697,
+ "latter": 26198,
+ "latvia": 30034,
+ "lau": 1853,
+ "lau": 23090,
+ "lauderdale": 24352,
+ "laugh": 4969,
+ "laugh": 6332,
+ "laughed": 16746,
+ "laughing": 8301,
+ "laughs": 14322,
+ "laughter": 10722,
+ "laun": 2944,
+ "launch": 31168,
+ "launch": 2904,
+ "launched": 6125,
+ "launcher": 35782,
+ "launches": 7023,
+ "launching": 8565,
+ "laundering": 34079,
+ "laundry": 14797,
+ "laur": 15256,
+ "laura": 17091,
+ "laura": 7763,
+ "laure": 16932,
+ "laureate": 25675,
+ "laurel": 43370,
+ "laurel": 19942,
+ "lauren": 10456,
+ "lauren": 7634,
+ "laurence": 29353,
+ "laurent": 23226,
+ "laurie": 20326,
+ "laus": 38895,
+ "laus": 28111,
+ "lause": 22269,
+ "laut": 47688,
+ "lav": 13767,
+ "lav": 26919,
+ "lava": 16765,
+ "laven": 15047,
+ "lavender": 16033,
+ "laver": 28188,
+ "lavish": 35443,
+ "law": 2874,
+ "law": 2606,
+ "lawful": 33845,
+ "lawler": 47862,
+ "lawless": 39468,
+ "lawmaker": 37169,
+ "lawmakers": 21190,
+ "lawn": 31675,
+ "lawn": 11024,
+ "lawrence": 32221,
+ "lawrence": 8820,
+ "laws": 7306,
+ "lawson": 22152,
+ "lawsuit": 14346,
+ "lawsuits": 44331,
+ "lawyer": 10552,
+ "lawyers": 14232,
+ "lax": 17750,
+ "lax": 10024,
+ "lay": 7205,
+ "lay": 6360,
+ "laye": 25995,
+ "layer": 12411,
+ "layered": 28520,
+ "layers": 15900,
+ "laying": 12333,
+ "layla": 45050,
+ "layne": 48721,
+ "layo": 21738,
+ "layoffs": 29019,
+ "layout": 17314,
+ "lays": 19546,
+ "layton": 38061,
+ "laz": 18806,
+ "lazar": 33075,
+ "lazarus": 49126,
+ "laze": 41559,
+ "lazer": 43735,
+ "lazio": 33010,
+ "lazy": 32614,
+ "lazy": 10753,
+ "lb": 21958,
+ "lb": 7422,
+ "lbc": 37694,
+ "lbj": 45683,
+ "lbloggers": 48695,
+ "lbs": 8912,
+ "lc": 9584,
+ "lc": 7225,
+ "lcd": 21356,
+ "lcfc": 25339,
+ "lcs": 32279,
+ "ld": 1431,
+ "ld": 730,
+ "lder": 6945,
+ "lders": 43221,
+ "ldn": 37050,
+ "ldn": 2517,
+ "ldnont": 25827,
+ "ldnt": 21690,
+ "ldr": 37279,
+ "lds": 31235,
+ "le": 534,
+ "le": 579,
+ "lea": 2246,
+ "lea": 13324,
+ "leach": 35527,
+ "lead": 1328,
+ "lead": 2784,
+ "leader": 14806,
+ "leader": 3236,
+ "leaderboard": 34519,
+ "leaders": 3546,
+ "leadership": 36876,
+ "leadership": 3652,
+ "leading": 3833,
+ "leads": 5335,
+ "leaf": 9377,
+ "leaf": 7232,
+ "leaflet": 38289,
+ "leaflets": 39014,
+ "leafs": 16688,
+ "leafy": 42616,
+ "leagu": 13317,
+ "league": 16635,
+ "league": 2313,
+ "leagueof": 26022,
+ "leagueoflegends": 31737,
+ "leagues": 19888,
+ "leah": 24350,
+ "leah": 19308,
+ "leak": 42900,
+ "leak": 15489,
+ "leaked": 14353,
+ "leaking": 34097,
+ "leaks": 15657,
+ "leam": 39606,
+ "lean": 12447,
+ "lean": 8208,
+ "leaning": 24411,
+ "leanne": 41448,
+ "leans": 9357,
+ "leap": 29129,
+ "leap": 15392,
+ "leaps": 48080,
+ "lear": 1146,
+ "lear": 27663,
+ "learn": 16959,
+ "learn": 1768,
+ "learned": 6048,
+ "learnenglish": 49040,
+ "learner": 33547,
+ "learners": 19572,
+ "learning": 22632,
+ "learning": 2378,
+ "learns": 17569,
+ "learnt": 18959,
+ "leary": 36051,
+ "lease": 49041,
+ "lease": 14394,
+ "leased": 48352,
+ "leash": 36192,
+ "leasing": 29160,
+ "least": 3651,
+ "leather": 21417,
+ "leather": 5862,
+ "leau": 26498,
+ "leav": 3198,
+ "leave": 37512,
+ "leave": 3258,
+ "leaves": 5579,
+ "leaving": 5216,
+ "leban": 9360,
+ "lebanese": 23819,
+ "lebanon": 11695,
+ "leblanc": 46381,
+ "lebo": 44184,
+ "lebron": 11971,
+ "lebu": 47030,
+ "lec": 944,
+ "lec": 35374,
+ "leche": 46197,
+ "lect": 45392,
+ "lection": 18252,
+ "lections": 30995,
+ "lecture": 6617,
+ "lecturer": 23795,
+ "lectures": 21118,
+ "led": 8767,
+ "led": 912,
+ "ledge": 23647,
+ "ledge": 4815,
+ "ledger": 26817,
+ "leds": 36763,
+ "lee": 6224,
+ "lee": 2592,
+ "leed": 16483,
+ "leed": 40206,
+ "leeds": 38900,
+ "leeds": 7420,
+ "leek": 34585,
+ "leeminho": 37831,
+ "leen": 35311,
+ "leen": 15940,
+ "leep": 48875,
+ "leep": 10191,
+ "lees": 29324,
+ "lees": 34056,
+ "lef": 9152,
+ "left": 33949,
+ "left": 1823,
+ "leftist": 35143,
+ "lefto": 17437,
+ "leftover": 26414,
+ "leftovers": 28481,
+ "lefty": 33935,
+ "leg": 1211,
+ "leg": 4924,
+ "lega": 38674,
+ "legacy": 44108,
+ "legacy": 6447,
+ "legal": 17743,
+ "legal": 3998,
+ "legalization": 40584,
+ "legalize": 42921,
+ "legally": 14152,
+ "legate": 46009,
+ "lege": 8065,
+ "legen": 6105,
+ "legend": 5480,
+ "legend": 3539,
+ "legendary": 6053,
+ "legendof": 47915,
+ "legends": 6396,
+ "leges": 15356,
+ "legg": 18474,
+ "legg": 32511,
+ "legged": 25830,
+ "leggings": 22895,
+ "leggo": 43441,
+ "legi": 11183,
+ "legion": 35503,
+ "legion": 14525,
+ "legis": 7200,
+ "legislat": 16486,
+ "legislation": 14143,
+ "legislative": 16755,
+ "legislators": 31572,
+ "legislature": 22309,
+ "legit": 12563,
+ "legitim": 17656,
+ "legitimate": 24491,
+ "lego": 28117,
+ "lego": 7849,
+ "legos": 45359,
+ "legs": 7072,
+ "leh": 19105,
+ "leh": 29298,
+ "lehead": 28090,
+ "lehigh": 34527,
+ "lehman": 46094,
+ "lei": 15828,
+ "lei": 21830,
+ "leia": 32723,
+ "leic": 35073,
+ "leica": 30206,
+ "leice": 10026,
+ "leicester": 28795,
+ "leicester": 11510,
+ "leicestershire": 45358,
+ "leigh": 14849,
+ "leigh": 9292,
+ "leighton": 30782,
+ "leila": 41342,
+ "lein": 20026,
+ "lein": 28551,
+ "leinster": 32242,
+ "leip": 36401,
+ "leipzig": 41860,
+ "leis": 13133,
+ "leisure": 15849,
+ "leit": 35446,
+ "leith": 34141,
+ "lek": 26626,
+ "lek": 36535,
+ "lel": 46623,
+ "lele": 26075,
+ "lem": 10213,
+ "lem": 8428,
+ "leman": 24478,
+ "lemans": 26694,
+ "lement": 9693,
+ "lements": 15833,
+ "lemme": 23318,
+ "lemon": 12272,
+ "lemon": 7184,
+ "lemonade": 18884,
+ "lemons": 29576,
+ "lemore": 41147,
+ "len": 3687,
+ "len": 2159,
+ "lena": 22038,
+ "lend": 45397,
+ "lend": 24987,
+ "lender": 44734,
+ "lenders": 42443,
+ "lending": 20209,
+ "lene": 17628,
+ "leness": 36551,
+ "leng": 7861,
+ "length": 10130,
+ "lengths": 31858,
+ "lengthy": 32624,
+ "lenin": 41760,
+ "lennon": 18360,
+ "lennox": 45748,
+ "lenny": 48448,
+ "lenny": 30124,
+ "leno": 45357,
+ "lenovo": 25886,
+ "lens": 8666,
+ "lenses": 21264,
+ "lent": 20943,
+ "lent": 22605,
+ "lentil": 41511,
+ "lentils": 44269,
+ "leo": 24008,
+ "leo": 8312,
+ "leon": 6581,
+ "leon": 9763,
+ "leonard": 43849,
+ "leonard": 13142,
+ "leonardo": 20282,
+ "leone": 22864,
+ "leop": 11234,
+ "leopard": 15931,
+ "leopards": 40996,
+ "leopold": 45501,
+ "lep": 48884,
+ "leppard": 41656,
+ "lepre": 45641,
+ "ler": 5587,
+ "ler": 1803,
+ "lero": 15067,
+ "lerosis": 35455,
+ "leroy": 32441,
+ "lers": 6247,
+ "lery": 38184,
+ "les": 4339,
+ "les": 840,
+ "lesbian": 17419,
+ "lesbians": 43182,
+ "lesh": 32282,
+ "lesley": 25506,
+ "lesli": 13649,
+ "leslie": 16244,
+ "lesn": 39568,
+ "lesnar": 42223,
+ "less": 3242,
+ "less": 1285,
+ "lesser": 20369,
+ "lessly": 13103,
+ "lessness": 24847,
+ "lesson": 7714,
+ "lessons": 7199,
+ "lest": 24372,
+ "lest": 6794,
+ "lester": 23157,
+ "lester": 24023,
+ "lestwe": 29726,
+ "lestweforget": 30273,
+ "let": 1898,
+ "let": 1094,
+ "leta": 34319,
+ "lete": 34078,
+ "letes": 6815,
+ "leth": 30022,
+ "leth": 42462,
+ "lethal": 21905,
+ "lethbridge": 48390,
+ "leti": 34176,
+ "letics": 14504,
+ "letit": 46423,
+ "leto": 32203,
+ "leton": 37674,
+ "leton": 7462,
+ "lets": 10448,
+ "lets": 3243,
+ "letsgo": 16967,
+ "letsgo": 29789,
+ "letstalk": 35591,
+ "lett": 22428,
+ "lett": 9778,
+ "lette": 41798,
+ "lette": 10301,
+ "letter": 15567,
+ "letter": 4861,
+ "lettering": 26382,
+ "letterman": 38447,
+ "letters": 9181,
+ "letting": 9510,
+ "letto": 35449,
+ "lettu": 17933,
+ "lettuce": 18573,
+ "leu": 15691,
+ "leuke": 31031,
+ "leukemia": 32097,
+ "leum": 21571,
+ "leur": 45806,
+ "lev": 17022,
+ "lev": 29950,
+ "levan": 42543,
+ "leve": 36271,
+ "level": 21682,
+ "level": 2931,
+ "leveled": 48453,
+ "levels": 6295,
+ "leven": 44792,
+ "leven": 34729,
+ "lever": 20178,
+ "lever": 23094,
+ "leverage": 24030,
+ "leveraging": 37948,
+ "levi": 25630,
+ "levi": 19113,
+ "leviathan": 41736,
+ "levin": 36949,
+ "levine": 26594,
+ "levit": 22715,
+ "levy": 17147,
+ "lew": 5063,
+ "lew": 25329,
+ "lewan": 48349,
+ "lewd": 45241,
+ "lewes": 40431,
+ "lewi": 19589,
+ "lewis": 22043,
+ "lewis": 6020,
+ "lewisham": 37385,
+ "lewisham": 47633,
+ "lewishamilton": 42960,
+ "lewood": 37951,
+ "lex": 6586,
+ "lex": 9658,
+ "lexa": 48259,
+ "lexi": 44231,
+ "lexi": 24679,
+ "lexington": 22308,
+ "lexus": 20694,
+ "ley": 2565,
+ "ley": 1066,
+ "leye": 37061,
+ "leys": 45609,
+ "leys": 14834,
+ "leyton": 46573,
+ "lez": 26442,
+ "lf": 33960,
+ "lf": 22078,
+ "lfc": 37826,
+ "lfc": 8267,
+ "lfw": 28514,
+ "lg": 4546,
+ "lg": 11368,
+ "lga": 39348,
+ "lgb": 25401,
+ "lgbt": 11743,
+ "lgbt": 9592,
+ "lgbti": 42730,
+ "lgbtq": 47625,
+ "lgbtq": 14939,
+ "lgm": 39389,
+ "lh": 27794,
+ "lh": 31159,
+ "lhp": 45092,
+ "lhs": 33170,
+ "li": 554,
+ "li": 4250,
+ "lia": 26118,
+ "lia": 6964,
+ "liability": 29139,
+ "liaison": 39294,
+ "liam": 5258,
+ "liam": 7167,
+ "lian": 18058,
+ "liance": 40864,
+ "liar": 16334,
+ "liars": 23863,
+ "lias": 46021,
+ "lib": 10249,
+ "lib": 13345,
+ "libby": 36832,
+ "libdems": 40869,
+ "liber": 3425,
+ "liberal": 48032,
+ "liberal": 9985,
+ "liberalism": 40018,
+ "liberals": 15981,
+ "liberated": 38690,
+ "liberation": 19507,
+ "liberia": 32208,
+ "libertarian": 35067,
+ "liberties": 48623,
+ "liberty": 23397,
+ "liberty": 8480,
+ "libr": 2856,
+ "libra": 43038,
+ "librarian": 25148,
+ "librarians": 37806,
+ "libraries": 14277,
+ "library": 25713,
+ "library": 3519,
+ "libre": 49210,
+ "libre": 31681,
+ "libs": 26401,
+ "liby": 36390,
+ "libya": 16417,
+ "libyan": 42319,
+ "lic": 2508,
+ "lic": 3376,
+ "lice": 45691,
+ "licen": 6706,
+ "licence": 20550,
+ "license": 10337,
+ "licensed": 18752,
+ "licenses": 36414,
+ "licensing": 24219,
+ "lich": 23979,
+ "lich": 25875,
+ "lick": 29197,
+ "lick": 17541,
+ "licking": 33013,
+ "licks": 42117,
+ "lics": 44552,
+ "lid": 39369,
+ "lid": 17678,
+ "lidge": 45558,
+ "lido": 35683,
+ "lids": 41609,
+ "lie": 6570,
+ "lie": 2538,
+ "lieb": 45387,
+ "liebe": 37749,
+ "lied": 6486,
+ "lief": 38428,
+ "lien": 45716,
+ "lier": 3626,
+ "liers": 19303,
+ "lies": 37236,
+ "lies": 3205,
+ "liest": 14020,
+ "liet": 41107,
+ "lieu": 20401,
+ "lieu": 35313,
+ "lieutenant": 22538,
+ "lif": 16456,
+ "life": 2666,
+ "life": 970,
+ "lifeat": 27801,
+ "lifeboat": 37404,
+ "lifecycle": 49171,
+ "lifein": 48447,
+ "lifeis": 24824,
+ "lifeisgood": 46433,
+ "lifel": 15025,
+ "lifeline": 38438,
+ "lifelong": 21358,
+ "lifeof": 36061,
+ "lifesaving": 48016,
+ "lifespan": 49257,
+ "lifestyle": 46512,
+ "lifestyle": 7037,
+ "lifestyles": 48521,
+ "lifetime": 48737,
+ "lifetime": 9107,
+ "liff": 34404,
+ "liffe": 38942,
+ "lift": 33146,
+ "lift": 6779,
+ "lifted": 16783,
+ "lifter": 38555,
+ "lifting": 10857,
+ "lifts": 18291,
+ "lig": 19915,
+ "lig": 38493,
+ "liga": 16802,
+ "ligam": 31077,
+ "ligament": 48705,
+ "ligan": 27962,
+ "ligans": 42133,
+ "ligh": 7510,
+ "light": 3885,
+ "light": 1395,
+ "lighted": 18404,
+ "lighten": 32717,
+ "lightening": 28170,
+ "lighter": 14102,
+ "lighthouse": 13717,
+ "lighting": 5799,
+ "lightly": 26878,
+ "lightning": 7756,
+ "lightroom": 41454,
+ "lights": 3073,
+ "lightweight": 16278,
+ "ligu": 42920,
+ "ligue": 29196,
+ "lik": 4831,
+ "lik": 18495,
+ "like": 9175,
+ "like": 789,
+ "liked": 7112,
+ "likefor": 48444,
+ "likeli": 40666,
+ "likelihood": 48158,
+ "likely": 5256,
+ "liken": 36084,
+ "likes": 4724,
+ "liking": 16810,
+ "lil": 6012,
+ "lil": 4461,
+ "lilac": 33647,
+ "lili": 26686,
+ "lili": 48411,
+ "lilies": 38110,
+ "lillard": 47016,
+ "lille": 38705,
+ "lilli": 40920,
+ "lillian": 41563,
+ "lilly": 47825,
+ "lilly": 21815,
+ "lily": 23803,
+ "lily": 10647,
+ "lim": 2377,
+ "lim": 17204,
+ "lima": 17589,
+ "limb": 27061,
+ "limb": 32363,
+ "limbo": 46179,
+ "limbs": 34886,
+ "lime": 17385,
+ "lime": 11193,
+ "limel": 48658,
+ "limer": 16915,
+ "limerick": 19501,
+ "limestone": 27272,
+ "limit": 18933,
+ "limit": 9973,
+ "limitations": 32730,
+ "limited": 49229,
+ "limited": 3472,
+ "limiting": 35812,
+ "limitless": 35833,
+ "limits": 11966,
+ "limo": 33166,
+ "limous": 47287,
+ "limpopo": 47175,
+ "lin": 1254,
+ "lin": 2424,
+ "lina": 26110,
+ "lincol": 6239,
+ "lincoln": 16957,
+ "lincoln": 7454,
+ "lincolnshire": 29014,
+ "lind": 6492,
+ "linda": 45410,
+ "linda": 10760,
+ "linden": 44076,
+ "linden": 34832,
+ "lindo": 38467,
+ "lindsay": 29846,
+ "lindsay": 16858,
+ "lindsey": 29475,
+ "lindsey": 18128,
+ "line": 3674,
+ "line": 1148,
+ "linear": 19816,
+ "linebacker": 29848,
+ "lined": 11842,
+ "lineman": 31501,
+ "linen": 20032,
+ "liner": 11618,
+ "liners": 24463,
+ "lines": 3418,
+ "liness": 28633,
+ "lineup": 7316,
+ "lineups": 33589,
+ "ling": 4851,
+ "ling": 1358,
+ "linger": 29593,
+ "lingerie": 18473,
+ "lingering": 46494,
+ "lings": 11390,
+ "lington": 27673,
+ "lington": 9002,
+ "lingu": 34449,
+ "lingui": 29942,
+ "linguistic": 46847,
+ "linguistics": 48651,
+ "lining": 11589,
+ "link": 18433,
+ "link": 2468,
+ "linke": 15088,
+ "linked": 11059,
+ "linkedin": 16302,
+ "linkin": 40287,
+ "linkin": 49291,
+ "linking": 23296,
+ "links": 8113,
+ "linn": 37431,
+ "lino": 41189,
+ "lino": 34995,
+ "lins": 6567,
+ "linson": 15401,
+ "linton": 36479,
+ "linus": 49303,
+ "linux": 14061,
+ "lio": 19395,
+ "lion": 8872,
+ "lion": 5567,
+ "lionel": 19441,
+ "lions": 7093,
+ "lip": 8630,
+ "lip": 8546,
+ "lipo": 38795,
+ "lipp": 38074,
+ "lips": 8847,
+ "lipse": 10351,
+ "lipstick": 15618,
+ "liqu": 6310,
+ "lique": 32680,
+ "liqueur": 43612,
+ "liqui": 33817,
+ "liquid": 18366,
+ "liquid": 10158,
+ "liquidity": 42812,
+ "liquor": 17828,
+ "lis": 7297,
+ "lis": 12749,
+ "lisa": 25236,
+ "lisa": 7424,
+ "lisam": 43072,
+ "lisboa": 40052,
+ "lisbon": 17708,
+ "lish": 12658,
+ "lish": 2354,
+ "lished": 22620,
+ "lisle": 21529,
+ "lism": 34390,
+ "liss": 45489,
+ "liss": 35433,
+ "lisse": 49309,
+ "list": 1734,
+ "list": 1998,
+ "lista": 37812,
+ "listed": 6457,
+ "listen": 17454,
+ "listen": 2672,
+ "listened": 15347,
+ "listener": 34819,
+ "listeners": 26901,
+ "listening": 3656,
+ "listens": 25912,
+ "lister": 45109,
+ "listing": 8145,
+ "listings": 21987,
+ "liston": 48041,
+ "lists": 12281,
+ "lit": 2213,
+ "lit": 4350,
+ "lita": 30100,
+ "lite": 29273,
+ "lite": 13694,
+ "litecoin": 39063,
+ "liter": 3085,
+ "liter": 34904,
+ "literacy": 12841,
+ "literal": 24269,
+ "literally": 4719,
+ "literary": 13586,
+ "literature": 11072,
+ "litfest": 40369,
+ "lith": 37005,
+ "lithium": 22794,
+ "litho": 31088,
+ "lithograph": 49022,
+ "lithu": 21045,
+ "lithuania": 27068,
+ "liti": 24292,
+ "litigation": 31769,
+ "lito": 47381,
+ "litre": 25786,
+ "litres": 39919,
+ "litt": 1216,
+ "litt": 47583,
+ "litter": 45431,
+ "litter": 17118,
+ "litters": 45300,
+ "little": 7024,
+ "little": 1274,
+ "littlemix": 29731,
+ "littlest": 48969,
+ "litur": 36830,
+ "litz": 30357,
+ "liu": 20466,
+ "liv": 13895,
+ "liv": 19901,
+ "livan": 12785,
+ "live": 3215,
+ "live": 1064,
+ "lived": 8867,
+ "livel": 17973,
+ "liveli": 26566,
+ "livelihood": 46497,
+ "livelihoods": 47716,
+ "lively": 19663,
+ "liveme": 35396,
+ "livemusic": 15688,
+ "liven": 41057,
+ "liveon": 22815,
+ "livepd": 38742,
+ "livepd": 31899,
+ "liver": 4755,
+ "liver": 12639,
+ "liverpool": 29778,
+ "liverpool": 5366,
+ "livery": 23248,
+ "lives": 3247,
+ "livesmatter": 20348,
+ "livestock": 22079,
+ "livestream": 16844,
+ "livetweet": 38546,
+ "livin": 28061,
+ "living": 10965,
+ "living": 2815,
+ "livingston": 30551,
+ "lix": 45068,
+ "liz": 8632,
+ "liz": 12242,
+ "liza": 28787,
+ "lizard": 17221,
+ "lizards": 41991,
+ "lizasober": 44487,
+ "lizasoberano": 45076,
+ "lizz": 34430,
+ "lizzie": 29530,
+ "lizzy": 32306,
+ "lj": 34211,
+ "lj": 32273,
+ "lju": 44562,
+ "lk": 39110,
+ "lk": 26596,
+ "lka": 21881,
+ "ll": 1657,
+ "ll": 865,
+ "lla": 15419,
+ "llama": 36679,
+ "llan": 17281,
+ "llan": 38728,
+ "lland": 31150,
+ "llc": 17161,
+ "lle": 26550,
+ "lle": 29732,
+ "llen": 41197,
+ "ller": 7722,
+ "llers": 26426,
+ "lli": 47015,
+ "lli": 13368,
+ "llis": 25518,
+ "lll": 27177,
+ "llll": 34874,
+ "llll": 43485,
+ "llo": 19293,
+ "lloy": 10092,
+ "lloyd": 33339,
+ "lloyd": 12400,
+ "llp": 28042,
+ "lls": 40535,
+ "lly": 26379,
+ "lm": 6981,
+ "lm": 15282,
+ "lma": 4493,
+ "lmao": 5121,
+ "lmaoo": 32623,
+ "lmaooo": 33362,
+ "lmaoooo": 45232,
+ "lmfa": 8928,
+ "lmfao": 11068,
+ "lmfaooo": 47658,
+ "lmp": 43575,
+ "lms": 30381,
+ "ln": 31644,
+ "ln": 18654,
+ "lng": 22339,
+ "lnp": 39679,
+ "lo": 549,
+ "lo": 2982,
+ "loa": 39678,
+ "load": 4515,
+ "load": 2834,
+ "loaded": 6756,
+ "loader": 28492,
+ "loading": 9975,
+ "loads": 8691,
+ "loaf": 26467,
+ "loaf": 18273,
+ "loan": 28431,
+ "loan": 8176,
+ "loans": 14206,
+ "lob": 11197,
+ "lob": 46606,
+ "lobal": 34574,
+ "lobb": 27698,
+ "lobby": 12449,
+ "lobbying": 36047,
+ "lobe": 46325,
+ "lobes": 24148,
+ "lobo": 39323,
+ "lobos": 36586,
+ "lobster": 13793,
+ "loc": 1378,
+ "loc": 25826,
+ "local": 9202,
+ "local": 2029,
+ "localized": 49399,
+ "locally": 15603,
+ "locals": 15041,
+ "locate": 20490,
+ "located": 5677,
+ "location": 4372,
+ "locations": 9580,
+ "loch": 20188,
+ "loch": 14101,
+ "lock": 7201,
+ "lock": 4381,
+ "lockdown": 35636,
+ "locke": 29698,
+ "locked": 8371,
+ "locker": 14053,
+ "lockhart": 48642,
+ "lockheed": 36637,
+ "locking": 19978,
+ "locks": 13212,
+ "lockscreen": 42439,
+ "loco": 25555,
+ "locom": 22798,
+ "locomo": 46147,
+ "locomotive": 30439,
+ "locu": 33635,
+ "locust": 46237,
+ "lod": 45650,
+ "lodge": 10504,
+ "loe": 30113,
+ "loe": 25484,
+ "loeb": 49334,
+ "lof": 15011,
+ "loff": 31008,
+ "loft": 35707,
+ "loft": 20049,
+ "loftus": 46689,
+ "log": 3239,
+ "log": 7383,
+ "logan": 20655,
+ "logan": 10569,
+ "logans": 40752,
+ "logg": 43002,
+ "logged": 31457,
+ "logger": 39089,
+ "logging": 24444,
+ "logi": 3177,
+ "logia": 48031,
+ "logic": 10670,
+ "logical": 4791,
+ "logically": 24782,
+ "logie": 33445,
+ "logies": 7378,
+ "login": 31121,
+ "logist": 7407,
+ "logistics": 14755,
+ "logists": 12233,
+ "logne": 19911,
+ "logo": 31480,
+ "logo": 5750,
+ "logos": 24879,
+ "logs": 22745,
+ "logue": 27785,
+ "logy": 22721,
+ "logy": 1659,
+ "loh": 49129,
+ "loh": 37983,
+ "loi": 35128,
+ "loid": 31408,
+ "loin": 21760,
+ "loire": 46040,
+ "lois": 27040,
+ "lok": 19908,
+ "lok": 23575,
+ "loki": 24435,
+ "lol": 10721,
+ "lol": 1824,
+ "lola": 19065,
+ "lolita": 42615,
+ "lolla": 45483,
+ "lolli": 27906,
+ "lollipop": 34605,
+ "lolly": 48264,
+ "lolo": 16895,
+ "lolo": 37481,
+ "lolol": 25280,
+ "lololol": 34738,
+ "lolz": 35260,
+ "lom": 9279,
+ "loma": 42889,
+ "lombar": 25493,
+ "lombard": 46461,
+ "lombardi": 44346,
+ "lomond": 48941,
+ "lon": 1235,
+ "lon": 6507,
+ "london": 6835,
+ "london": 1789,
+ "londonmarathon": 35018,
+ "lone": 22220,
+ "lone": 13576,
+ "lonel": 28872,
+ "loneliness": 30310,
+ "lonely": 34509,
+ "lonely": 12368,
+ "lonelyplanet": 44984,
+ "long": 4792,
+ "long": 1538,
+ "longe": 25793,
+ "longer": 5349,
+ "longest": 10731,
+ "longevity": 35354,
+ "longh": 20286,
+ "longhorn": 41047,
+ "longhorns": 38295,
+ "longing": 38482,
+ "longlive": 47840,
+ "longs": 43618,
+ "longtime": 19685,
+ "loo": 731,
+ "loo": 11804,
+ "look": 8874,
+ "look": 1012,
+ "lookalike": 38307,
+ "lookbook": 39184,
+ "looked": 4913,
+ "lookin": 11254,
+ "looking": 36898,
+ "looking": 1312,
+ "lookout": 18330,
+ "looks": 1606,
+ "lool": 33125,
+ "loom": 37440,
+ "loom": 17199,
+ "looming": 35384,
+ "looms": 30550,
+ "loon": 28222,
+ "loona": 48137,
+ "looney": 45315,
+ "looo": 20902,
+ "loool": 36016,
+ "looool": 47038,
+ "looooo": 31484,
+ "loop": 19606,
+ "loop": 10408,
+ "loops": 21625,
+ "loos": 45723,
+ "loose": 43815,
+ "loose": 9786,
+ "loot": 21518,
+ "lop": 36734,
+ "lop": 17066,
+ "lopes": 49269,
+ "lopez": 12982,
+ "lor": 2179,
+ "lor": 11335,
+ "lord": 18896,
+ "lord": 3486,
+ "lorde": 35483,
+ "lords": 14969,
+ "lore": 12880,
+ "lore": 27218,
+ "loren": 13602,
+ "loren": 33398,
+ "lorenzo": 21342,
+ "lores": 34510,
+ "loretta": 40863,
+ "lori": 20164,
+ "lori": 23095,
+ "lorna": 46316,
+ "lorraine": 27602,
+ "lorry": 31354,
+ "los": 32217,
+ "los": 3087,
+ "losange": 14037,
+ "losangeles": 14638,
+ "lose": 43318,
+ "lose": 5354,
+ "loser": 18168,
+ "losers": 23201,
+ "loses": 14263,
+ "losing": 7918,
+ "loss": 34761,
+ "loss": 4327,
+ "losses": 16909,
+ "lost": 14258,
+ "lost": 2624,
+ "lostdog": 48482,
+ "lot": 5132,
+ "lot": 1954,
+ "loth": 43625,
+ "lothian": 31360,
+ "lothing": 42058,
+ "lotion": 25260,
+ "lotr": 34165,
+ "lots": 2958,
+ "lott": 42854,
+ "lotta": 29125,
+ "lotte": 16535,
+ "lotte": 7274,
+ "lottery": 16975,
+ "lottie": 48517,
+ "lotto": 28265,
+ "lotus": 13824,
+ "lou": 2207,
+ "lou": 9745,
+ "loubout": 38369,
+ "loud": 22884,
+ "loud": 7464,
+ "louder": 25904,
+ "loudest": 49214,
+ "loudly": 39256,
+ "lough": 21927,
+ "lough": 28045,
+ "loughborough": 49153,
+ "loui": 42173,
+ "louie": 25790,
+ "louis": 8916,
+ "louis": 4459,
+ "louisa": 40011,
+ "louise": 32275,
+ "louise": 13076,
+ "louisi": 12187,
+ "louisiana": 12946,
+ "louisville": 13860,
+ "louisvuitton": 44911,
+ "loun": 6466,
+ "lounge": 7141,
+ "lounging": 45430,
+ "lour": 29383,
+ "lourdes": 45071,
+ "louvre": 36995,
+ "lov": 8923,
+ "lov": 21229,
+ "lova": 37394,
+ "lovable": 38565,
+ "lovato": 18960,
+ "love": 2618,
+ "love": 793,
+ "lovecraft": 42405,
+ "loved": 3249,
+ "lovefl": 38884,
+ "loveher": 38306,
+ "lovehim": 45733,
+ "loveis": 30931,
+ "loveisland": 30970,
+ "loveislove": 43603,
+ "loveit": 24764,
+ "lovel": 8999,
+ "lovelies": 31412,
+ "lovelondon": 46493,
+ "lovely": 33250,
+ "lovely": 2165,
+ "lovemy": 20041,
+ "lovemyjob": 40130,
+ "loven": 33754,
+ "lover": 28508,
+ "lover": 7168,
+ "lovers": 48416,
+ "lovers": 5973,
+ "loves": 37773,
+ "loves": 3925,
+ "lovethe": 33040,
+ "lovethem": 48298,
+ "lovett": 47095,
+ "lovewins": 47687,
+ "loveyou": 39226,
+ "loveyou": 25964,
+ "loveyour": 26462,
+ "lovin": 33442,
+ "lovin": 16354,
+ "loving": 29568,
+ "loving": 3721,
+ "lovingly": 44100,
+ "low": 1049,
+ "low": 1042,
+ "loway": 16104,
+ "lowe": 17910,
+ "lowed": 22733,
+ "lowell": 24458,
+ "lower": 32578,
+ "lower": 4909,
+ "lowered": 34968,
+ "lowering": 35261,
+ "lowers": 36398,
+ "lowes": 38515,
+ "lowest": 12098,
+ "lowing": 8283,
+ "lowkey": 29481,
+ "lowry": 27444,
+ "lows": 4406,
+ "lox": 41725,
+ "loy": 4519,
+ "loy": 23929,
+ "loyal": 13032,
+ "loyalty": 14686,
+ "loyd": 44212,
+ "loyed": 29279,
+ "loyment": 18307,
+ "loyola": 32569,
+ "lp": 22282,
+ "lp": 6392,
+ "lpc": 44092,
+ "lpg": 47905,
+ "lpga": 34295,
+ "lps": 32094,
+ "lr": 20572,
+ "lr": 7041,
+ "lrt": 32996,
+ "ls": 19051,
+ "ls": 1268,
+ "lsd": 43766,
+ "lse": 46127,
+ "lse": 43886,
+ "lsu": 35428,
+ "lsu": 15672,
+ "lt": 13642,
+ "lt": 3333,
+ "ltc": 27664,
+ "ltd": 6802,
+ "lte": 25202,
+ "lton": 14237,
+ "lu": 664,
+ "lu": 9657,
+ "lub": 22469,
+ "lub": 11836,
+ "lubbock": 37660,
+ "lubric": 40963,
+ "luc": 7013,
+ "luc": 28014,
+ "luca": 21053,
+ "lucas": 23425,
+ "lucas": 10225,
+ "lucci": 45849,
+ "luce": 46217,
+ "lucent": 41552,
+ "lucer": 36042,
+ "luch": 36646,
+ "lucha": 38449,
+ "luci": 8787,
+ "lucia": 22290,
+ "luciano": 46365,
+ "lucid": 44540,
+ "lucie": 39461,
+ "lucifer": 46224,
+ "lucifer": 27687,
+ "lucille": 47454,
+ "lucin": 27523,
+ "luck": 9647,
+ "luck": 2820,
+ "luckiest": 42469,
+ "luckily": 20100,
+ "lucknow": 29407,
+ "lucky": 20495,
+ "lucky": 4133,
+ "lucrative": 41485,
+ "lucy": 17262,
+ "lucy": 10120,
+ "lud": 14288,
+ "lude": 28755,
+ "ludo": 40141,
+ "ludwig": 30633,
+ "lue": 45199,
+ "luf": 25264,
+ "lufc": 17818,
+ "luffy": 39047,
+ "lufthan": 37769,
+ "lufthansa": 39145,
+ "lug": 45521,
+ "lugg": 19673,
+ "luggage": 20138,
+ "luhan": 20975,
+ "luigi": 28444,
+ "luis": 25231,
+ "luis": 11339,
+ "luiz": 39633,
+ "lujah": 31639,
+ "luk": 21652,
+ "luka": 34878,
+ "lukaku": 37177,
+ "lukas": 37941,
+ "luke": 11970,
+ "luke": 5652,
+ "lul": 20861,
+ "lulla": 37019,
+ "lullaby": 41676,
+ "lulu": 32052,
+ "lulu": 26935,
+ "lum": 18112,
+ "lum": 5997,
+ "lumb": 36231,
+ "lumber": 27421,
+ "lumber": 34692,
+ "lumi": 41437,
+ "lumia": 31912,
+ "lumin": 15867,
+ "luminous": 37913,
+ "lump": 38704,
+ "lumpur": 34411,
+ "lun": 3221,
+ "lun": 49390,
+ "luna": 14425,
+ "lunar": 16043,
+ "lunatic": 45874,
+ "lunch": 10954,
+ "lunch": 2772,
+ "luncheon": 15104,
+ "lunches": 29705,
+ "lunchtime": 14330,
+ "lund": 30975,
+ "lund": 20181,
+ "lunes": 35648,
+ "lung": 38479,
+ "lung": 16271,
+ "lungs": 27366,
+ "lup": 27413,
+ "lupita": 49352,
+ "lupus": 36017,
+ "lur": 14439,
+ "lure": 31376,
+ "lures": 46747,
+ "lurking": 29941,
+ "lus": 7158,
+ "lusci": 38004,
+ "luscious": 39935,
+ "lush": 40382,
+ "lush": 16263,
+ "lust": 42071,
+ "lust": 12662,
+ "lustre": 46673,
+ "luther": 21848,
+ "luther": 17208,
+ "lutheran": 27341,
+ "luton": 28288,
+ "luv": 24726,
+ "luv": 8502,
+ "lux": 3439,
+ "lux": 16704,
+ "luxe": 26373,
+ "luxemb": 21314,
+ "luxembour": 22712,
+ "luxembourg": 23949,
+ "luxu": 16112,
+ "luxurious": 17292,
+ "luxury": 12083,
+ "luxury": 5247,
+ "luxurytravel": 29010,
+ "luz": 41008,
+ "lv": 10862,
+ "lv": 11184,
+ "lvl": 31256,
+ "lw": 40515,
+ "lw": 35115,
+ "lx": 30789,
+ "ly": 1251,
+ "ly": 597,
+ "lydia": 24316,
+ "lyf": 43688,
+ "lyfe": 30787,
+ "lyft": 32944,
+ "lying": 7175,
+ "lyk": 46376,
+ "lyle": 36828,
+ "lym": 20087,
+ "lyme": 31167,
+ "lymph": 30073,
+ "lymphoma": 37648,
+ "lyn": 3957,
+ "lyn": 5054,
+ "lynch": 31586,
+ "lynch": 13560,
+ "lynd": 33416,
+ "lynda": 42959,
+ "lyndon": 48518,
+ "lynn": 25303,
+ "lynn": 10667,
+ "lynne": 26900,
+ "lynx": 28941,
+ "lyon": 17176,
+ "lyons": 29453,
+ "lyric": 24366,
+ "lyric": 21291,
+ "lyrical": 33358,
+ "lyricist": 49013,
+ "lyrics": 9551,
+ "lyrix": 46814,
+ "lys": 45054,
+ "lyte": 40059,
+ "lywood": 4012,
+ "lz": 30818,
+ "lé": 39641,
+ "m": 76,
+ "m": 332,
+ "ma": 577,
+ "ma": 1226,
+ "maa": 42774,
+ "maa": 21555,
+ "maan": 33668,
+ "maar": 48927,
+ "maas": 43332,
+ "mab": 35639,
+ "mabel": 47319,
+ "mable": 23001,
+ "mably": 40082,
+ "mabu": 44682,
+ "mac": 1961,
+ "mac": 4945,
+ "macar": 21558,
+ "macaroni": 41824,
+ "macarthur": 36785,
+ "macau": 43984,
+ "macau": 33370,
+ "macbeth": 36321,
+ "macbook": 20617,
+ "macdonald": 20315,
+ "mace": 44869,
+ "maced": 21102,
+ "macedonia": 27071,
+ "macfar": 45374,
+ "macfarlane": 48825,
+ "mach": 2637,
+ "mach": 35091,
+ "machado": 42318,
+ "mache": 43220,
+ "macher": 29330,
+ "machi": 41783,
+ "machin": 17972,
+ "machine": 11539,
+ "machine": 4169,
+ "machinelearning": 13621,
+ "machinery": 21858,
+ "machines": 11108,
+ "machining": 45562,
+ "macho": 43977,
+ "macht": 45225,
+ "macin": 36533,
+ "mack": 8590,
+ "mack": 12145,
+ "mackay": 32497,
+ "macken": 48057,
+ "mackenzie": 22351,
+ "mackerel": 35002,
+ "mackin": 26010,
+ "macklemore": 41758,
+ "macle": 33843,
+ "maclean": 47137,
+ "macleod": 43684,
+ "macmillan": 36364,
+ "macmillan": 35191,
+ "macon": 35818,
+ "macos": 45469,
+ "macqu": 38365,
+ "macquarie": 40858,
+ "macro": 20891,
+ "macro": 16626,
+ "macron": 24859,
+ "macs": 46548,
+ "macy": 17113,
+ "macys": 47652,
+ "mad": 2740,
+ "mad": 3843,
+ "mada": 37799,
+ "madagas": 24758,
+ "madagascar": 25744,
+ "madam": 33634,
+ "madam": 27538,
+ "madame": 23507,
+ "madd": 31717,
+ "madden": 19093,
+ "maddie": 39959,
+ "maddie": 18875,
+ "maddow": 32644,
+ "maddy": 31734,
+ "made": 5388,
+ "made": 1105,
+ "madein": 13670,
+ "madeira": 33810,
+ "madel": 34532,
+ "madele": 29831,
+ "madeleine": 33264,
+ "madeline": 33905,
+ "madewith": 28627,
+ "madewithunity": 43190,
+ "madhu": 23000,
+ "madhuri": 38346,
+ "madhuridixit": 43889,
+ "madhya": 48302,
+ "madi": 6527,
+ "madi": 27282,
+ "madison": 24798,
+ "madison": 8791,
+ "madmen": 45452,
+ "madness": 8755,
+ "madon": 44852,
+ "madonna": 14137,
+ "madra": 27416,
+ "madras": 42046,
+ "madre": 42130,
+ "madri": 5529,
+ "madrid": 5909,
+ "mads": 41201,
+ "madu": 34913,
+ "madurai": 49159,
+ "maduro": 32912,
+ "mae": 16898,
+ "mae": 17339,
+ "maer": 47088,
+ "maestro": 24140,
+ "mafi": 47164,
+ "mafia": 14890,
+ "mag": 1191,
+ "mag": 4508,
+ "maga": 8694,
+ "magaz": 2974,
+ "magazine": 3113,
+ "magazines": 22253,
+ "magdal": 29673,
+ "mage": 46568,
+ "mage": 10923,
+ "magee": 43872,
+ "magenta": 38091,
+ "magento": 42442,
+ "mages": 31059,
+ "maggi": 29611,
+ "maggie": 41443,
+ "maggie": 14524,
+ "maggio": 49087,
+ "magh": 45555,
+ "magi": 19270,
+ "magic": 13061,
+ "magic": 3778,
+ "magical": 36408,
+ "magical": 7823,
+ "magician": 26368,
+ "magin": 42678,
+ "maging": 41310,
+ "magn": 10290,
+ "magna": 34076,
+ "magne": 9921,
+ "magnesium": 36379,
+ "magnet": 18240,
+ "magnetic": 13838,
+ "magnets": 33030,
+ "magni": 24297,
+ "magnific": 9725,
+ "magnificent": 10724,
+ "magnitude": 22955,
+ "magno": 21184,
+ "magnolia": 27123,
+ "magnu": 45198,
+ "magnum": 23496,
+ "magnus": 26275,
+ "magpie": 45973,
+ "mags": 31021,
+ "maguire": 26470,
+ "mah": 7206,
+ "mah": 10801,
+ "maha": 12237,
+ "maha": 33983,
+ "mahal": 22301,
+ "mahan": 45191,
+ "mahar": 11635,
+ "maharaj": 38488,
+ "maharashtra": 19328,
+ "mahat": 32434,
+ "mahatma": 40530,
+ "mahe": 15756,
+ "maher": 29826,
+ "mahesh": 33448,
+ "mahesh": 22095,
+ "mahi": 32529,
+ "mahi": 38659,
+ "mahin": 24113,
+ "mahindra": 31285,
+ "mahmoud": 41361,
+ "mahog": 30804,
+ "mahogany": 33084,
+ "mahon": 45864,
+ "mahon": 20371,
+ "mahone": 26634,
+ "mai": 7138,
+ "mai": 14595,
+ "maia": 46585,
+ "maid": 23148,
+ "maid": 10226,
+ "maidan": 37346,
+ "maiden": 37011,
+ "maiden": 13809,
+ "maids": 27305,
+ "maidstone": 44395,
+ "mail": 10478,
+ "mail": 2614,
+ "mailbox": 31482,
+ "mailed": 42314,
+ "mailing": 26680,
+ "mailonline": 26021,
+ "mails": 45213,
+ "main": 3904,
+ "main": 2623,
+ "maine": 18639,
+ "maine": 7836,
+ "mained": 15609,
+ "mainedcm": 15845,
+ "mainland": 27629,
+ "mainly": 15280,
+ "mains": 33656,
+ "mainst": 42102,
+ "mainstream": 18034,
+ "maintain": 12954,
+ "maintained": 26665,
+ "maintaining": 21964,
+ "maintains": 38335,
+ "mainten": 9399,
+ "maintenance": 9610,
+ "mais": 28153,
+ "maisie": 47355,
+ "maison": 37065,
+ "maison": 27626,
+ "mait": 26387,
+ "maize": 35386,
+ "maj": 2948,
+ "maj": 28723,
+ "maja": 47498,
+ "maje": 9852,
+ "majestic": 15335,
+ "majesty": 21188,
+ "major": 8008,
+ "major": 3350,
+ "majority": 10508,
+ "majors": 23597,
+ "mak": 11271,
+ "mak": 19253,
+ "makar": 42242,
+ "makati": 39402,
+ "make": 3232,
+ "make": 1078,
+ "makeaw": 45859,
+ "makeinindia": 42739,
+ "makeit": 26308,
+ "maken": 47093,
+ "makeover": 17926,
+ "maker": 15196,
+ "maker": 4836,
+ "makers": 6577,
+ "makerspace": 42400,
+ "makes": 2088,
+ "makeshift": 43274,
+ "makeu": 41707,
+ "makeup": 26402,
+ "makeup": 5853,
+ "makeyourown": 34090,
+ "makeyourownlane": 34823,
+ "maki": 34514,
+ "makin": 43096,
+ "makin": 22407,
+ "making": 17976,
+ "making": 1665,
+ "makk": 39852,
+ "maknae": 44118,
+ "mako": 49061,
+ "mal": 1662,
+ "mal": 3796,
+ "mala": 28290,
+ "malade": 36928,
+ "malaga": 35395,
+ "malala": 41137,
+ "malam": 48956,
+ "malaria": 24929,
+ "malawi": 23405,
+ "malay": 5323,
+ "malay": 42430,
+ "malayalam": 34860,
+ "malaysi": 39668,
+ "malaysia": 8146,
+ "malaysian": 21136,
+ "malbec": 47741,
+ "malcol": 12645,
+ "malcolm": 14139,
+ "maldives": 16795,
+ "male": 11326,
+ "male": 2801,
+ "males": 14426,
+ "malhotra": 28866,
+ "mali": 6701,
+ "mali": 22669,
+ "malia": 46714,
+ "malibu": 21723,
+ "malicious": 42147,
+ "malign": 41122,
+ "malik": 11394,
+ "mall": 10984,
+ "mall": 6220,
+ "mallorca": 28082,
+ "mallory": 38968,
+ "malls": 36447,
+ "malm": 44071,
+ "malnutrition": 41153,
+ "malo": 43518,
+ "malone": 19852,
+ "maloney": 45897,
+ "mals": 25370,
+ "malt": 21688,
+ "malta": 16989,
+ "maltese": 39838,
+ "malvern": 39356,
+ "malware": 24153,
+ "mam": 4404,
+ "mam": 17778,
+ "mama": 7133,
+ "mamamoo": 36012,
+ "mamas": 42395,
+ "mamba": 44189,
+ "mament": 45690,
+ "mami": 43858,
+ "mamma": 34893,
+ "mammal": 33385,
+ "mammals": 31987,
+ "mammoth": 28022,
+ "man": 723,
+ "man": 786,
+ "mana": 29467,
+ "mana": 15837,
+ "manafort": 40108,
+ "manag": 1830,
+ "manage": 9770,
+ "managed": 7928,
+ "management": 3319,
+ "manager": 3898,
+ "managerial": 44261,
+ "managers": 12853,
+ "manages": 29699,
+ "managing": 10892,
+ "manas": 44188,
+ "manatee": 46558,
+ "mance": 2324,
+ "manchester": 24424,
+ "manchester": 4651,
+ "mancini": 47681,
+ "mancity": 31538,
+ "mancrush": 36945,
+ "mancrushmonday": 39307,
+ "mand": 4325,
+ "mand": 27244,
+ "mandala": 41106,
+ "mandarin": 26455,
+ "mandate": 26228,
+ "mandatory": 19934,
+ "mandel": 34960,
+ "mandela": 16280,
+ "mandi": 38961,
+ "mandir": 35815,
+ "mando": 34006,
+ "mands": 12340,
+ "mandu": 31440,
+ "mandy": 41505,
+ "mandy": 24302,
+ "mane": 44471,
+ "mane": 16044,
+ "maneu": 33216,
+ "mang": 25616,
+ "mang": 31096,
+ "manga": 11873,
+ "mangal": 43027,
+ "manger": 48251,
+ "mango": 43831,
+ "mango": 13962,
+ "mangrove": 47180,
+ "manhatt": 10152,
+ "manhattan": 10961,
+ "mani": 5654,
+ "mani": 10718,
+ "mania": 8435,
+ "maniac": 31814,
+ "maniacs": 41444,
+ "manian": 40077,
+ "manic": 23017,
+ "manic": 37825,
+ "manicure": 33637,
+ "manife": 14379,
+ "manifest": 34422,
+ "manifestation": 48348,
+ "manifesto": 20907,
+ "manil": 38827,
+ "manila": 10969,
+ "manipu": 40261,
+ "manipul": 19237,
+ "manipulation": 30277,
+ "manipur": 47757,
+ "manish": 41759,
+ "manish": 44720,
+ "manit": 15693,
+ "manitoba": 20342,
+ "manjaro": 41489,
+ "mankind": 24155,
+ "manly": 25194,
+ "mann": 19396,
+ "mann": 4783,
+ "manne": 30160,
+ "manned": 26139,
+ "mannequin": 43388,
+ "manner": 20700,
+ "manners": 31693,
+ "manning": 15996,
+ "manny": 37054,
+ "manny": 20933,
+ "mano": 15753,
+ "mano": 24016,
+ "manoj": 41146,
+ "manor": 41830,
+ "manor": 13614,
+ "mans": 28422,
+ "mans": 7746,
+ "mansfield": 25543,
+ "manship": 15460,
+ "mansion": 13404,
+ "manslaughter": 48632,
+ "manson": 26715,
+ "mant": 25122,
+ "mant": 27037,
+ "manta": 41431,
+ "mantis": 39946,
+ "mantle": 22159,
+ "mantra": 25162,
+ "manu": 3404,
+ "manu": 25799,
+ "manual": 12268,
+ "manuel": 29171,
+ "manuel": 9567,
+ "manufac": 5105,
+ "manufacture": 27741,
+ "manufactured": 24010,
+ "manufacturer": 15668,
+ "manufacturers": 18763,
+ "manufacturing": 8386,
+ "manure": 47907,
+ "manus": 28181,
+ "manuscript": 24365,
+ "manuscripts": 40765,
+ "manutd": 20994,
+ "many": 28484,
+ "many": 1346,
+ "manziel": 40637,
+ "mao": 47447,
+ "mao": 25605,
+ "maori": 43400,
+ "map": 25180,
+ "map": 3923,
+ "maple": 21980,
+ "maple": 10570,
+ "mapleleafs": 41257,
+ "mapoli": 28768,
+ "mapp": 36894,
+ "mapped": 41596,
+ "mapping": 15231,
+ "maps": 8765,
+ "mapu": 42082,
+ "mar": 675,
+ "mar": 3091,
+ "mara": 15655,
+ "marais": 47913,
+ "maran": 44732,
+ "marath": 16274,
+ "marathi": 34102,
+ "marathon": 40764,
+ "marathon": 5910,
+ "marau": 38475,
+ "marbella": 36182,
+ "marble": 45429,
+ "marble": 13071,
+ "marbles": 42931,
+ "marc": 14054,
+ "marc": 9075,
+ "marca": 38242,
+ "marcel": 17726,
+ "marcel": 24652,
+ "marcelo": 35939,
+ "march": 10638,
+ "march": 2227,
+ "marche": 36173,
+ "marched": 37976,
+ "marches": 38249,
+ "marchfor": 31721,
+ "marching": 15082,
+ "marchmadness": 28555,
+ "marci": 36698,
+ "marcia": 41075,
+ "marck": 47733,
+ "marco": 24719,
+ "marco": 10924,
+ "marcor": 39945,
+ "marcorubio": 41143,
+ "marcos": 21696,
+ "marcu": 20760,
+ "marcus": 48955,
+ "marcus": 9895,
+ "mardi": 39728,
+ "mardi": 29229,
+ "mardigras": 43343,
+ "mare": 26512,
+ "mare": 8870,
+ "mares": 19724,
+ "marg": 44014,
+ "margar": 16838,
+ "margare": 10232,
+ "margaret": 12185,
+ "margarita": 25958,
+ "margaritas": 42679,
+ "margate": 37428,
+ "margin": 19464,
+ "margin": 21357,
+ "marginal": 38320,
+ "margins": 33763,
+ "margot": 37144,
+ "mari": 2603,
+ "mari": 19322,
+ "maria": 41109,
+ "maria": 6595,
+ "mariachi": 44299,
+ "mariah": 31214,
+ "mariah": 24789,
+ "mariahcarey": 36538,
+ "marian": 41129,
+ "marian": 24677,
+ "mariana": 44224,
+ "marianne": 32214,
+ "mariano": 43988,
+ "marie": 20657,
+ "marie": 7864,
+ "marietta": 46634,
+ "marig": 41002,
+ "marijuana": 9864,
+ "maril": 14611,
+ "marilyn": 38959,
+ "marilyn": 18489,
+ "marin": 8910,
+ "marin": 23992,
+ "marina": 12060,
+ "marinated": 33406,
+ "marine": 20674,
+ "marine": 5746,
+ "mariner": 39972,
+ "mariners": 19086,
+ "marines": 15018,
+ "marino": 30878,
+ "mario": 39176,
+ "mario": 7600,
+ "marion": 37765,
+ "marion": 18397,
+ "maris": 21512,
+ "maris": 33093,
+ "marisa": 42938,
+ "mariska": 44703,
+ "marissa": 31219,
+ "marist": 48223,
+ "mariti": 13124,
+ "maritime": 14331,
+ "marj": 38639,
+ "mark": 3805,
+ "mark": 2110,
+ "marke": 2399,
+ "marked": 12360,
+ "marker": 18170,
+ "markers": 23664,
+ "market": 11614,
+ "market": 2196,
+ "marketer": 33482,
+ "marketers": 23682,
+ "marketing": 19535,
+ "marketing": 2905,
+ "marketplace": 18241,
+ "markets": 7292,
+ "markham": 39817,
+ "marking": 14705,
+ "markings": 41046,
+ "markle": 32672,
+ "marko": 38338,
+ "marks": 5466,
+ "markus": 33725,
+ "marl": 24922,
+ "marlborough": 43515,
+ "marlene": 45117,
+ "marley": 16504,
+ "marlin": 34275,
+ "marlins": 23309,
+ "marlon": 32995,
+ "marmalade": 39068,
+ "marnock": 48305,
+ "maro": 27029,
+ "maroon": 20501,
+ "marqu": 20704,
+ "marque": 13012,
+ "marquee": 27725,
+ "marquette": 37624,
+ "marquez": 27317,
+ "marquis": 33530,
+ "marr": 32871,
+ "marrake": 37125,
+ "marrakech": 39006,
+ "marri": 3839,
+ "marriage": 38047,
+ "marriage": 7040,
+ "marriages": 38190,
+ "married": 6791,
+ "marries": 46283,
+ "marriott": 19211,
+ "marrow": 31030,
+ "marry": 13288,
+ "marrying": 40507,
+ "mars": 41469,
+ "mars": 7496,
+ "marsden": 43344,
+ "marse": 26577,
+ "marseille": 30365,
+ "marsh": 9237,
+ "marsh": 13505,
+ "marsha": 21491,
+ "marshal": 26608,
+ "marshall": 30939,
+ "marshall": 9811,
+ "marshals": 44175,
+ "marshes": 43450,
+ "marshmal": 21069,
+ "marshmallow": 28530,
+ "marshmallows": 39471,
+ "mart": 2348,
+ "mart": 7772,
+ "marta": 32858,
+ "martens": 43211,
+ "marth": 34493,
+ "martha": 16427,
+ "marti": 20577,
+ "martial": 17088,
+ "martialarts": 35895,
+ "martian": 30214,
+ "martin": 6929,
+ "martin": 3690,
+ "martina": 34393,
+ "martinez": 13913,
+ "marting": 47570,
+ "martini": 22199,
+ "martino": 41675,
+ "martins": 30569,
+ "marty": 9926,
+ "marty": 17169,
+ "martyn": 44075,
+ "martyr": 36155,
+ "martyr": 26067,
+ "martyrdom": 43110,
+ "martyred": 39114,
+ "martyrs": 24707,
+ "maru": 37413,
+ "maru": 31838,
+ "marvel": 13835,
+ "marvel": 5996,
+ "marvelcomics": 46897,
+ "marvell": 26576,
+ "marvellous": 28402,
+ "marvelous": 25487,
+ "marvin": 19675,
+ "marx": 30559,
+ "marx": 26001,
+ "marxist": 45205,
+ "mary": 5146,
+ "mary": 2676,
+ "maryam": 33636,
+ "maryam": 36393,
+ "maryland": 11379,
+ "marys": 40905,
+ "marys": 40228,
+ "mas": 5226,
+ "mas": 1412,
+ "masa": 24995,
+ "masa": 41868,
+ "masala": 31483,
+ "masc": 23564,
+ "mascar": 46984,
+ "mascara": 31635,
+ "mascot": 13983,
+ "mascots": 43266,
+ "mascul": 25589,
+ "masculine": 48269,
+ "masculinity": 40465,
+ "mase": 49128,
+ "maser": 25798,
+ "maserati": 30442,
+ "mash": 12317,
+ "mash": 15680,
+ "mashable": 41026,
+ "mashed": 27395,
+ "mashup": 27079,
+ "masi": 35965,
+ "masjid": 31420,
+ "mask": 19262,
+ "mask": 8306,
+ "masked": 25757,
+ "masking": 47046,
+ "masks": 19055,
+ "maslow": 44359,
+ "mason": 17424,
+ "mason": 9699,
+ "masonic": 36491,
+ "masonry": 30764,
+ "masons": 37195,
+ "masqu": 26593,
+ "masquer": 29604,
+ "masquerade": 36944,
+ "mass": 4636,
+ "mass": 4854,
+ "massach": 14484,
+ "massachuse": 14577,
+ "massachusetts": 14756,
+ "massacre": 14696,
+ "massage": 13055,
+ "masse": 41735,
+ "masses": 22978,
+ "massey": 29868,
+ "massi": 17239,
+ "massimo": 45821,
+ "massive": 4818,
+ "massively": 34297,
+ "mast": 45916,
+ "mast": 27920,
+ "master": 4534,
+ "master": 3498,
+ "mastercard": 40542,
+ "masterchef": 34809,
+ "masterclass": 17529,
+ "mastered": 32616,
+ "masterful": 46823,
+ "mastering": 28326,
+ "mastermind": 34029,
+ "masterpiece": 12066,
+ "masterpieces": 37596,
+ "masters": 6913,
+ "mastery": 34800,
+ "mastiff": 42311,
+ "maswar": 47887,
+ "mat": 905,
+ "mat": 9063,
+ "mata": 17270,
+ "match": 7733,
+ "match": 2439,
+ "matcha": 32433,
+ "matchday": 15947,
+ "matched": 17792,
+ "matches": 8609,
+ "matching": 11840,
+ "matchup": 19355,
+ "matchups": 49162,
+ "mate": 6137,
+ "mate": 2936,
+ "mated": 33813,
+ "mateo": 34991,
+ "mater": 23724,
+ "materi": 7084,
+ "material": 7118,
+ "materials": 8161,
+ "maternal": 26131,
+ "maternity": 23894,
+ "mates": 5817,
+ "math": 13277,
+ "math": 6025,
+ "mathe": 8725,
+ "mathemat": 11901,
+ "mathematical": 25609,
+ "mathematician": 41036,
+ "mathematics": 20113,
+ "mathew": 36333,
+ "mathews": 37120,
+ "mathi": 23014,
+ "mathieu": 40417,
+ "maths": 14763,
+ "mati": 12716,
+ "mati": 32268,
+ "matic": 36859,
+ "matic": 7900,
+ "matically": 38282,
+ "matics": 23634,
+ "matil": 26751,
+ "matilda": 36308,
+ "matin": 44849,
+ "matinee": 38525,
+ "mating": 34346,
+ "mation": 11701,
+ "matisse": 43446,
+ "mato": 13127,
+ "matologist": 48842,
+ "matology": 27940,
+ "matory": 25519,
+ "matri": 27041,
+ "matrix": 18078,
+ "mats": 22259,
+ "matsu": 30242,
+ "matt": 7972,
+ "matt": 3972,
+ "mattb": 42791,
+ "matte": 31237,
+ "matte": 19771,
+ "mattel": 35365,
+ "matteo": 33120,
+ "matter": 30471,
+ "matter": 3828,
+ "matters": 5708,
+ "matth": 41846,
+ "matthe": 5116,
+ "matthew": 17588,
+ "matthew": 7008,
+ "matthews": 16739,
+ "matthi": 29853,
+ "matthias": 45104,
+ "matti": 39840,
+ "mattress": 23438,
+ "matty": 31233,
+ "matty": 29176,
+ "matu": 40616,
+ "matur": 22897,
+ "mature": 14417,
+ "maturity": 28047,
+ "mau": 8134,
+ "mau": 23033,
+ "maui": 20463,
+ "maul": 30725,
+ "maur": 10574,
+ "maure": 25191,
+ "maureen": 31723,
+ "maurice": 20200,
+ "mauricio": 39066,
+ "mauriti": 28406,
+ "mauritius": 29305,
+ "mauro": 41691,
+ "mav": 25697,
+ "maver": 16700,
+ "maverick": 27425,
+ "mavericks": 30092,
+ "mavs": 30665,
+ "maw": 39351,
+ "maw": 42271,
+ "mawards": 37682,
+ "max": 4898,
+ "max": 3902,
+ "maxi": 8554,
+ "maxi": 23266,
+ "maxim": 19892,
+ "maxim": 38574,
+ "maximize": 28673,
+ "maximum": 13162,
+ "maximus": 44312,
+ "maxine": 38468,
+ "maxwell": 19611,
+ "maxx": 37466,
+ "may": 1686,
+ "may": 1270,
+ "maya": 45783,
+ "maya": 12987,
+ "mayan": 37952,
+ "maybe": 3746,
+ "mayday": 29957,
+ "mayer": 21196,
+ "mayfair": 35171,
+ "mayfield": 33933,
+ "mayhem": 21502,
+ "maymay": 26600,
+ "maymay": 33853,
+ "maymayentrata": 30480,
+ "maynard": 32487,
+ "mayne": 35771,
+ "mayo": 22449,
+ "mayo": 11280,
+ "mayor": 15429,
+ "mayor": 4676,
+ "mayoral": 28983,
+ "mayorof": 43533,
+ "mayors": 28501,
+ "mays": 35445,
+ "maythe": 42281,
+ "mayward": 45751,
+ "mayward": 23519,
+ "mayweather": 22774,
+ "maz": 9177,
+ "maz": 36215,
+ "mazda": 18506,
+ "maze": 21988,
+ "mazz": 29439,
+ "mañ": 37059,
+ "mañana": 39354,
+ "mb": 758,
+ "mb": 3996,
+ "mba": 8329,
+ "mban": 46685,
+ "mbar": 44452,
+ "mbb": 10736,
+ "mbc": 20137,
+ "mbe": 38395,
+ "mbe": 27004,
+ "mber": 5467,
+ "mber": 1034,
+ "mberg": 26372,
+ "mbers": 5443,
+ "mbi": 45347,
+ "mble": 20310,
+ "mble": 4756,
+ "mbles": 28693,
+ "mbling": 28604,
+ "mbo": 25733,
+ "mbo": 11319,
+ "mbps": 44896,
+ "mbs": 10370,
+ "mbta": 38979,
+ "mbu": 42228,
+ "mbuhari": 36752,
+ "mc": 1278,
+ "mc": 4126,
+ "mca": 40570,
+ "mca": 14635,
+ "mcal": 28663,
+ "mcar": 43776,
+ "mcbride": 35080,
+ "mcc": 21192,
+ "mccabe": 37628,
+ "mccaf": 47385,
+ "mccain": 20397,
+ "mccall": 34844,
+ "mccann": 27140,
+ "mccar": 9570,
+ "mccarthy": 16974,
+ "mccartney": 19958,
+ "mccl": 24709,
+ "mccla": 43672,
+ "mccle": 40139,
+ "mcclure": 44945,
+ "mcco": 46152,
+ "mccon": 32638,
+ "mccor": 23057,
+ "mccormack": 45164,
+ "mccormick": 39088,
+ "mccoy": 20218,
+ "mccr": 41996,
+ "mccre": 25393,
+ "mccul": 38833,
+ "mccull": 41782,
+ "mcd": 28930,
+ "mcder": 27355,
+ "mcdermott": 34504,
+ "mcdon": 12171,
+ "mcdonald": 10741,
+ "mcdonalds": 17674,
+ "mcdonnell": 34360,
+ "mcdowell": 34119,
+ "mce": 26864,
+ "mcel": 28752,
+ "mcen": 47423,
+ "mcfad": 36976,
+ "mcfadden": 42105,
+ "mcfar": 29020,
+ "mcfarlane": 47174,
+ "mcfc": 16416,
+ "mcfly": 38211,
+ "mcg": 42507,
+ "mcg": 27995,
+ "mcgee": 29223,
+ "mcgill": 46524,
+ "mcgill": 35511,
+ "mcgin": 29596,
+ "mcgowan": 40462,
+ "mcgr": 25169,
+ "mcgra": 29367,
+ "mcgrath": 28759,
+ "mcgraw": 40950,
+ "mcgregor": 19642,
+ "mcgu": 34294,
+ "mcguinness": 45299,
+ "mcguire": 32635,
+ "mci": 46212,
+ "mci": 45491,
+ "mcil": 30481,
+ "mcin": 18770,
+ "mcintosh": 45353,
+ "mcintyre": 33369,
+ "mck": 6781,
+ "mckay": 33611,
+ "mcke": 27424,
+ "mckee": 43529,
+ "mcken": 42619,
+ "mckenna": 24924,
+ "mckenzie": 25502,
+ "mckin": 15437,
+ "mckinley": 39891,
+ "mckinney": 33554,
+ "mckinnon": 48736,
+ "mckinsey": 48143,
+ "mcl": 49021,
+ "mcla": 12565,
+ "mclaren": 37381,
+ "mclaren": 16789,
+ "mclau": 32285,
+ "mclaughlin": 35346,
+ "mcle": 25299,
+ "mclean": 28666,
+ "mcleod": 40259,
+ "mcm": 12251,
+ "mcmahon": 24026,
+ "mcmaster": 42703,
+ "mcmillan": 45603,
+ "mcn": 42919,
+ "mcnam": 32682,
+ "mcnamara": 37506,
+ "mcne": 42545,
+ "mco": 33723,
+ "mcqueen": 22544,
+ "mcr": 29884,
+ "mcr": 16966,
+ "mcs": 27020,
+ "mcu": 30403,
+ "md": 8637,
+ "md": 4732,
+ "mdc": 38773,
+ "mdc": 41761,
+ "mds": 48746,
+ "mdt": 40822,
+ "me": 613,
+ "me": 614,
+ "mea": 46045,
+ "mea": 17711,
+ "mead": 12134,
+ "mead": 21567,
+ "meade": 37218,
+ "meado": 16402,
+ "meadow": 25213,
+ "meadow": 17195,
+ "meadows": 17178,
+ "meal": 29662,
+ "meal": 5478,
+ "meals": 11229,
+ "mean": 4189,
+ "mean": 3450,
+ "meand": 48015,
+ "meaning": 14586,
+ "meaning": 8342,
+ "meaningful": 17480,
+ "meaningless": 48932,
+ "meanings": 45814,
+ "means": 3494,
+ "meant": 8674,
+ "meantime": 27499,
+ "meanwhile": 9650,
+ "meas": 5867,
+ "measles": 38230,
+ "measurable": 48010,
+ "measure": 15261,
+ "measure": 10579,
+ "measured": 23154,
+ "measurement": 20973,
+ "measurements": 29894,
+ "measures": 11936,
+ "measuring": 18064,
+ "meat": 10805,
+ "meat": 6480,
+ "meatball": 43642,
+ "meatballs": 29233,
+ "meath": 37920,
+ "meatless": 48085,
+ "meats": 29558,
+ "mec": 27432,
+ "mecca": 36095,
+ "mech": 38305,
+ "mechan": 6715,
+ "mechanic": 24582,
+ "mechanical": 14467,
+ "mechanics": 20536,
+ "mechanism": 22576,
+ "mechanisms": 28610,
+ "meck": 41908,
+ "med": 1948,
+ "med": 2177,
+ "meda": 33614,
+ "medal": 29714,
+ "medal": 6974,
+ "medalist": 21040,
+ "medalists": 43397,
+ "medalli": 31349,
+ "medallion": 43469,
+ "medallist": 41472,
+ "medals": 14710,
+ "mede": 48225,
+ "meded": 27627,
+ "medi": 1436,
+ "media": 22064,
+ "media": 1895,
+ "mediac": 37490,
+ "median": 30491,
+ "mediation": 42829,
+ "medic": 3602,
+ "medic": 35441,
+ "medicaid": 25421,
+ "medical": 18432,
+ "medical": 4116,
+ "medicare": 23710,
+ "medication": 23771,
+ "medications": 37181,
+ "medicinal": 28772,
+ "medicine": 5616,
+ "medicines": 26541,
+ "medics": 46688,
+ "medieval": 38956,
+ "medieval": 10789,
+ "medina": 27281,
+ "mediocre": 41170,
+ "medit": 19130,
+ "meditate": 38039,
+ "meditation": 10827,
+ "mediter": 14194,
+ "mediterran": 14358,
+ "mediterranean": 15327,
+ "medium": 8675,
+ "medley": 24793,
+ "meds": 25075,
+ "medtech": 42044,
+ "medusa": 44216,
+ "medway": 42286,
+ "mee": 1725,
+ "mee": 14075,
+ "meek": 28935,
+ "meen": 37940,
+ "meen": 46515,
+ "meer": 26714,
+ "meer": 27555,
+ "meet": 5714,
+ "meet": 1633,
+ "meeting": 48566,
+ "meeting": 2071,
+ "meetings": 9980,
+ "meets": 5972,
+ "meetthe": 27575,
+ "meetup": 15430,
+ "meg": 11500,
+ "meg": 16186,
+ "mega": 15979,
+ "mega": 9068,
+ "megab": 38103,
+ "megadeth": 46741,
+ "megal": 37650,
+ "megam": 26073,
+ "megan": 19127,
+ "megan": 11503,
+ "megap": 33624,
+ "megat": 35581,
+ "megh": 31192,
+ "meghan": 39939,
+ "meghan": 18261,
+ "meh": 10512,
+ "meh": 22211,
+ "mehta": 25031,
+ "mei": 22564,
+ "mei": 25198,
+ "meier": 29812,
+ "mein": 28857,
+ "mein": 21466,
+ "meister": 28407,
+ "mek": 44645,
+ "mel": 1902,
+ "mel": 6834,
+ "mela": 35032,
+ "melan": 22261,
+ "melanch": 44818,
+ "melancholy": 47821,
+ "melani": 34031,
+ "melania": 32796,
+ "melanie": 22153,
+ "melanoma": 40862,
+ "melb": 47007,
+ "melb": 28980,
+ "melbourne": 28387,
+ "melbourne": 6995,
+ "melee": 45108,
+ "meli": 28885,
+ "melinda": 46303,
+ "melis": 18913,
+ "melissa": 41866,
+ "melissa": 13030,
+ "mell": 22531,
+ "mell": 41583,
+ "mello": 47594,
+ "mellon": 45162,
+ "mellow": 32034,
+ "melo": 10354,
+ "melo": 22374,
+ "melodic": 41877,
+ "melodies": 38412,
+ "melody": 19119,
+ "melon": 12146,
+ "melrose": 36296,
+ "melt": 22209,
+ "melt": 15957,
+ "meltdown": 30613,
+ "melted": 23037,
+ "melting": 19247,
+ "melton": 46062,
+ "melts": 31446,
+ "melville": 46030,
+ "melvin": 31544,
+ "mely": 6373,
+ "mem": 4937,
+ "mem": 34944,
+ "memb": 2114,
+ "member": 29566,
+ "member": 1640,
+ "members": 2567,
+ "membership": 11562,
+ "membrane": 34088,
+ "meme": 35157,
+ "meme": 9169,
+ "memes": 12828,
+ "memo": 15967,
+ "memo": 19334,
+ "memoir": 20532,
+ "memoirs": 45311,
+ "memor": 1858,
+ "memorab": 26271,
+ "memorabilia": 27488,
+ "memorable": 13172,
+ "memorial": 16285,
+ "memorial": 4642,
+ "memorialday": 21598,
+ "memoriam": 48191,
+ "memories": 4304,
+ "memory": 44766,
+ "memory": 5137,
+ "memph": 10285,
+ "memphis": 38432,
+ "memphis": 11298,
+ "men": 1552,
+ "men": 1656,
+ "mena": 23052,
+ "menace": 29949,
+ "mend": 8151,
+ "mend": 46927,
+ "mendel": 49268,
+ "mendes": 18060,
+ "mendez": 48275,
+ "mendo": 19327,
+ "mendoza": 23680,
+ "meng": 37102,
+ "meng": 37450,
+ "mening": 46428,
+ "menon": 38255,
+ "menopau": 34974,
+ "menopause": 46026,
+ "mens": 16924,
+ "mens": 10495,
+ "mensfashion": 27578,
+ "menstru": 28345,
+ "menstrual": 40915,
+ "menswear": 18803,
+ "ment": 1585,
+ "ment": 777,
+ "mental": 8611,
+ "mental": 3448,
+ "mentalhealth": 20593,
+ "mentalhealth": 13022,
+ "mentality": 26647,
+ "mentally": 14307,
+ "mentary": 4468,
+ "mentation": 9512,
+ "mentday": 40397,
+ "mente": 40302,
+ "mente": 36396,
+ "mented": 9249,
+ "menting": 14471,
+ "mention": 43881,
+ "mention": 6762,
+ "mentioned": 11948,
+ "mentioning": 34290,
+ "mentions": 12334,
+ "mento": 30582,
+ "mentor": 45342,
+ "mentor": 11642,
+ "mentoring": 19610,
+ "mentors": 20945,
+ "mentorship": 33878,
+ "ments": 1827,
+ "menu": 6225,
+ "menus": 33534,
+ "meo": 30792,
+ "meow": 39965,
+ "meow": 17246,
+ "mep": 27095,
+ "mer": 1316,
+ "mer": 2452,
+ "mera": 20028,
+ "merc": 34357,
+ "merc": 44399,
+ "mercado": 45479,
+ "merce": 8409,
+ "mercede": 34959,
+ "mercedes": 26403,
+ "mercedes": 10685,
+ "mercedesam": 40107,
+ "mercedesbenz": 32347,
+ "mercen": 40301,
+ "mercer": 21632,
+ "merch": 11504,
+ "merchandi": 14954,
+ "merchandise": 16808,
+ "merchandising": 49196,
+ "merchant": 19563,
+ "merchants": 34427,
+ "merci": 23364,
+ "merci": 29378,
+ "mercur": 11471,
+ "mercury": 45203,
+ "mercury": 12653,
+ "mercy": 33249,
+ "mercy": 10815,
+ "mere": 29657,
+ "mere": 10342,
+ "mered": 24657,
+ "mered": 32297,
+ "meredith": 25103,
+ "merely": 28718,
+ "merge": 30406,
+ "merged": 46492,
+ "merger": 24744,
+ "merging": 49256,
+ "meri": 17993,
+ "meri": 36109,
+ "meria": 48433,
+ "meric": 27097,
+ "merica": 30561,
+ "meridi": 37901,
+ "meridian": 31195,
+ "mering": 41060,
+ "meringue": 41661,
+ "merino": 42648,
+ "merit": 20830,
+ "merkel": 24715,
+ "merle": 48586,
+ "merlin": 26517,
+ "merlot": 40424,
+ "mermaid": 16064,
+ "mermaids": 43617,
+ "mero": 19097,
+ "merr": 48288,
+ "merri": 21462,
+ "merrill": 47713,
+ "merritt": 36462,
+ "merry": 14167,
+ "merry": 5779,
+ "merrychristmas": 19672,
+ "mers": 4199,
+ "mersal": 36711,
+ "mersey": 25248,
+ "mersey": 46239,
+ "merseyside": 35382,
+ "mert": 48496,
+ "merton": 35315,
+ "mery": 40873,
+ "meryl": 35787,
+ "mes": 28432,
+ "mes": 3029,
+ "mesa": 18956,
+ "mese": 42018,
+ "mesh": 15030,
+ "mesm": 18695,
+ "mesmer": 38435,
+ "mesmeri": 25985,
+ "mesmerizing": 35637,
+ "meso": 25537,
+ "mesqu": 46819,
+ "mess": 2490,
+ "mess": 8188,
+ "message": 3918,
+ "messages": 9390,
+ "messaging": 23234,
+ "messe": 40391,
+ "messed": 23580,
+ "messenger": 17389,
+ "messi": 19394,
+ "messi": 11252,
+ "messiah": 28737,
+ "messing": 23144,
+ "messy": 15987,
+ "mest": 23780,
+ "mester": 47349,
+ "mesut": 49177,
+ "met": 5249,
+ "met": 2340,
+ "meta": 14803,
+ "meta": 22701,
+ "metab": 16150,
+ "metabol": 48389,
+ "metaboli": 25573,
+ "metabolic": 34311,
+ "metabolism": 27824,
+ "metal": 8935,
+ "metal": 4044,
+ "metall": 19084,
+ "metallic": 17257,
+ "metallica": 24079,
+ "metals": 21375,
+ "metam": 28862,
+ "metamor": 39030,
+ "metamorpho": 47601,
+ "metaph": 24189,
+ "metaphor": 34233,
+ "metast": 41973,
+ "mete": 11226,
+ "meteor": 26429,
+ "meteor": 26823,
+ "meteoro": 25948,
+ "meteorologist": 42849,
+ "meter": 10104,
+ "meters": 13247,
+ "metgala": 30089,
+ "meth": 21867,
+ "meth": 26177,
+ "methane": 37565,
+ "metho": 5770,
+ "method": 10284,
+ "methodist": 25165,
+ "methodo": 28488,
+ "methodology": 37316,
+ "methods": 12200,
+ "methyl": 48999,
+ "metmuseum": 28207,
+ "meto": 25679,
+ "metoo": 24722,
+ "metr": 15086,
+ "metre": 27889,
+ "metres": 19798,
+ "metric": 19950,
+ "metrical": 40704,
+ "metrics": 24396,
+ "metro": 7257,
+ "metro": 6784,
+ "metroid": 39957,
+ "metropolis": 40476,
+ "metropolitan": 19013,
+ "metry": 20039,
+ "mets": 9633,
+ "mett": 28081,
+ "metz": 40506,
+ "meu": 34520,
+ "mew": 40368,
+ "mex": 3213,
+ "mex": 18387,
+ "mexic": 31728,
+ "mexican": 37442,
+ "mexican": 8186,
+ "mexicans": 47729,
+ "mexico": 31834,
+ "mexico": 4604,
+ "mey": 28584,
+ "mey": 27777,
+ "meyer": 13963,
+ "meyers": 32326,
+ "mez": 30615,
+ "mez": 46833,
+ "mezz": 38771,
+ "mf": 18199,
+ "mf": 11067,
+ "mfa": 24107,
+ "mfc": 39474,
+ "mfg": 21912,
+ "mfw": 27309,
+ "mg": 10003,
+ "mg": 8014,
+ "mga": 23954,
+ "mgm": 27572,
+ "mgmt": 22288,
+ "mgr": 31500,
+ "mgs": 48073,
+ "mgt": 48663,
+ "mh": 9962,
+ "mh": 10834,
+ "mha": 41944,
+ "mhealth": 41225,
+ "mhs": 28815,
+ "mhz": 31550,
+ "mi": 714,
+ "mi": 2251,
+ "mia": 5852,
+ "miam": 31053,
+ "miami": 15106,
+ "miami": 4891,
+ "mian": 24792,
+ "miaw": 36046,
+ "mib": 48178,
+ "mic": 1213,
+ "mic": 3816,
+ "mica": 41551,
+ "micah": 33870,
+ "mice": 19030,
+ "mich": 25628,
+ "mich": 23029,
+ "micha": 2083,
+ "michael": 6051,
+ "michael": 2511,
+ "michaela": 41897,
+ "michaeljackson": 33532,
+ "michaels": 23868,
+ "michal": 47144,
+ "miche": 37966,
+ "micheal": 43709,
+ "michel": 5158,
+ "michel": 17153,
+ "michelangelo": 41245,
+ "michele": 20642,
+ "michelin": 26330,
+ "michelle": 19028,
+ "michelle": 8625,
+ "michi": 5658,
+ "michigan": 32344,
+ "michigan": 6296,
+ "mick": 15171,
+ "mick": 12592,
+ "mickey": 41813,
+ "mickey": 13053,
+ "micky": 43011,
+ "micro": 3160,
+ "micro": 11374,
+ "microbes": 44671,
+ "microbi": 19496,
+ "microbial": 30335,
+ "microbiology": 35348,
+ "microbiome": 35148,
+ "micron": 48742,
+ "microphone": 24643,
+ "micropoetry": 35997,
+ "microscope": 29114,
+ "microscopy": 38431,
+ "microsof": 42424,
+ "microsoft": 38650,
+ "microsoft": 7254,
+ "microwave": 24240,
+ "mics": 16554,
+ "mid": 2192,
+ "mid": 4734,
+ "midcentury": 48988,
+ "midd": 2983,
+ "midday": 23390,
+ "middle": 9849,
+ "middle": 3694,
+ "middleeast": 32783,
+ "middles": 29769,
+ "middlesbrough": 32436,
+ "middlesex": 39154,
+ "middleton": 23627,
+ "middleweight": 35829,
+ "midfield": 28116,
+ "midfielder": 13423,
+ "midget": 30734,
+ "midi": 39496,
+ "midi": 27326,
+ "midland": 24822,
+ "midlands": 18062,
+ "midnight": 35746,
+ "midnight": 6302,
+ "mids": 40821,
+ "midst": 24752,
+ "midsummer": 35234,
+ "midterm": 34365,
+ "midterms": 32015,
+ "midtown": 26069,
+ "midway": 26536,
+ "midweek": 29120,
+ "midwest": 16627,
+ "midwi": 44802,
+ "midwife": 37681,
+ "midwives": 42355,
+ "mie": 20865,
+ "mie": 10555,
+ "miento": 46482,
+ "mier": 36490,
+ "mies": 8840,
+ "miff": 49398,
+ "mig": 28743,
+ "might": 2727,
+ "mighty": 26632,
+ "mighty": 7815,
+ "mign": 41678,
+ "migos": 44640,
+ "migr": 3736,
+ "migra": 28186,
+ "migraine": 35360,
+ "migrant": 18902,
+ "migrants": 15814,
+ "migrate": 41804,
+ "migrating": 43604,
+ "migration": 11891,
+ "migu": 12279,
+ "miguel": 33672,
+ "miguel": 14436,
+ "miho": 46870,
+ "mii": 39896,
+ "mik": 15096,
+ "mik": 46203,
+ "mika": 28609,
+ "mika": 25185,
+ "mike": 5884,
+ "mike": 3178,
+ "mikel": 48865,
+ "mikequind": 33508,
+ "mikequindazzi": 33551,
+ "mikey": 34934,
+ "mikey": 23368,
+ "mikha": 30999,
+ "mikhail": 38327,
+ "miki": 48863,
+ "miko": 35413,
+ "miku": 37703,
+ "mil": 1469,
+ "mil": 12826,
+ "mila": 26183,
+ "milan": 30380,
+ "milan": 8552,
+ "milano": 18585,
+ "milb": 42248,
+ "mild": 16085,
+ "mildly": 49059,
+ "mile": 7833,
+ "mile": 6243,
+ "mileage": 30579,
+ "miler": 44680,
+ "miles": 3446,
+ "milestone": 13485,
+ "milestones": 34025,
+ "miley": 25336,
+ "miley": 14321,
+ "mileycyrus": 28528,
+ "milf": 45386,
+ "milford": 35840,
+ "mili": 16698,
+ "miliband": 41440,
+ "milit": 3715,
+ "militant": 33629,
+ "militants": 23974,
+ "military": 24498,
+ "military": 4323,
+ "militi": 46625,
+ "militia": 32114,
+ "milk": 13409,
+ "milk": 5205,
+ "milkshake": 29066,
+ "milky": 37320,
+ "milky": 21120,
+ "milkyway": 43246,
+ "mill": 4221,
+ "mill": 6637,
+ "milla": 49381,
+ "millan": 34930,
+ "millan": 22188,
+ "millar": 41851,
+ "mille": 34066,
+ "millen": 48501,
+ "millenni": 10406,
+ "millennial": 28357,
+ "millennials": 18804,
+ "millennium": 21116,
+ "miller": 21699,
+ "miller": 5733,
+ "milli": 5340,
+ "millie": 29283,
+ "milling": 39133,
+ "million": 13154,
+ "million": 2506,
+ "millionaire": 25179,
+ "millionaires": 47159,
+ "millions": 8492,
+ "mills": 10331,
+ "millwall": 35902,
+ "milly": 45794,
+ "milne": 44590,
+ "milner": 45230,
+ "milo": 24548,
+ "milton": 39004,
+ "milton": 17360,
+ "milwau": 13452,
+ "milwaukee": 14259,
+ "mim": 39379,
+ "mimi": 27086,
+ "mimic": 47116,
+ "mimic": 46519,
+ "mimo": 45551,
+ "min": 771,
+ "min": 3331,
+ "mina": 15281,
+ "minaj": 25136,
+ "minal": 40222,
+ "minat": 33275,
+ "mince": 32396,
+ "mind": 5890,
+ "mind": 2575,
+ "mindanao": 44228,
+ "minded": 21330,
+ "mindful": 28457,
+ "mindfulness": 15707,
+ "minding": 45337,
+ "minds": 9244,
+ "mindset": 14217,
+ "mindy": 46875,
+ "mindy": 38551,
+ "mine": 20149,
+ "mine": 3347,
+ "minecraft": 15678,
+ "mined": 48034,
+ "minent": 12533,
+ "miner": 14109,
+ "miner": 26572,
+ "mineral": 17692,
+ "minerals": 21169,
+ "miners": 22119,
+ "mines": 16211,
+ "ming": 10868,
+ "ming": 2107,
+ "mingham": 7590,
+ "mingle": 38437,
+ "mingly": 36909,
+ "mington": 49283,
+ "mington": 23119,
+ "minh": 48734,
+ "minho": 21318,
+ "mini": 1810,
+ "mini": 3954,
+ "miniature": 44298,
+ "miniature": 16377,
+ "miniatures": 38816,
+ "minic": 31522,
+ "minim": 10005,
+ "minimal": 18458,
+ "minimalism": 42594,
+ "minimalist": 26641,
+ "minimize": 38697,
+ "minimum": 12244,
+ "minindia": 28458,
+ "mining": 8473,
+ "minion": 28622,
+ "minions": 27035,
+ "minis": 33409,
+ "minis": 35976,
+ "minister": 25688,
+ "minister": 3569,
+ "ministerial": 33008,
+ "ministers": 16406,
+ "ministries": 27895,
+ "ministry": 8742,
+ "mink": 42017,
+ "minn": 45991,
+ "minn": 47318,
+ "minne": 7083,
+ "minneapolis": 16977,
+ "minneso": 9380,
+ "minnesota": 9968,
+ "minnie": 24493,
+ "mino": 22791,
+ "minogue": 44202,
+ "minor": 8522,
+ "minorities": 28119,
+ "minority": 16210,
+ "minors": 36789,
+ "mins": 6196,
+ "minsk": 46151,
+ "minster": 11189,
+ "mint": 48084,
+ "mint": 7506,
+ "minted": 49377,
+ "minton": 20050,
+ "minu": 29064,
+ "minus": 15358,
+ "minute": 28931,
+ "minute": 4497,
+ "minutes": 3056,
+ "mio": 26366,
+ "mir": 2750,
+ "mir": 6585,
+ "mira": 21665,
+ "mira": 22762,
+ "mirac": 13685,
+ "miracle": 49208,
+ "miracle": 11543,
+ "miracles": 23478,
+ "miraculous": 38671,
+ "mirage": 28679,
+ "mirai": 49060,
+ "mirand": 32367,
+ "miranda": 17590,
+ "mire": 38140,
+ "mire": 30140,
+ "miri": 22273,
+ "miriam": 30950,
+ "miro": 34851,
+ "miro": 48317,
+ "mirren": 47600,
+ "mirro": 48500,
+ "mirror": 29823,
+ "mirror": 7220,
+ "mirrors": 21823,
+ "mirza": 36440,
+ "mis": 866,
+ "mis": 11239,
+ "mischief": 33896,
+ "misconceptions": 48681,
+ "misconduct": 30601,
+ "mise": 46567,
+ "mise": 17267,
+ "miser": 33394,
+ "miserable": 26196,
+ "misery": 28360,
+ "mises": 24390,
+ "misfits": 42708,
+ "mish": 15494,
+ "mish": 20981,
+ "misha": 35434,
+ "mishra": 33042,
+ "misleading": 30862,
+ "mism": 15948,
+ "miso": 27657,
+ "miso": 33441,
+ "misogy": 31315,
+ "misogyny": 48415,
+ "miss": 6984,
+ "miss": 1526,
+ "missal": 38337,
+ "missed": 3955,
+ "misses": 15844,
+ "missi": 3008,
+ "missile": 14411,
+ "missiles": 27868,
+ "missin": 36209,
+ "missing": 23509,
+ "missing": 3423,
+ "mission": 12738,
+ "mission": 2406,
+ "missionaries": 40580,
+ "missionary": 27915,
+ "missions": 6990,
+ "mississ": 26483,
+ "mississauga": 28393,
+ "mississi": 11687,
+ "mississippi": 12232,
+ "missou": 30710,
+ "missoula": 48549,
+ "missouri": 11835,
+ "missuni": 26347,
+ "missuniverse": 28766,
+ "missy": 48105,
+ "missy": 31515,
+ "missyou": 45799,
+ "mist": 12610,
+ "mist": 11946,
+ "mistak": 20478,
+ "mistake": 11303,
+ "mistaken": 29182,
+ "mistakenly": 48494,
+ "mistakes": 12824,
+ "mister": 26949,
+ "mister": 18895,
+ "mistle": 46800,
+ "mistletoe": 48569,
+ "mistre": 42039,
+ "mistress": 24349,
+ "mists": 28636,
+ "misty": 18799,
+ "misunderstood": 41574,
+ "misuse": 40970,
+ "mit": 3303,
+ "mit": 4551,
+ "mita": 47514,
+ "mitage": 27964,
+ "mitch": 6969,
+ "mitch": 14150,
+ "mitchell": 39339,
+ "mitchell": 9007,
+ "mite": 26929,
+ "mith": 21752,
+ "mith": 17948,
+ "miti": 17857,
+ "mitigate": 42273,
+ "mitigation": 35514,
+ "mito": 38254,
+ "mitochondri": 42132,
+ "mitra": 47703,
+ "mits": 24086,
+ "mitsu": 17905,
+ "mitsubi": 21604,
+ "mitsubishi": 23030,
+ "mitt": 17321,
+ "mitt": 21341,
+ "mitted": 10307,
+ "mitting": 27938,
+ "mitz": 41827,
+ "mium": 35891,
+ "miwx": 43941,
+ "mix": 3210,
+ "mix": 3285,
+ "mixed": 29376,
+ "mixed": 6780,
+ "mixer": 17200,
+ "mixers": 39175,
+ "mixes": 19061,
+ "mixing": 15588,
+ "mixtape": 11044,
+ "mixture": 28286,
+ "miy": 25695,
+ "miya": 36257,
+ "miz": 20881,
+ "miz": 30795,
+ "mize": 19076,
+ "mized": 43418,
+ "mizing": 38715,
+ "mizz": 19985,
+ "mizzou": 26165,
+ "mj": 13117,
+ "mj": 14733,
+ "mk": 11581,
+ "mk": 8937,
+ "mke": 36642,
+ "mkt": 24814,
+ "ml": 3627,
+ "ml": 5780,
+ "mla": 16723,
+ "mlas": 48464,
+ "mlb": 21039,
+ "mlb": 7482,
+ "mley": 40329,
+ "mlg": 45801,
+ "mlin": 24556,
+ "mlk": 17941,
+ "mlkday": 39905,
+ "mlm": 37611,
+ "mln": 18971,
+ "mlp": 23620,
+ "mlpfi": 45475,
+ "mlpfim": 45640,
+ "mls": 13077,
+ "mm": 1028,
+ "mm": 2848,
+ "mma": 34140,
+ "mma": 6096,
+ "mmc": 44253,
+ "mme": 13105,
+ "mmed": 19570,
+ "mmer": 35717,
+ "mmer": 7508,
+ "mmers": 28128,
+ "mmes": 42862,
+ "mmi": 34147,
+ "mming": 21038,
+ "mming": 16507,
+ "mmings": 31357,
+ "mmit": 41050,
+ "mmj": 43015,
+ "mmm": 37908,
+ "mmm": 7641,
+ "mmmm": 36312,
+ "mmmm": 13180,
+ "mmmmm": 21808,
+ "mmmmmm": 43740,
+ "mmo": 30418,
+ "mmon": 41131,
+ "mmor": 36657,
+ "mmorpg": 39476,
+ "mms": 37803,
+ "mmva": 42666,
+ "mmy": 28837,
+ "mmy": 8722,
+ "mn": 5086,
+ "mn": 4057,
+ "mna": 34877,
+ "mnd": 44776,
+ "mnet": 34129,
+ "mnf": 41105,
+ "mnl": 32980,
+ "mnleg": 42653,
+ "mns": 39040,
+ "mnt": 21477,
+ "mntwins": 45448,
+ "mnwild": 39044,
+ "mnwx": 39592,
+ "mo": 617,
+ "mo": 2080,
+ "moa": 33174,
+ "moana": 43241,
+ "mob": 2818,
+ "mob": 12754,
+ "mobi": 9451,
+ "mobil": 26343,
+ "mobil": 29815,
+ "mobile": 12935,
+ "mobile": 3451,
+ "mobiles": 44302,
+ "mobili": 20770,
+ "mobility": 12546,
+ "mobilization": 48916,
+ "moby": 47219,
+ "moc": 41439,
+ "moc": 36992,
+ "mocha": 28425,
+ "mochi": 47973,
+ "mock": 15641,
+ "mock": 12759,
+ "mocked": 47400,
+ "mocking": 28692,
+ "mocking": 37870,
+ "mocks": 35142,
+ "mod": 6362,
+ "mod": 10893,
+ "moda": 25814,
+ "modal": 33157,
+ "mode": 20402,
+ "mode": 6493,
+ "model": 4591,
+ "model": 2863,
+ "modeled": 39527,
+ "modeling": 13706,
+ "modelling": 19946,
+ "models": 6176,
+ "moder": 2894,
+ "moderate": 16435,
+ "moderated": 27928,
+ "moderating": 34242,
+ "moderator": 32659,
+ "modern": 11706,
+ "modern": 4077,
+ "modernart": 34417,
+ "moderni": 24328,
+ "modernism": 39601,
+ "modernist": 36773,
+ "modernization": 47294,
+ "modes": 30454,
+ "modest": 25436,
+ "modi": 9047,
+ "modi": 7774,
+ "modification": 37630,
+ "modified": 17964,
+ "modo": 36820,
+ "mods": 23843,
+ "modu": 9036,
+ "modular": 22437,
+ "module": 16757,
+ "modules": 30575,
+ "moe": 38655,
+ "moe": 17938,
+ "mof": 30798,
+ "moff": 27160,
+ "mog": 42362,
+ "moga": 41732,
+ "mogadishu": 45133,
+ "mogul": 41320,
+ "moh": 18979,
+ "moh": 35388,
+ "moha": 46892,
+ "moham": 7923,
+ "mohamed": 18472,
+ "mohammad": 19926,
+ "mohammed": 16168,
+ "mohan": 26521,
+ "mohan": 23586,
+ "mohawk": 34942,
+ "mohd": 49094,
+ "mohsin": 48861,
+ "moi": 20691,
+ "moi": 21825,
+ "moil": 30349,
+ "moines": 32091,
+ "moist": 19831,
+ "moist": 33263,
+ "moisture": 20412,
+ "moisturi": 25942,
+ "moj": 34505,
+ "moja": 49055,
+ "mojito": 46830,
+ "mojo": 25204,
+ "mok": 49146,
+ "mol": 4246,
+ "mol": 31582,
+ "mold": 21846,
+ "molding": 46274,
+ "moldova": 47317,
+ "mole": 9927,
+ "mole": 23529,
+ "molecular": 19370,
+ "molecule": 39233,
+ "molecules": 35643,
+ "molina": 34201,
+ "mollie": 48203,
+ "molly": 24368,
+ "molly": 12573,
+ "molo": 41510,
+ "mology": 32255,
+ "molten": 46071,
+ "moly": 47083,
+ "mom": 1614,
+ "mom": 2543,
+ "moma": 33605,
+ "mombasa": 40340,
+ "moment": 12197,
+ "moment": 2495,
+ "momento": 30078,
+ "moments": 5251,
+ "momentum": 15722,
+ "momlife": 43825,
+ "momma": 14508,
+ "mommy": 12456,
+ "momo": 48490,
+ "momo": 25980,
+ "moms": 28446,
+ "moms": 10042,
+ "momsdemand": 33744,
+ "mon": 749,
+ "mon": 2173,
+ "mona": 19143,
+ "monaco": 14938,
+ "monaghan": 39797,
+ "monarch": 27235,
+ "monarch": 22619,
+ "monarchs": 36750,
+ "monarchy": 47503,
+ "monaster": 19422,
+ "monastery": 21850,
+ "monc": 34847,
+ "moncton": 44962,
+ "mond": 14522,
+ "mond": 4475,
+ "monday": 6205,
+ "monday": 2098,
+ "mondaymorning": 40089,
+ "mondaymotiv": 45488,
+ "mondaymotivation": 8198,
+ "mondaymotivaton": 47034,
+ "mondays": 13815,
+ "monde": 29339,
+ "mondo": 36207,
+ "monds": 20317,
+ "mone": 25990,
+ "monet": 24499,
+ "monetary": 26394,
+ "moneti": 38056,
+ "money": 12743,
+ "money": 2327,
+ "mong": 43566,
+ "monger": 38928,
+ "mongers": 27670,
+ "mongo": 20680,
+ "mongolia": 27144,
+ "mongolian": 46335,
+ "moni": 46851,
+ "monia": 31161,
+ "monic": 30893,
+ "monica": 13540,
+ "monit": 9014,
+ "monitor": 10198,
+ "monitored": 45828,
+ "monitoring": 11030,
+ "monitors": 30478,
+ "monk": 30557,
+ "monk": 16424,
+ "monkey": 29597,
+ "monkey": 9465,
+ "monkeys": 15781,
+ "monks": 29090,
+ "monmouth": 36929,
+ "mono": 8220,
+ "mono": 22537,
+ "monochrome": 25576,
+ "monogram": 39665,
+ "monologue": 47776,
+ "monopoly": 25241,
+ "monoxide": 49314,
+ "monro": 45750,
+ "monroe": 13625,
+ "mons": 19885,
+ "monsanto": 37592,
+ "monsi": 46677,
+ "monsieur": 48879,
+ "monsoon": 18872,
+ "monsta": 30718,
+ "monstax": 45631,
+ "monste": 47045,
+ "monster": 14454,
+ "monster": 6060,
+ "monsters": 11546,
+ "mont": 5186,
+ "mont": 5382,
+ "montag": 37202,
+ "montage": 32325,
+ "montal": 42126,
+ "montan": 28405,
+ "montana": 11436,
+ "monte": 8711,
+ "monte": 14667,
+ "montene": 28538,
+ "montenegro": 30378,
+ "monter": 36673,
+ "monterey": 23388,
+ "monterrey": 45254,
+ "montess": 43205,
+ "montessori": 45443,
+ "montgom": 13852,
+ "montgomery": 14951,
+ "month": 7680,
+ "month": 1924,
+ "monthly": 8764,
+ "months": 3109,
+ "monthsary": 42420,
+ "monton": 41961,
+ "montp": 39523,
+ "montre": 8434,
+ "montreal": 9262,
+ "montrose": 42347,
+ "monty": 43997,
+ "monty": 24038,
+ "monu": 9748,
+ "monument": 12019,
+ "monumental": 31297,
+ "monuments": 26916,
+ "mony": 4117,
+ "monza": 40380,
+ "moo": 4953,
+ "moo": 24626,
+ "mood": 42358,
+ "mood": 5394,
+ "moods": 43727,
+ "moody": 17170,
+ "moom": 36887,
+ "moon": 6334,
+ "moon": 3293,
+ "mooney": 37942,
+ "moonlight": 20001,
+ "moons": 29887,
+ "moonshine": 46706,
+ "moor": 14817,
+ "moor": 11877,
+ "moore": 28613,
+ "moore": 6708,
+ "moors": 32577,
+ "moose": 37562,
+ "moose": 17338,
+ "moot": 46895,
+ "mop": 33900,
+ "mopar": 41166,
+ "mor": 657,
+ "mor": 18614,
+ "mora": 29262,
+ "moral": 11246,
+ "morale": 39404,
+ "morales": 27117,
+ "morality": 34133,
+ "morally": 42519,
+ "morals": 46223,
+ "moran": 21557,
+ "moray": 44569,
+ "more": 5434,
+ "more": 750,
+ "morecam": 37305,
+ "morecambe": 43414,
+ "mored": 20195,
+ "moreland": 44135,
+ "moreno": 24826,
+ "morethan": 30889,
+ "morg": 34284,
+ "morgan": 15432,
+ "morgan": 6075,
+ "morgen": 35106,
+ "mori": 25710,
+ "mori": 29514,
+ "moris": 43131,
+ "moritz": 45594,
+ "morley": 40439,
+ "mormon": 27715,
+ "morn": 22393,
+ "mornin": 28327,
+ "morning": 10769,
+ "morning": 1119,
+ "mornings": 12106,
+ "moro": 31613,
+ "moroc": 11996,
+ "moroccan": 27546,
+ "morocco": 15228,
+ "moron": 31875,
+ "morons": 46477,
+ "morow": 40779,
+ "morph": 23915,
+ "morph": 41700,
+ "morphe": 38978,
+ "morpho": 38622,
+ "morrha": 43044,
+ "morri": 9876,
+ "morris": 22560,
+ "morris": 9090,
+ "morrison": 40961,
+ "morrison": 14094,
+ "morrisons": 40965,
+ "morrissey": 30040,
+ "morro": 48363,
+ "morrow": 21611,
+ "mors": 13064,
+ "morse": 25282,
+ "mort": 24257,
+ "mort": 30583,
+ "mortal": 31883,
+ "mortal": 14680,
+ "mortality": 20347,
+ "mortar": 27258,
+ "mortg": 12069,
+ "mortgage": 13988,
+ "mortgages": 45391,
+ "mortimer": 47836,
+ "morton": 20698,
+ "morty": 37391,
+ "mory": 22633,
+ "mos": 28658,
+ "mos": 9593,
+ "mosa": 14164,
+ "mosa": 23809,
+ "mosaic": 17506,
+ "mosch": 47003,
+ "mosco": 9840,
+ "moscow": 10371,
+ "moseley": 47080,
+ "moses": 18451,
+ "mosley": 46228,
+ "mosqu": 15215,
+ "mosque": 12694,
+ "mosques": 41214,
+ "mosquit": 39699,
+ "mosquito": 25083,
+ "mosquitoes": 41870,
+ "moss": 25107,
+ "moss": 12815,
+ "most": 7034,
+ "most": 1096,
+ "mostly": 8829,
+ "mosul": 29165,
+ "mot": 16352,
+ "mot": 15452,
+ "mota": 42499,
+ "motd": 46232,
+ "motel": 26191,
+ "moth": 33208,
+ "moth": 11736,
+ "mother": 7455,
+ "mother": 3050,
+ "motherhood": 32274,
+ "motherland": 46774,
+ "mothers": 10546,
+ "mothersday": 15583,
+ "motherwell": 48104,
+ "moths": 29086,
+ "moti": 38210,
+ "motif": 35373,
+ "motion": 32139,
+ "motion": 7860,
+ "motiv": 3183,
+ "motivate": 26771,
+ "motivated": 16521,
+ "motivates": 44684,
+ "motivating": 37720,
+ "motivation": 26117,
+ "motivation": 4193,
+ "motivational": 32832,
+ "motivational": 20472,
+ "motivationmonday": 28703,
+ "motive": 36669,
+ "motley": 42553,
+ "motm": 41192,
+ "moto": 10646,
+ "moto": 11431,
+ "motocross": 34562,
+ "motogp": 16615,
+ "motor": 3975,
+ "motor": 7659,
+ "motorbike": 33341,
+ "motorcycle": 10297,
+ "motorcycles": 24869,
+ "motoring": 44491,
+ "motorists": 32766,
+ "motorola": 33738,
+ "motors": 14989,
+ "motorsport": 18371,
+ "motorsports": 24264,
+ "motorway": 31808,
+ "motown": 32685,
+ "mott": 44570,
+ "mott": 21708,
+ "motto": 23338,
+ "mou": 2809,
+ "mou": 25289,
+ "moud": 37698,
+ "moul": 25725,
+ "mould": 36743,
+ "moulin": 47656,
+ "moun": 2023,
+ "mound": 21414,
+ "mount": 20553,
+ "mount": 5532,
+ "mountain": 14547,
+ "mountain": 3965,
+ "mountaine": 24841,
+ "mountaineer": 49255,
+ "mountains": 5873,
+ "mounted": 17897,
+ "mounting": 29910,
+ "mounts": 36767,
+ "mour": 9053,
+ "mour": 42446,
+ "moured": 29555,
+ "mourinho": 18536,
+ "mourn": 33592,
+ "mourning": 24169,
+ "mourns": 42811,
+ "mous": 24837,
+ "mous": 17425,
+ "mouse": 33032,
+ "mouse": 9301,
+ "mousse": 31869,
+ "moustache": 32795,
+ "mouth": 15152,
+ "mouth": 4932,
+ "mouths": 38518,
+ "mov": 23950,
+ "move": 16624,
+ "move": 2783,
+ "moved": 6997,
+ "movember": 23474,
+ "movement": 5208,
+ "movements": 19665,
+ "mover": 37673,
+ "movers": 33957,
+ "moves": 6880,
+ "movi": 1707,
+ "movic": 43838,
+ "movie": 11247,
+ "movie": 2016,
+ "movies": 4772,
+ "moving": 32160,
+ "moving": 3584,
+ "mow": 31006,
+ "mow": 36329,
+ "mower": 30895,
+ "mowing": 46424,
+ "mowx": 44263,
+ "moy": 27276,
+ "moy": 34205,
+ "moyes": 37119,
+ "moz": 14761,
+ "moz": 43738,
+ "mozam": 26648,
+ "mozambique": 28831,
+ "mozart": 22132,
+ "mozz": 26317,
+ "mozzarella": 27845,
+ "mp": 1037,
+ "mp": 1246,
+ "mpa": 30749,
+ "mpc": 38560,
+ "mpd": 33814,
+ "mped": 28134,
+ "mper": 22803,
+ "mpg": 39830,
+ "mpg": 37454,
+ "mpgvip": 42149,
+ "mph": 5306,
+ "mpi": 43263,
+ "mping": 27999,
+ "mple": 21139,
+ "mplo": 47071,
+ "mpls": 34298,
+ "mpo": 33674,
+ "mpp": 39570,
+ "mps": 5504,
+ "mption": 9717,
+ "mpton": 27448,
+ "mpu": 47156,
+ "mpus": 25864,
+ "mpy": 17192,
+ "mq": 19103,
+ "mqm": 24687,
+ "mr": 3139,
+ "mr": 1982,
+ "mra": 44568,
+ "mrc": 25897,
+ "mri": 24773,
+ "mrs": 25003,
+ "mrs": 4255,
+ "mrt": 30256,
+ "mru": 22370,
+ "mrw": 15303,
+ "ms": 3525,
+ "ms": 988,
+ "msa": 36306,
+ "msc": 31826,
+ "msc": 20529,
+ "msd": 25804,
+ "msd": 36407,
+ "msdhoni": 32850,
+ "msf": 36239,
+ "msg": 44430,
+ "msg": 10928,
+ "msh": 41751,
+ "msi": 43597,
+ "msi": 45278,
+ "msk": 38501,
+ "msl": 42736,
+ "msm": 22210,
+ "msn": 18824,
+ "msn": 41042,
+ "msnbc": 20245,
+ "mson": 27773,
+ "mson": 12298,
+ "msp": 41445,
+ "msp": 22318,
+ "mss": 42136,
+ "mss": 48610,
+ "mst": 26335,
+ "msu": 26763,
+ "msu": 17298,
+ "mswx": 42957,
+ "msy": 43919,
+ "mt": 4252,
+ "mt": 3284,
+ "mta": 28691,
+ "mtb": 48306,
+ "mtb": 18747,
+ "mtc": 42482,
+ "mtg": 49142,
+ "mtg": 13648,
+ "mth": 48151,
+ "mtl": 22135,
+ "mtn": 26041,
+ "mtn": 18953,
+ "mtr": 46650,
+ "mts": 38751,
+ "mtv": 8099,
+ "mtv": 12555,
+ "mtvbr": 47258,
+ "mtvhottest": 16751,
+ "mtvstars": 19948,
+ "mu": 670,
+ "mu": 6411,
+ "mua": 21395,
+ "muay": 44910,
+ "muaythai": 47763,
+ "mubarak": 17957,
+ "muc": 49115,
+ "much": 14300,
+ "much": 1238,
+ "mucha": 42191,
+ "muchas": 26278,
+ "mucho": 19864,
+ "muck": 44731,
+ "muck": 45330,
+ "mud": 17491,
+ "mud": 11673,
+ "mudder": 49104,
+ "muddy": 21524,
+ "mue": 44383,
+ "mue": 40717,
+ "mueller": 46863,
+ "mueller": 14719,
+ "muen": 48646,
+ "muer": 33840,
+ "muf": 33852,
+ "mufc": 9013,
+ "muffin": 22696,
+ "muffins": 25922,
+ "mufti": 44930,
+ "mug": 16339,
+ "mug": 9722,
+ "mugabe": 36441,
+ "mughal": 37508,
+ "mugs": 22852,
+ "mugshot": 40028,
+ "muh": 36335,
+ "muh": 46475,
+ "muham": 10043,
+ "muhammad": 12259,
+ "muir": 44650,
+ "muir": 24745,
+ "muj": 44635,
+ "muk": 17327,
+ "muk": 32600,
+ "mukher": 34575,
+ "mukherjee": 37862,
+ "mul": 1899,
+ "mul": 43193,
+ "mula": 40937,
+ "mulator": 17463,
+ "mulberry": 39221,
+ "mule": 28695,
+ "mull": 17313,
+ "mull": 35310,
+ "mulled": 44641,
+ "mullen": 30797,
+ "muller": 33956,
+ "mullet": 35010,
+ "mulligan": 44336,
+ "mullins": 41265,
+ "mult": 34219,
+ "multi": 3947,
+ "multi": 6400,
+ "multic": 21683,
+ "multicul": 28004,
+ "multicultural": 34667,
+ "multil": 27975,
+ "multimedia": 27977,
+ "multin": 38996,
+ "multinational": 46540,
+ "multip": 40314,
+ "multiplayer": 27460,
+ "multiple": 6470,
+ "multipurpose": 47665,
+ "multit": 27814,
+ "multitasking": 48684,
+ "mulus": 26180,
+ "mum": 15565,
+ "mum": 4030,
+ "mumb": 5850,
+ "mumbai": 24279,
+ "mumbai": 6971,
+ "mumford": 46184,
+ "mummy": 16301,
+ "mums": 17868,
+ "mun": 2617,
+ "mun": 21059,
+ "muna": 48424,
+ "munch": 23587,
+ "munch": 33299,
+ "munchies": 44324,
+ "munchkin": 41305,
+ "mund": 14244,
+ "mundo": 20990,
+ "muni": 27327,
+ "muni": 39795,
+ "munich": 13526,
+ "munici": 12159,
+ "municipal": 43667,
+ "municipal": 16600,
+ "municipality": 29987,
+ "munition": 32668,
+ "munro": 36501,
+ "munster": 27201,
+ "mup": 21966,
+ "muppet": 40598,
+ "muppets": 40187,
+ "mups": 42195,
+ "mur": 2144,
+ "mur": 18293,
+ "mura": 45176,
+ "mural": 12315,
+ "murals": 31499,
+ "murder": 28136,
+ "murder": 5787,
+ "murdered": 13158,
+ "murderer": 26956,
+ "murderers": 48472,
+ "murdering": 36055,
+ "murders": 22409,
+ "murdoch": 29037,
+ "murphy": 48976,
+ "murphy": 8914,
+ "murray": 31978,
+ "murray": 7513,
+ "murs": 38783,
+ "mus": 2198,
+ "mus": 8103,
+ "musa": 30540,
+ "musc": 5696,
+ "muscat": 33322,
+ "muscle": 27323,
+ "muscle": 9269,
+ "muscles": 16786,
+ "muscular": 30606,
+ "muse": 2369,
+ "muse": 15686,
+ "museo": 36457,
+ "muses": 48243,
+ "museu": 27087,
+ "museum": 15602,
+ "museum": 2786,
+ "museums": 15542,
+ "museumweek": 37996,
+ "mush": 7635,
+ "mushroom": 13011,
+ "mushrooms": 14730,
+ "musi": 15628,
+ "music": 4110,
+ "music": 1179,
+ "musica": 26668,
+ "musical": 36002,
+ "musical": 5173,
+ "musically": 48893,
+ "musicals": 36974,
+ "musichistory": 37890,
+ "musician": 11179,
+ "musicians": 12498,
+ "musicislife": 43311,
+ "musicmonday": 35887,
+ "musicvideo": 26764,
+ "musik": 32986,
+ "musings": 44961,
+ "musique": 42250,
+ "musk": 32143,
+ "musk": 19063,
+ "muskete": 32775,
+ "musketeers": 37993,
+ "musko": 34987,
+ "muskoka": 40832,
+ "musli": 4958,
+ "muslim": 43795,
+ "muslim": 7060,
+ "muslims": 10513,
+ "muss": 41493,
+ "mussels": 33393,
+ "must": 6783,
+ "must": 2048,
+ "mustache": 23451,
+ "mustaf": 23596,
+ "mustafa": 29000,
+ "mustang": 42361,
+ "mustang": 13309,
+ "mustangs": 22500,
+ "mustard": 15794,
+ "muster": 47361,
+ "mustread": 28978,
+ "mut": 12598,
+ "mut": 22839,
+ "mutant": 28384,
+ "mutation": 38626,
+ "mutations": 39651,
+ "mute": 31252,
+ "muted": 48028,
+ "muth": 34280,
+ "mutil": 39950,
+ "mutt": 45924,
+ "mutu": 17574,
+ "mutual": 15055,
+ "mutuals": 31158,
+ "muy": 44625,
+ "mv": 10580,
+ "mv": 8269,
+ "mvc": 40549,
+ "mvp": 8905,
+ "mw": 16725,
+ "mw": 11206,
+ "mwc": 24289,
+ "mwf": 48565,
+ "mx": 21947,
+ "mx": 9575,
+ "my": 1152,
+ "my": 607,
+ "mya": 31401,
+ "myal": 42735,
+ "myan": 13761,
+ "myanmar": 14764,
+ "myart": 38826,
+ "myco": 48362,
+ "mydayin": 41896,
+ "mydayinla": 42801,
+ "mydubai": 43475,
+ "mye": 27551,
+ "myel": 40084,
+ "myers": 15993,
+ "myjaps": 47939,
+ "myle": 43700,
+ "myles": 25511,
+ "mylife": 30537,
+ "mylittle": 37757,
+ "mylittlepony": 45107,
+ "myo": 16206,
+ "myr": 20272,
+ "myra": 35694,
+ "myri": 34972,
+ "myrt": 47785,
+ "myrtle": 27768,
+ "mys": 11724,
+ "myself": 3245,
+ "mysore": 44924,
+ "myspace": 41382,
+ "myster": 4669,
+ "mysteries": 20605,
+ "mysterious": 12650,
+ "mystery": 39828,
+ "mystery": 6711,
+ "mysti": 28711,
+ "mystic": 36264,
+ "mystic": 23722,
+ "mystical": 34122,
+ "myth": 20322,
+ "myth": 13878,
+ "mythical": 34377,
+ "mytho": 43857,
+ "mythology": 22496,
+ "myths": 18675,
+ "mz": 29509,
+ "mz": 33400,
+ "mzan": 36322,
+ "mzansi": 43301,
+ "má": 36842,
+ "mé": 21890,
+ "méxico": 46159,
+ "mü": 28142,
+ "mün": 41235,
+ "n": 77,
+ "n": 333,
+ "na": 1097,
+ "na": 1272,
+ "naa": 37738,
+ "naacp": 32176,
+ "nab": 6951,
+ "nab": 19440,
+ "nabe": 35111,
+ "naby": 24800,
+ "nac": 14557,
+ "nac": 18950,
+ "nach": 12168,
+ "nach": 43622,
+ "nacho": 35647,
+ "nachos": 32847,
+ "nacht": 37261,
+ "nacional": 38782,
+ "nad": 6204,
+ "nad": 43928,
+ "nada": 31683,
+ "nadal": 20814,
+ "nade": 24908,
+ "nadi": 30512,
+ "nadia": 27487,
+ "nadine": 23356,
+ "nadu": 20936,
+ "nae": 19374,
+ "naf": 16161,
+ "naf": 45956,
+ "nafta": 43123,
+ "nag": 6694,
+ "nag": 23902,
+ "naga": 45953,
+ "naga": 38997,
+ "nagar": 17490,
+ "nage": 41219,
+ "nago": 38349,
+ "nagoya": 43303,
+ "nagpur": 43328,
+ "nah": 26421,
+ "nah": 11129,
+ "nahi": 35244,
+ "nai": 6230,
+ "nai": 10692,
+ "naia": 31340,
+ "naidu": 42429,
+ "naija": 16326,
+ "naik": 34424,
+ "nail": 19459,
+ "nail": 9059,
+ "nailart": 43532,
+ "nailed": 19035,
+ "nails": 8469,
+ "nair": 27107,
+ "naira": 39450,
+ "naire": 48892,
+ "nairobi": 17756,
+ "nais": 46396,
+ "naissance": 44761,
+ "naive": 43362,
+ "naj": 30985,
+ "naji": 32589,
+ "nak": 9248,
+ "nak": 25550,
+ "naked": 46371,
+ "naked": 11478,
+ "naku": 39864,
+ "nal": 14132,
+ "nal": 3119,
+ "nale": 27198,
+ "nall": 32869,
+ "nally": 26158,
+ "nam": 1410,
+ "nam": 12344,
+ "nama": 39586,
+ "naman": 27635,
+ "namaste": 35549,
+ "name": 18160,
+ "name": 1981,
+ "named": 3194,
+ "nameis": 40831,
+ "nament": 3916,
+ "naments": 16540,
+ "names": 6130,
+ "namesake": 41298,
+ "nami": 20393,
+ "namibia": 23731,
+ "naming": 19367,
+ "namjoon": 31986,
+ "namm": 35524,
+ "namo": 46013,
+ "namo": 24854,
+ "nan": 4375,
+ "nan": 7750,
+ "nana": 18761,
+ "nanaimo": 40518,
+ "nancy": 21511,
+ "nancy": 11425,
+ "nand": 20435,
+ "nandez": 12764,
+ "nando": 46044,
+ "nang": 48148,
+ "nani": 27980,
+ "nanny": 31104,
+ "nano": 15835,
+ "nano": 22006,
+ "nanop": 34177,
+ "nanotechnology": 42235,
+ "nanow": 46734,
+ "nant": 22526,
+ "nantes": 47533,
+ "nantucket": 41573,
+ "nao": 39319,
+ "naom": 34955,
+ "naomi": 20173,
+ "nap": 6568,
+ "nap": 11012,
+ "napa": 20545,
+ "napier": 40875,
+ "napkin": 38930,
+ "naples": 23560,
+ "napo": 18715,
+ "napol": 20122,
+ "napoleon": 24969,
+ "napoli": 22445,
+ "napp": 11359,
+ "napping": 37657,
+ "naps": 31317,
+ "naq": 46453,
+ "nar": 2977,
+ "nar": 20145,
+ "nara": 33823,
+ "narcis": 25229,
+ "narcissi": 35442,
+ "narco": 38461,
+ "nard": 18216,
+ "nare": 34853,
+ "naren": 8468,
+ "narendr": 9807,
+ "narendra": 25848,
+ "narendramodi": 9853,
+ "narnia": 48693,
+ "narr": 11845,
+ "narrated": 43609,
+ "narrative": 15933,
+ "narratives": 35117,
+ "narrator": 46529,
+ "narrow": 24006,
+ "narrow": 16652,
+ "narrowly": 29747,
+ "naruto": 22732,
+ "nas": 3090,
+ "nas": 15250,
+ "nasa": 6841,
+ "nasal": 42853,
+ "nascar": 25723,
+ "nascar": 7868,
+ "nasdaq": 26629,
+ "nash": 6771,
+ "nash": 13620,
+ "nasheed": 49176,
+ "nashgrier": 33372,
+ "nashville": 45356,
+ "nashville": 8585,
+ "nasi": 47987,
+ "nasir": 47509,
+ "nassau": 34048,
+ "nasser": 43559,
+ "nasty": 32930,
+ "nasty": 8709,
+ "nat": 1276,
+ "nat": 11310,
+ "nata": 39392,
+ "natal": 28516,
+ "natali": 20296,
+ "natalia": 32978,
+ "natalie": 36634,
+ "natalie": 13595,
+ "natash": 48701,
+ "natasha": 23093,
+ "nate": 26643,
+ "nate": 7587,
+ "natgeo": 33009,
+ "natgeo": 25046,
+ "nath": 22203,
+ "nath": 19843,
+ "nathan": 13028,
+ "nathan": 9711,
+ "nathanfillion": 47422,
+ "nathaniel": 32667,
+ "nati": 1060,
+ "nati": 13384,
+ "natic": 44944,
+ "natin": 44358,
+ "nation": 2317,
+ "nation": 2670,
+ "national": 3126,
+ "national": 1362,
+ "nationalbestfriend": 42222,
+ "nationaldogday": 32227,
+ "nationalism": 29867,
+ "nationalist": 25058,
+ "nationality": 44451,
+ "nationally": 15130,
+ "nationalpark": 33060,
+ "nationalparks": 41204,
+ "nationals": 10784,
+ "nationaltrust": 34051,
+ "nations": 7654,
+ "nationwide": 13795,
+ "native": 20639,
+ "native": 4562,
+ "natives": 36060,
+ "nativity": 33988,
+ "natl": 39225,
+ "natl": 34465,
+ "nato": 13139,
+ "nats": 21106,
+ "natu": 2775,
+ "natur": 6800,
+ "natural": 13198,
+ "natural": 3288,
+ "naturally": 12995,
+ "naturals": 44686,
+ "nature": 9382,
+ "nature": 2625,
+ "naturelovers": 41514,
+ "naturephotography": 22533,
+ "natures": 15616,
+ "natureuk": 46193,
+ "nau": 5955,
+ "nau": 32878,
+ "naught": 41001,
+ "naughty": 47255,
+ "naughty": 15101,
+ "nautical": 31660,
+ "nav": 3413,
+ "nav": 25308,
+ "navajo": 35523,
+ "naval": 44725,
+ "naval": 13273,
+ "navar": 24848,
+ "navarro": 37104,
+ "nave": 42704,
+ "naveen": 43837,
+ "naver": 32534,
+ "navi": 16159,
+ "navi": 44848,
+ "navig": 12507,
+ "navigate": 24400,
+ "navigating": 33134,
+ "navigation": 20148,
+ "navigator": 38910,
+ "navis": 36377,
+ "navratri": 45428,
+ "navy": 28414,
+ "navy": 5598,
+ "naw": 16259,
+ "naw": 30500,
+ "nawaz": 49161,
+ "nawaz": 19523,
+ "nax": 38299,
+ "nay": 11704,
+ "nay": 16182,
+ "naya": 38917,
+ "nayanth": 38157,
+ "nayanthara": 45184,
+ "naz": 6363,
+ "naz": 35534,
+ "nazi": 12972,
+ "nazis": 21778,
+ "nb": 6459,
+ "nb": 6813,
+ "nba": 22524,
+ "nba": 5139,
+ "nbad": 43458,
+ "nbaf": 30127,
+ "nbafinals": 33803,
+ "nbap": 41956,
+ "nbaplayoffs": 43860,
+ "nbat": 46291,
+ "nbc": 9352,
+ "nbc": 8799,
+ "nbd": 24526,
+ "nbl": 42652,
+ "nc": 5021,
+ "nc": 4911,
+ "nca": 6921,
+ "ncaa": 9418,
+ "ncbd": 47221,
+ "ncc": 33195,
+ "ncc": 36686,
+ "ncds": 47573,
+ "ncfc": 31274,
+ "ncis": 33617,
+ "ncpol": 40562,
+ "ncr": 38474,
+ "ncs": 42689,
+ "nct": 27723,
+ "nct": 20319,
+ "ncwx": 36166,
+ "nd": 5625,
+ "nd": 1764,
+ "nda": 32862,
+ "ndc": 47564,
+ "ndi": 48229,
+ "ndp": 19257,
+ "nds": 31347,
+ "ndtv": 26261,
+ "ne": 557,
+ "ne": 1422,
+ "nea": 24068,
+ "neal": 33652,
+ "neal": 16730,
+ "near": 11296,
+ "near": 2252,
+ "nearby": 13314,
+ "nearest": 18985,
+ "nearing": 26571,
+ "nearly": 4816,
+ "nears": 37710,
+ "neat": 43201,
+ "neat": 15465,
+ "neath": 18315,
+ "neau": 31559,
+ "neb": 40209,
+ "nebra": 13371,
+ "nebraska": 14565,
+ "nebu": 49295,
+ "nebula": 22532,
+ "nec": 25109,
+ "nec": 22992,
+ "necess": 6961,
+ "necessarily": 25853,
+ "necessary": 8955,
+ "necessities": 43483,
+ "necessity": 33163,
+ "neck": 6066,
+ "neck": 6906,
+ "necklace": 7385,
+ "necklaces": 32276,
+ "necks": 29701,
+ "nectar": 33683,
+ "ned": 16030,
+ "ned": 1369,
+ "nederland": 49058,
+ "nee": 20494,
+ "nee": 10601,
+ "need": 3229,
+ "need": 1262,
+ "needed": 4049,
+ "needing": 22894,
+ "needle": 44490,
+ "needle": 19886,
+ "needles": 27250,
+ "needless": 39984,
+ "needs": 2536,
+ "needy": 30150,
+ "neel": 33092,
+ "neel": 46043,
+ "neer": 34245,
+ "nees": 47248,
+ "neet": 46362,
+ "neg": 5513,
+ "negan": 42623,
+ "negative": 8869,
+ "negatively": 40254,
+ "negativity": 34658,
+ "neglec": 18827,
+ "neglect": 33680,
+ "neglected": 31893,
+ "negli": 32594,
+ "negligence": 45658,
+ "negoti": 10216,
+ "negotiate": 32969,
+ "negotiating": 35510,
+ "negotiation": 36504,
+ "negotiations": 20433,
+ "negr": 42190,
+ "negro": 26554,
+ "neh": 40416,
+ "neh": 41697,
+ "neha": 44463,
+ "nehru": 30316,
+ "nei": 9366,
+ "neigh": 4061,
+ "neighb": 6534,
+ "neighbor": 7759,
+ "neighbor": 14485,
+ "neighborhood": 9471,
+ "neighborhoods": 26713,
+ "neighboring": 44754,
+ "neighbors": 13037,
+ "neighbour": 15858,
+ "neighbour": 23719,
+ "neighbourhood": 20312,
+ "neighbours": 17594,
+ "neil": 13591,
+ "neil": 8030,
+ "neilhimself": 45682,
+ "neill": 19324,
+ "neither": 14398,
+ "nek": 47727,
+ "neko": 47066,
+ "nel": 5476,
+ "nel": 2693,
+ "nell": 27081,
+ "nell": 8117,
+ "nelly": 21166,
+ "nels": 19296,
+ "nelson": 24774,
+ "nelson": 8586,
+ "nem": 45153,
+ "neman": 48553,
+ "neme": 30993,
+ "nemesis": 37811,
+ "nemo": 30441,
+ "nen": 17817,
+ "nen": 15451,
+ "nene": 44167,
+ "neo": 14562,
+ "neo": 11017,
+ "neon": 21043,
+ "neon": 13919,
+ "neonatal": 46464,
+ "neop": 49069,
+ "nep": 20739,
+ "nep": 41960,
+ "nepal": 25597,
+ "nepal": 10066,
+ "nepali": 47579,
+ "neph": 27926,
+ "nephe": 41810,
+ "nephew": 11689,
+ "nephews": 43747,
+ "nephro": 43054,
+ "neptune": 30566,
+ "ner": 2064,
+ "ner": 998,
+ "nerd": 24452,
+ "nerd": 12273,
+ "nerds": 22609,
+ "nerdy": 33124,
+ "nered": 17583,
+ "nerf": 42914,
+ "nering": 20226,
+ "nero": 29048,
+ "ners": 2129,
+ "nerve": 18571,
+ "nerves": 27813,
+ "nervous": 13928,
+ "nery": 48597,
+ "nes": 5457,
+ "nes": 4980,
+ "nesburg": 27159,
+ "nese": 32220,
+ "ness": 7187,
+ "ness": 1294,
+ "nesses": 20107,
+ "nessy": 32939,
+ "nest": 20302,
+ "nest": 8719,
+ "nesting": 28860,
+ "nestle": 43967,
+ "nestled": 38107,
+ "nests": 41133,
+ "net": 1851,
+ "net": 2315,
+ "netany": 23137,
+ "netanyahu": 23583,
+ "netball": 19761,
+ "netes": 44335,
+ "netfli": 6304,
+ "netflix": 35325,
+ "netflix": 6600,
+ "nether": 9946,
+ "netherlands": 11060,
+ "neti": 43980,
+ "netneutrality": 47794,
+ "nets": 8582,
+ "nett": 23403,
+ "nett": 6975,
+ "nette": 13271,
+ "network": 23285,
+ "network": 3304,
+ "networking": 9818,
+ "networks": 10004,
+ "neu": 3855,
+ "neu": 43342,
+ "neue": 45764,
+ "neur": 19001,
+ "neur": 31976,
+ "neural": 26388,
+ "neuro": 7401,
+ "neuro": 36000,
+ "neurological": 41718,
+ "neurology": 43197,
+ "neurons": 40442,
+ "neuroscience": 23381,
+ "neutr": 17207,
+ "neutral": 17011,
+ "neutrality": 26511,
+ "neutron": 44056,
+ "nev": 10236,
+ "nev": 43645,
+ "neva": 43304,
+ "nevada": 13499,
+ "neve": 44099,
+ "neve": 44023,
+ "never": 6746,
+ "never": 1426,
+ "neveragain": 45053,
+ "neverforget": 19242,
+ "nevergiveup": 42497,
+ "neverland": 41483,
+ "nevertheless": 48355,
+ "nevertrump": 47494,
+ "neville": 19269,
+ "nevis": 43670,
+ "new": 1218,
+ "new": 686,
+ "newark": 20240,
+ "newbie": 45427,
+ "newborn": 18320,
+ "newbury": 34169,
+ "newcastle": 41955,
+ "newcastle": 9302,
+ "newcomer": 30648,
+ "newcomers": 44037,
+ "newe": 40068,
+ "newell": 41436,
+ "newer": 33099,
+ "newest": 4990,
+ "newfound": 25250,
+ "newfoundland": 28079,
+ "newh": 18546,
+ "newin": 31911,
+ "newjersey": 32621,
+ "newly": 42186,
+ "newly": 7056,
+ "newman": 15815,
+ "newmarket": 38617,
+ "newmexico": 35238,
+ "newmusic": 32510,
+ "newmusic": 17201,
+ "newor": 25969,
+ "neworleans": 31205,
+ "newport": 42580,
+ "newport": 14846,
+ "newprofile": 14633,
+ "newprofilepic": 14754,
+ "newrelease": 34793,
+ "news": 6216,
+ "news": 1120,
+ "newsat": 43979,
+ "newsc": 28656,
+ "newscast": 45031,
+ "newsle": 10727,
+ "newsletter": 11069,
+ "newsnow": 48650,
+ "newsp": 7109,
+ "newspaper": 8786,
+ "newspapers": 22423,
+ "newsroom": 23200,
+ "newt": 37224,
+ "newton": 33122,
+ "newton": 12606,
+ "newtown": 31747,
+ "newyear": 22161,
+ "newyear": 12999,
+ "newyearseve": 37587,
+ "newyork": 18140,
+ "newyork": 10454,
+ "newyorkcity": 30460,
+ "newyorker": 39732,
+ "newzealand": 21117,
+ "nex": 6897,
+ "nex": 39720,
+ "next": 12434,
+ "next": 1131,
+ "nextgen": 41933,
+ "nexus": 19053,
+ "ney": 3857,
+ "ney": 1438,
+ "neymar": 21878,
+ "neys": 12616,
+ "nez": 27388,
+ "nf": 15195,
+ "nf": 25643,
+ "nfamily": 20098,
+ "nfc": 23695,
+ "nffc": 27893,
+ "nfl": 11219,
+ "nfl": 4691,
+ "nfldraft": 25002,
+ "ng": 10352,
+ "ng": 5215,
+ "nga": 35477,
+ "ngc": 29046,
+ "ngo": 38740,
+ "ngo": 24821,
+ "ngos": 34627,
+ "nguyen": 29947,
+ "nh": 3760,
+ "nh": 10803,
+ "nhc": 44817,
+ "nhl": 12290,
+ "nhl": 8167,
+ "nhlbruins": 39081,
+ "nhljets": 49357,
+ "nhm": 39483,
+ "nhpolitics": 36125,
+ "nhq": 42368,
+ "nhra": 30052,
+ "nhs": 23282,
+ "nhs": 7695,
+ "ni": 697,
+ "ni": 3256,
+ "nia": 3098,
+ "niag": 18071,
+ "niagar": 39298,
+ "niagara": 18965,
+ "niall": 41354,
+ "niall": 8327,
+ "niallo": 22855,
+ "niallofficial": 23084,
+ "niam": 39347,
+ "nian": 46003,
+ "nib": 31049,
+ "nic": 2109,
+ "nic": 6651,
+ "nica": 29040,
+ "nicar": 25119,
+ "nicaragua": 28423,
+ "nice": 28386,
+ "nice": 1805,
+ "nicely": 12303,
+ "nicer": 29488,
+ "nicest": 22967,
+ "niche": 25279,
+ "nichol": 7668,
+ "nicholas": 39814,
+ "nicholas": 13148,
+ "nicholls": 38846,
+ "nichols": 22730,
+ "nicholson": 28745,
+ "nick": 4209,
+ "nick": 4253,
+ "nickel": 22034,
+ "nickelo": 28668,
+ "nickelodeon": 33279,
+ "nicki": 17738,
+ "nickimin": 27390,
+ "nickiminaj": 27593,
+ "nickjonas": 43862,
+ "nickname": 24731,
+ "nicknamed": 45190,
+ "nicks": 15049,
+ "nicky": 28893,
+ "nicky": 22091,
+ "nico": 20850,
+ "nico": 17779,
+ "nicol": 9919,
+ "nicol": 48274,
+ "nicola": 21791,
+ "nicolas": 43813,
+ "nicolas": 18918,
+ "nicole": 21246,
+ "nicole": 10000,
+ "nicot": 45099,
+ "nicotine": 46697,
+ "nie": 9524,
+ "nie": 3501,
+ "niece": 12795,
+ "nieces": 44877,
+ "niel": 19109,
+ "niel": 26837,
+ "niels": 37154,
+ "nielsen": 28372,
+ "nier": 13014,
+ "nies": 10586,
+ "niest": 15007,
+ "nieu": 29781,
+ "nific": 4748,
+ "nifty": 25604,
+ "nig": 27933,
+ "nig": 28099,
+ "nigan": 48516,
+ "nigel": 33919,
+ "nigel": 15153,
+ "niger": 4524,
+ "niger": 29920,
+ "nigeri": 40913,
+ "nigeria": 6106,
+ "nigerian": 12167,
+ "nigerians": 25358,
+ "nigh": 13525,
+ "nigh": 48157,
+ "night": 3870,
+ "night": 930,
+ "nightclub": 20418,
+ "nighter": 41349,
+ "nighting": 36211,
+ "nightingale": 40696,
+ "nightlife": 28823,
+ "nightly": 28868,
+ "nightmare": 12867,
+ "nightmares": 24032,
+ "nightout": 44257,
+ "nights": 4296,
+ "nighttime": 38147,
+ "nightw": 39956,
+ "nih": 25783,
+ "nik": 5126,
+ "nik": 13705,
+ "nike": 16300,
+ "nike": 5783,
+ "nikeplus": 43154,
+ "niki": 36136,
+ "nikita": 37118,
+ "nikk": 38596,
+ "nikki": 23156,
+ "nikki": 16689,
+ "niko": 43771,
+ "nikol": 27430,
+ "nikola": 42146,
+ "nikon": 25488,
+ "nikon": 13849,
+ "nikov": 43960,
+ "nil": 16852,
+ "nil": 35030,
+ "nile": 24252,
+ "nim": 30402,
+ "nim": 42093,
+ "nima": 42586,
+ "nin": 5794,
+ "nin": 14145,
+ "nina": 13891,
+ "nine": 16213,
+ "nine": 7330,
+ "ninety": 48214,
+ "ning": 6050,
+ "ning": 762,
+ "ningham": 23395,
+ "ningly": 43537,
+ "nings": 4588,
+ "nington": 26214,
+ "ninj": 23225,
+ "ninja": 11969,
+ "ninjas": 42796,
+ "nino": 25633,
+ "ninten": 6184,
+ "nintendo": 13969,
+ "nintendo": 7886,
+ "nintendoswitch": 16404,
+ "ninth": 22770,
+ "nip": 33889,
+ "nip": 22333,
+ "nipp": 24634,
+ "nipple": 45987,
+ "nipples": 44774,
+ "nippon": 47960,
+ "nips": 49241,
+ "nir": 15503,
+ "nir": 40057,
+ "nireland": 45763,
+ "niro": 47373,
+ "nirvana": 28300,
+ "nis": 5609,
+ "nis": 3786,
+ "nish": 19834,
+ "nish": 13256,
+ "nished": 24141,
+ "nishi": 32386,
+ "nishings": 49247,
+ "nison": 45700,
+ "niss": 39043,
+ "nissan": 37635,
+ "nissan": 11082,
+ "nist": 17782,
+ "nister": 36640,
+ "nit": 4087,
+ "nit": 19011,
+ "nite": 8427,
+ "niti": 43964,
+ "niti": 45355,
+ "nitin": 37529,
+ "nitro": 30726,
+ "nitrogen": 30706,
+ "niture": 7840,
+ "nity": 12707,
+ "niu": 48187,
+ "niv": 47300,
+ "niversary": 29643,
+ "nix": 48552,
+ "nix": 32278,
+ "nixon": 20671,
+ "nj": 8343,
+ "nj": 6672,
+ "njcaa": 48992,
+ "njpw": 38992,
+ "nk": 22708,
+ "nk": 17456,
+ "nko": 36353,
+ "nl": 12057,
+ "nl": 7655,
+ "nli": 37502,
+ "nlp": 35680,
+ "nlwx": 49260,
+ "nm": 15956,
+ "nm": 11370,
+ "nmd": 43331,
+ "nme": 40454,
+ "nmwx": 47967,
+ "nn": 8947,
+ "nn": 12925,
+ "nnn": 26277,
+ "nnnn": 41420,
+ "no": 578,
+ "no": 871,
+ "noaa": 27557,
+ "noah": 28806,
+ "noah": 11519,
+ "nobel": 33742,
+ "nobel": 15605,
+ "nobelprize": 46074,
+ "noble": 29430,
+ "noble": 12051,
+ "nobody": 7009,
+ "noc": 16988,
+ "noc": 44420,
+ "nocchi": 46359,
+ "noch": 38672,
+ "noche": 29689,
+ "noches": 44166,
+ "nock": 16993,
+ "noctur": 26291,
+ "nocturnal": 41738,
+ "nod": 18648,
+ "nodapl": 39079,
+ "node": 31434,
+ "node": 24871,
+ "nodejs": 39262,
+ "nodes": 40534,
+ "noel": 38406,
+ "noel": 17496,
+ "nof": 29505,
+ "noff": 46979,
+ "nofilter": 16418,
+ "nog": 31157,
+ "noh": 40775,
+ "noi": 43115,
+ "noi": 39889,
+ "noida": 33404,
+ "noir": 39291,
+ "noir": 12953,
+ "nois": 22057,
+ "noise": 41018,
+ "noise": 9307,
+ "noises": 31575,
+ "noisse": 45686,
+ "noisy": 33495,
+ "nokia": 17731,
+ "nol": 8055,
+ "nola": 13289,
+ "nolan": 17323,
+ "nold": 40322,
+ "nole": 34654,
+ "noles": 40569,
+ "nollywood": 43145,
+ "nology": 42221,
+ "nom": 2981,
+ "nom": 12799,
+ "nomad": 27849,
+ "noman": 45592,
+ "nomin": 5643,
+ "nominate": 17122,
+ "nominated": 8710,
+ "nominating": 45747,
+ "nomination": 14136,
+ "nominations": 17124,
+ "nominee": 14122,
+ "nominees": 17873,
+ "nomnom": 26962,
+ "nomore": 35126,
+ "noms": 35706,
+ "non": 4282,
+ "non": 3353,
+ "none": 29644,
+ "none": 8906,
+ "nonetheless": 39675,
+ "nonfiction": 31654,
+ "nonprofit": 19315,
+ "nonprofits": 37935,
+ "nonsense": 19136,
+ "nonstop": 30300,
+ "nont": 25207,
+ "noo": 6759,
+ "noo": 46672,
+ "noodle": 19521,
+ "noodles": 15782,
+ "nook": 30088,
+ "noon": 37693,
+ "noon": 2347,
+ "noor": 46978,
+ "noor": 31323,
+ "nope": 15625,
+ "nor": 1062,
+ "nor": 6190,
+ "nora": 25890,
+ "norcal": 41970,
+ "nord": 19261,
+ "nord": 36067,
+ "nordic": 36439,
+ "nordic": 20734,
+ "nordstrom": 38562,
+ "norfolk": 30232,
+ "norfolk": 12202,
+ "norm": 10990,
+ "norm": 22457,
+ "norma": 35757,
+ "normal": 28748,
+ "normal": 5967,
+ "normali": 45157,
+ "normally": 15870,
+ "norman": 22027,
+ "norman": 11338,
+ "normandy": 23840,
+ "normani": 44596,
+ "norms": 33011,
+ "norris": 21814,
+ "norse": 36559,
+ "norte": 35638,
+ "north": 3468,
+ "north": 2188,
+ "northampton": 49246,
+ "northampton": 26175,
+ "northan": 37081,
+ "northbound": 24228,
+ "northcarolina": 43386,
+ "northe": 24675,
+ "northeast": 42673,
+ "northeast": 13009,
+ "northeastern": 28297,
+ "northeasthour": 42869,
+ "norther": 26908,
+ "northern": 17210,
+ "northern": 5049,
+ "northernlights": 48940,
+ "northkorea": 38495,
+ "northside": 45957,
+ "northumber": 22295,
+ "northumberland": 22922,
+ "northwales": 49371,
+ "northwest": 12894,
+ "northwestern": 23685,
+ "norton": 18032,
+ "norway": 8780,
+ "norwe": 14414,
+ "norwegian": 15971,
+ "norwich": 37629,
+ "norwich": 15812,
+ "norwood": 37889,
+ "nos": 13420,
+ "nose": 24192,
+ "nose": 8231,
+ "noses": 48163,
+ "nostal": 12076,
+ "nostalgia": 16622,
+ "nostalgic": 24468,
+ "not": 2534,
+ "not": 783,
+ "notable": 22023,
+ "notch": 19476,
+ "notdead": 42059,
+ "note": 10910,
+ "note": 3246,
+ "notebook": 16365,
+ "notebooks": 37623,
+ "noted": 22501,
+ "notes": 5795,
+ "nothin": 24291,
+ "nothing": 28412,
+ "nothing": 2586,
+ "noti": 10686,
+ "notic": 6915,
+ "notice": 6683,
+ "noticeable": 40857,
+ "noticed": 9324,
+ "notices": 33459,
+ "noticias": 47759,
+ "noticing": 37571,
+ "notification": 22512,
+ "notifications": 23169,
+ "notified": 39454,
+ "noting": 38649,
+ "notion": 37856,
+ "notjust": 33212,
+ "notjustlakes": 45803,
+ "notmy": 39301,
+ "noto": 29878,
+ "noton": 48258,
+ "notor": 21711,
+ "notori": 44065,
+ "notorious": 22489,
+ "notre": 24397,
+ "notre": 15306,
+ "notredame": 34077,
+ "notsorry": 34361,
+ "nott": 9333,
+ "nott": 34989,
+ "notte": 47308,
+ "nottingham": 12852,
+ "notts": 25598,
+ "nou": 8751,
+ "nou": 30953,
+ "noun": 33663,
+ "nouri": 23796,
+ "nourish": 46025,
+ "nourished": 48354,
+ "nous": 29485,
+ "nouveau": 29948,
+ "nouvel": 34215,
+ "nov": 2264,
+ "nov": 4293,
+ "nova": 11236,
+ "novak": 26465,
+ "novasco": 33785,
+ "novascotia": 34744,
+ "novation": 39753,
+ "nove": 30507,
+ "novel": 15044,
+ "novel": 6080,
+ "novelist": 27314,
+ "novella": 42770,
+ "novels": 16040,
+ "novelty": 37750,
+ "november": 3680,
+ "nover": 37465,
+ "novi": 47957,
+ "novice": 33743,
+ "novo": 27504,
+ "novo": 36581,
+ "now": 2040,
+ "now": 692,
+ "nowadays": 26155,
+ "nowhere": 14108,
+ "nowplaying": 3708,
+ "nowwatching": 30852,
+ "nox": 27406,
+ "noxi": 39304,
+ "noxious": 42833,
+ "noy": 32787,
+ "np": 18205,
+ "np": 6314,
+ "npa": 42378,
+ "npc": 33966,
+ "npr": 39941,
+ "npr": 24078,
+ "nps": 22025,
+ "npt": 47231,
+ "nr": 6574,
+ "nr": 9713,
+ "nra": 17286,
+ "nrc": 45786,
+ "nrf": 47982,
+ "nrg": 48662,
+ "nrl": 27142,
+ "nrl": 18127,
+ "ns": 12405,
+ "ns": 1373,
+ "nsa": 23004,
+ "nsc": 32792,
+ "nsd": 36659,
+ "nsf": 34180,
+ "nsfw": 19847,
+ "nsi": 47824,
+ "nsw": 21301,
+ "nsw": 11693,
+ "nswpol": 44434,
+ "nt": 10902,
+ "nt": 3207,
+ "ntr": 30845,
+ "nts": 43775,
+ "ntt": 22859,
+ "ntv": 24807,
+ "ntv": 45304,
+ "nu": 1156,
+ "nu": 9444,
+ "nucle": 25693,
+ "nuclear": 34136,
+ "nuclear": 7279,
+ "nude": 16630,
+ "nudes": 32122,
+ "nue": 22834,
+ "nuestra": 45649,
+ "nuestro": 38590,
+ "nuev": 47861,
+ "nueva": 48810,
+ "nuevo": 30265,
+ "nufc": 15720,
+ "nuff": 37324,
+ "nug": 13471,
+ "nugent": 47457,
+ "nugget": 25448,
+ "nuggets": 18970,
+ "nuh": 45950,
+ "nuit": 38815,
+ "nuk": 39228,
+ "nuke": 39399,
+ "nul": 29358,
+ "null": 47376,
+ "num": 17896,
+ "num": 30534,
+ "numb": 34639,
+ "numb": 39427,
+ "number": 44078,
+ "number": 2842,
+ "numbered": 25975,
+ "numbers": 6121,
+ "numer": 11442,
+ "numerous": 17082,
+ "numis": 39100,
+ "nun": 12511,
+ "nun": 28540,
+ "nunavut": 48626,
+ "nunes": 40697,
+ "nuns": 44061,
+ "nup": 46757,
+ "nur": 3920,
+ "nur": 33493,
+ "nure": 42480,
+ "nurse": 37547,
+ "nurse": 10058,
+ "nursery": 15540,
+ "nurses": 12938,
+ "nursing": 11126,
+ "nurture": 38865,
+ "nurturing": 45229,
+ "nus": 25157,
+ "nus": 18239,
+ "nut": 10358,
+ "nut": 6491,
+ "nutcracker": 36733,
+ "nutella": 27312,
+ "nutr": 6198,
+ "nutri": 15470,
+ "nutrient": 32900,
+ "nutrients": 24668,
+ "nutriti": 17978,
+ "nutrition": 41546,
+ "nutrition": 7989,
+ "nutritional": 26457,
+ "nutritious": 30387,
+ "nuts": 8644,
+ "nutshell": 26659,
+ "nutty": 39846,
+ "nv": 17217,
+ "nv": 16985,
+ "nvi": 22847,
+ "nvidia": 27325,
+ "nw": 7826,
+ "nw": 7030,
+ "nwa": 34237,
+ "nwo": 40976,
+ "nws": 23333,
+ "nws": 30998,
+ "nwsl": 48394,
+ "nwt": 25029,
+ "nx": 18810,
+ "nx": 16997,
+ "nxt": 35037,
+ "nxt": 17804,
+ "ny": 1383,
+ "ny": 1350,
+ "nya": 24165,
+ "nyc": 13304,
+ "nyc": 2832,
+ "nycc": 27187,
+ "nycfc": 47497,
+ "nye": 40723,
+ "nye": 13416,
+ "nyfw": 21089,
+ "nyk": 46841,
+ "nylon": 25915,
+ "nyo": 41534,
+ "nyo": 44586,
+ "nypd": 42293,
+ "nypd": 18279,
+ "nyr": 32538,
+ "nyrd": 47936,
+ "nys": 36375,
+ "nys": 23423,
+ "nyse": 32650,
+ "nyt": 46311,
+ "nyt": 12816,
+ "nytimes": 13772,
+ "nyu": 43143,
+ "nyu": 31355,
+ "nz": 10142,
+ "nz": 7082,
+ "o": 78,
+ "o": 334,
+ "oa": 11994,
+ "oahu": 37790,
+ "oak": 6010,
+ "oak": 7221,
+ "oakland": 42663,
+ "oakland": 12077,
+ "oakley": 27810,
+ "oaks": 16734,
+ "oakville": 38500,
+ "oasis": 18185,
+ "oat": 20095,
+ "oat": 34132,
+ "oates": 47094,
+ "oath": 20108,
+ "oatmeal": 26374,
+ "oats": 24150,
+ "oax": 43090,
+ "oaxaca": 47818,
+ "ob": 1411,
+ "ob": 14908,
+ "oba": 42902,
+ "oba": 15147,
+ "obam": 13174,
+ "obama": 4276,
+ "obamacare": 18005,
+ "obe": 11897,
+ "obe": 29117,
+ "obedience": 48921,
+ "ober": 15284,
+ "obese": 41757,
+ "obesity": 19499,
+ "obey": 26926,
+ "obi": 21454,
+ "obi": 18414,
+ "obile": 20513,
+ "obitu": 39218,
+ "obituary": 43580,
+ "objec": 7970,
+ "object": 14115,
+ "objective": 23663,
+ "objectives": 30238,
+ "objects": 13770,
+ "obl": 31452,
+ "oblast": 42672,
+ "obli": 11416,
+ "obligation": 34473,
+ "obligations": 38232,
+ "obligatory": 35020,
+ "oblivion": 45323,
+ "obo": 46001,
+ "obo": 26618,
+ "obrien": 31946,
+ "obs": 39162,
+ "obsc": 20392,
+ "obscure": 33337,
+ "obse": 8433,
+ "observ": 9050,
+ "observation": 20250,
+ "observations": 27409,
+ "observatory": 21236,
+ "observe": 23217,
+ "observed": 21267,
+ "observer": 22077,
+ "observers": 47544,
+ "observing": 28359,
+ "obsessed": 9744,
+ "obsession": 15718,
+ "obsi": 47323,
+ "obsole": 35561,
+ "obsolete": 40628,
+ "obst": 29398,
+ "obstac": 24075,
+ "obstacle": 29751,
+ "obstacles": 24480,
+ "obste": 49103,
+ "obstru": 44876,
+ "obstruc": 38762,
+ "obstruction": 40240,
+ "obtain": 26555,
+ "obtained": 29322,
+ "obvious": 13959,
+ "obviously": 10068,
+ "oc": 1566,
+ "oc": 6603,
+ "oca": 31120,
+ "ocal": 38148,
+ "occ": 43940,
+ "occa": 8530,
+ "occasion": 12280,
+ "occasional": 33059,
+ "occasionally": 32479,
+ "occasions": 26154,
+ "occer": 20804,
+ "occi": 42994,
+ "occu": 7863,
+ "occult": 42529,
+ "occup": 11152,
+ "occupation": 18624,
+ "occupational": 30644,
+ "occupied": 17271,
+ "occupy": 22453,
+ "occupy": 24210,
+ "occur": 11264,
+ "occur": 21813,
+ "occurred": 19850,
+ "occurrence": 40615,
+ "occurring": 31335,
+ "occurs": 26563,
+ "ocd": 35904,
+ "oce": 3509,
+ "ocean": 12941,
+ "ocean": 4918,
+ "oceans": 16792,
+ "och": 29334,
+ "och": 32011,
+ "oche": 33045,
+ "oci": 9891,
+ "ocity": 46039,
+ "ock": 33579,
+ "ock": 21313,
+ "ocks": 22410,
+ "oclock": 36274,
+ "oco": 32553,
+ "ocon": 33090,
+ "ocr": 45813,
+ "ocre": 40320,
+ "ocs": 27297,
+ "oct": 4565,
+ "octa": 23444,
+ "octag": 37768,
+ "octagon": 49167,
+ "octane": 43040,
+ "octavia": 47416,
+ "octo": 31032,
+ "october": 3481,
+ "octopus": 22327,
+ "ocu": 22709,
+ "oculus": 30082,
+ "od": 4886,
+ "od": 9719,
+ "oda": 24777,
+ "oday": 41954,
+ "odd": 15525,
+ "odd": 11387,
+ "oddly": 34213,
+ "odds": 11555,
+ "ode": 19125,
+ "ode": 19639,
+ "odell": 41556,
+ "odessa": 43574,
+ "odi": 12223,
+ "odi": 18853,
+ "odin": 35175,
+ "odisha": 15737,
+ "odo": 49188,
+ "odo": 40993,
+ "odor": 39509,
+ "odu": 35095,
+ "odu": 39904,
+ "odyssey": 19991,
+ "oe": 24251,
+ "oe": 11667,
+ "oec": 24288,
+ "oecd": 30816,
+ "oem": 29650,
+ "oes": 3643,
+ "of": 684,
+ "of": 539,
+ "ofa": 29774,
+ "ofc": 19877,
+ "ofe": 30000,
+ "ofer": 47322,
+ "off": 892,
+ "off": 1007,
+ "offe": 8261,
+ "offee": 34059,
+ "offen": 7231,
+ "offence": 34594,
+ "offences": 33972,
+ "offended": 30765,
+ "offender": 48294,
+ "offenders": 35878,
+ "offense": 15253,
+ "offensive": 11037,
+ "offer": 20607,
+ "offer": 3271,
+ "offered": 9395,
+ "offering": 6896,
+ "offerings": 24535,
+ "offers": 4679,
+ "offic": 3276,
+ "office": 18033,
+ "office": 2171,
+ "officeof": 38750,
+ "officeofrg": 47100,
+ "officer": 4683,
+ "officers": 6335,
+ "offices": 10933,
+ "offici": 1401,
+ "official": 5768,
+ "official": 1868,
+ "officially": 4226,
+ "officials": 7658,
+ "officiel": 26548,
+ "offl": 16851,
+ "offline": 22724,
+ "offro": 32198,
+ "offroad": 37173,
+ "offs": 23987,
+ "offseason": 25485,
+ "offset": 28843,
+ "offshore": 15496,
+ "offside": 49347,
+ "offspring": 38635,
+ "offthe": 38189,
+ "ofi": 36692,
+ "ofi": 49090,
+ "oficial": 18061,
+ "oft": 16693,
+ "oftball": 39768,
+ "often": 4864,
+ "ofthe": 7592,
+ "oftheday": 6988,
+ "oftheweek": 20654,
+ "oftheyear": 33975,
+ "og": 11542,
+ "og": 8555,
+ "oga": 47312,
+ "ogden": 42011,
+ "ogil": 39013,
+ "ography": 22399,
+ "ogue": 24761,
+ "ogun": 48970,
+ "oh": 5648,
+ "oh": 1779,
+ "ohana": 48330,
+ "ohh": 23076,
+ "ohhh": 27697,
+ "ohhhh": 40201,
+ "ohi": 5207,
+ "ohio": 18951,
+ "ohio": 6155,
+ "ohiostate": 41324,
+ "ohl": 45547,
+ "ohl": 41095,
+ "ohmy": 29758,
+ "ohn": 48043,
+ "ohs": 39542,
+ "ohwx": 47993,
+ "oi": 27357,
+ "oi": 13934,
+ "oic": 45554,
+ "oid": 14758,
+ "oids": 21847,
+ "oil": 11973,
+ "oil": 2870,
+ "oiland": 32316,
+ "oilandgas": 34130,
+ "oilers": 21627,
+ "oilpainting": 34279,
+ "oils": 17886,
+ "oily": 47550,
+ "oir": 48079,
+ "oir": 37113,
+ "ois": 23262,
+ "oit": 18453,
+ "oitnb": 34865,
+ "oj": 30986,
+ "oj": 34553,
+ "ok": 1944,
+ "ok": 2481,
+ "oka": 42258,
+ "oka": 19092,
+ "okan": 41263,
+ "okanagan": 43233,
+ "okay": 4917,
+ "okc": 42418,
+ "okc": 18357,
+ "oke": 26636,
+ "oke": 23598,
+ "oki": 20390,
+ "okin": 30687,
+ "okinawa": 35877,
+ "okla": 9431,
+ "oklahoma": 10170,
+ "oko": 26892,
+ "oko": 26095,
+ "okstate": 36356,
+ "oktoberfest": 32026,
+ "oku": 45010,
+ "oku": 43829,
+ "okwx": 27336,
+ "ol": 562,
+ "ol": 2985,
+ "ola": 20499,
+ "ola": 3373,
+ "olaf": 39709,
+ "olan": 48489,
+ "olan": 24227,
+ "oland": 26452,
+ "olas": 40800,
+ "old": 4931,
+ "old": 896,
+ "olde": 37731,
+ "older": 7700,
+ "oldest": 9285,
+ "oldham": 29929,
+ "oldie": 35280,
+ "oldies": 36278,
+ "oldman": 48614,
+ "olds": 8580,
+ "oldschool": 44384,
+ "oldschool": 25133,
+ "oldsmobile": 45396,
+ "ole": 9089,
+ "ole": 1947,
+ "oled": 46768,
+ "oler": 24069,
+ "oles": 16962,
+ "olf": 16346,
+ "olga": 34779,
+ "oli": 3811,
+ "oli": 8810,
+ "olic": 31341,
+ "oligar": 46185,
+ "olim": 47769,
+ "olin": 37823,
+ "olin": 18283,
+ "olina": 34711,
+ "oline": 17441,
+ "oling": 38033,
+ "olini": 36040,
+ "olis": 49397,
+ "olithic": 35574,
+ "olive": 22486,
+ "olive": 9898,
+ "oliver": 22882,
+ "oliver": 9261,
+ "olives": 27149,
+ "olivi": 20773,
+ "olivia": 11697,
+ "olivier": 23891,
+ "oll": 32270,
+ "oll": 15510,
+ "olla": 31908,
+ "ollie": 24434,
+ "olls": 42697,
+ "olly": 23998,
+ "olo": 14628,
+ "olo": 7606,
+ "ological": 12345,
+ "ologist": 23442,
+ "ologists": 30912,
+ "ology": 4627,
+ "olor": 29245,
+ "olph": 25077,
+ "ols": 2236,
+ "olsen": 26307,
+ "olson": 28046,
+ "olt": 46252,
+ "olu": 16502,
+ "olu": 46302,
+ "olulu": 27645,
+ "oly": 20323,
+ "oly": 24823,
+ "olym": 3594,
+ "olympi": 13597,
+ "olympia": 23965,
+ "olympiad": 47694,
+ "olympian": 25420,
+ "olympians": 44583,
+ "olympic": 26099,
+ "olympic": 6388,
+ "olympics": 7629,
+ "olympus": 30960,
+ "om": 547,
+ "om": 3932,
+ "oma": 44603,
+ "oma": 5358,
+ "omaha": 16509,
+ "oman": 22088,
+ "oman": 10871,
+ "omar": 19488,
+ "omar": 13367,
+ "omars": 37099,
+ "omas": 36023,
+ "omat": 40788,
+ "omb": 34447,
+ "ombe": 35967,
+ "omd": 49346,
+ "ome": 3693,
+ "ome": 5832,
+ "omed": 16835,
+ "omega": 13465,
+ "omelette": 38789,
+ "omen": 9969,
+ "omen": 25469,
+ "oment": 43683,
+ "omeo": 39844,
+ "omer": 24087,
+ "omer": 17902,
+ "omes": 25736,
+ "ometer": 20060,
+ "ometric": 38702,
+ "omez": 12541,
+ "omf": 47496,
+ "omfg": 12523,
+ "omg": 35233,
+ "omg": 3186,
+ "omi": 24097,
+ "omi": 10341,
+ "omic": 40536,
+ "omic": 12793,
+ "omics": 15138,
+ "omile": 46915,
+ "omin": 16457,
+ "omination": 42571,
+ "oming": 10796,
+ "ominous": 40914,
+ "omni": 18793,
+ "omni": 39489,
+ "omnibus": 44760,
+ "omnic": 48383,
+ "omo": 14478,
+ "omo": 11066,
+ "omon": 48758,
+ "omor": 29431,
+ "oms": 3770,
+ "omusic": 38965,
+ "omy": 40805,
+ "omy": 6884,
+ "on": 521,
+ "on": 525,
+ "ona": 2687,
+ "onair": 29511,
+ "onal": 918,
+ "onboard": 21689,
+ "once": 16331,
+ "once": 2654,
+ "onceupon": 28122,
+ "onceuponatime": 33505,
+ "onco": 46700,
+ "oncology": 24593,
+ "ond": 27918,
+ "ond": 2636,
+ "onda": 32643,
+ "onday": 29864,
+ "onde": 44532,
+ "ondo": 29529,
+ "ondon": 42043,
+ "ondon": 11851,
+ "one": 1980,
+ "one": 637,
+ "onec": 27746,
+ "oned": 28012,
+ "oned": 4698,
+ "onedirection": 16245,
+ "onee": 44433,
+ "oneill": 44808,
+ "onelove": 47417,
+ "onent": 12147,
+ "onents": 11709,
+ "oneof": 48478,
+ "onep": 20440,
+ "onepiece": 43153,
+ "oneplus": 25981,
+ "oner": 30055,
+ "oner": 6071,
+ "oners": 12324,
+ "ones": 20757,
+ "ones": 1575,
+ "oneself": 46874,
+ "onesie": 33237,
+ "oness": 25379,
+ "onet": 36058,
+ "oneteam": 41094,
+ "onetsy": 33392,
+ "onew": 43848,
+ "onews": 18696,
+ "onex": 49116,
+ "oney": 44498,
+ "oney": 9408,
+ "onf": 41790,
+ "onfox": 29874,
+ "ong": 2787,
+ "ong": 846,
+ "onga": 30259,
+ "ongchang": 35071,
+ "ongi": 21754,
+ "ongo": 31226,
+ "ongoing": 10393,
+ "ongs": 12143,
+ "oni": 4385,
+ "oni": 8048,
+ "onia": 8001,
+ "onial": 27599,
+ "onian": 21090,
+ "onic": 15838,
+ "onic": 3711,
+ "onica": 14631,
+ "onics": 9779,
+ "onie": 35249,
+ "onies": 22601,
+ "onimo": 41271,
+ "oning": 5197,
+ "onion": 10985,
+ "onions": 15255,
+ "onist": 10099,
+ "onists": 19659,
+ "onix": 27370,
+ "onized": 43657,
+ "onlin": 31103,
+ "online": 12940,
+ "online": 2027,
+ "onlinemarketing": 41820,
+ "onlineshopping": 38587,
+ "only": 11646,
+ "only": 1033,
+ "onlyin": 32947,
+ "onna": 25438,
+ "onna": 35458,
+ "onnaise": 48934,
+ "onne": 23466,
+ "onnell": 45613,
+ "ono": 28165,
+ "ono": 14388,
+ "onom": 48014,
+ "onomy": 36873,
+ "onpoli": 20708,
+ "ons": 26076,
+ "ons": 708,
+ "onsale": 36324,
+ "onset": 30527,
+ "onsite": 37336,
+ "onstage": 21821,
+ "onstorm": 49333,
+ "ont": 34303,
+ "ont": 11157,
+ "ontari": 6739,
+ "ontario": 42766,
+ "ontario": 7436,
+ "onte": 34723,
+ "onthe": 12241,
+ "onther": 46563,
+ "ontheroad": 47516,
+ "onthisday": 6862,
+ "onto": 11745,
+ "onto": 3141,
+ "ontology": 37364,
+ "ontour": 32155,
+ "onu": 44142,
+ "onward": 34827,
+ "onwards": 20682,
+ "ony": 9490,
+ "ony": 2926,
+ "onym": 11483,
+ "onymous": 13038,
+ "onyx": 31353,
+ "oo": 574,
+ "oo": 2822,
+ "ood": 16429,
+ "ood": 738,
+ "oodle": 45289,
+ "oods": 44660,
+ "oof": 42270,
+ "ooh": 16806,
+ "ook": 22326,
+ "ook": 8394,
+ "ooks": 31082,
+ "ool": 37702,
+ "ool": 929,
+ "oom": 22786,
+ "oom": 15002,
+ "oomf": 40607,
+ "oon": 35651,
+ "oon": 7100,
+ "ooo": 9571,
+ "oooh": 28927,
+ "oooo": 4002,
+ "oooo": 13643,
+ "ooooo": 12532,
+ "oooooo": 43590,
+ "oooooo": 20372,
+ "ooooooo": 30859,
+ "oooooooo": 15473,
+ "oooooooo": 43408,
+ "oooooooooooooooo": 48645,
+ "oop": 7326,
+ "ooper": 39906,
+ "oops": 9116,
+ "oor": 35239,
+ "oos": 9896,
+ "oosa": 30834,
+ "oose": 38941,
+ "oot": 17667,
+ "ootball": 28914,
+ "ootd": 16547,
+ "ooth": 12682,
+ "oott": 34316,
+ "ooza": 22809,
+ "op": 676,
+ "op": 3691,
+ "opa": 28949,
+ "opal": 28982,
+ "opar": 18167,
+ "opath": 33079,
+ "opathic": 37521,
+ "opathy": 28466,
+ "opau": 27239,
+ "opd": 38288,
+ "ope": 31694,
+ "ope": 11440,
+ "opec": 33138,
+ "opel": 36952,
+ "open": 3647,
+ "open": 1488,
+ "openaccess": 26591,
+ "opend": 28069,
+ "opendata": 35709,
+ "openday": 46991,
+ "opened": 5303,
+ "opener": 8998,
+ "openhouse": 36091,
+ "opening": 33728,
+ "opening": 2516,
+ "openingday": 36359,
+ "openings": 27643,
+ "openly": 23005,
+ "opens": 4801,
+ "opensource": 29930,
+ "oper": 2796,
+ "oper": 37533,
+ "opera": 8056,
+ "operate": 19306,
+ "operated": 23031,
+ "operates": 38675,
+ "operating": 12218,
+ "operation": 27173,
+ "operation": 7639,
+ "operational": 18237,
+ "operations": 8106,
+ "operative": 28380,
+ "operator": 15972,
+ "operators": 19267,
+ "opers": 48728,
+ "opes": 37258,
+ "oph": 6796,
+ "opha": 38634,
+ "ophel": 45017,
+ "ophelia": 49118,
+ "ophi": 44547,
+ "ophile": 35915,
+ "opho": 12900,
+ "ophobia": 21111,
+ "ophobic": 29934,
+ "ophon": 25120,
+ "ophone": 26345,
+ "ophthal": 33135,
+ "ophy": 28539,
+ "opi": 40056,
+ "opi": 48994,
+ "opin": 7636,
+ "opini": 14825,
+ "opinion": 7843,
+ "opinions": 16192,
+ "opio": 17371,
+ "opioid": 22833,
+ "opioids": 47578,
+ "opla": 36270,
+ "ople": 25663,
+ "opol": 15173,
+ "opoly": 23729,
+ "opor": 39650,
+ "opoulos": 42020,
+ "opp": 2020,
+ "opp": 21024,
+ "oppa": 23637,
+ "oppo": 7399,
+ "oppo": 41770,
+ "opponent": 17002,
+ "opponents": 19664,
+ "oppor": 2914,
+ "opportun": 2939,
+ "opportunities": 5978,
+ "opportunity": 4004,
+ "oppos": 10091,
+ "oppose": 23617,
+ "opposed": 22509,
+ "opposes": 47471,
+ "opposing": 24376,
+ "opposite": 12872,
+ "opposition": 11062,
+ "oppre": 17341,
+ "oppressed": 41492,
+ "oppression": 30650,
+ "opra": 28291,
+ "oprah": 22562,
+ "opry": 35340,
+ "ops": 3054,
+ "opt": 45103,
+ "opt": 27188,
+ "opted": 42035,
+ "opti": 6580,
+ "optic": 25190,
+ "optic": 24755,
+ "optical": 16822,
+ "optics": 27165,
+ "optim": 22331,
+ "optimal": 25235,
+ "optimi": 9737,
+ "optimis": 39459,
+ "optimism": 25226,
+ "optimist": 44581,
+ "optimistic": 23104,
+ "optimization": 25125,
+ "optimize": 30456,
+ "optimized": 43939,
+ "optimizing": 49157,
+ "optimum": 35974,
+ "optimus": 43453,
+ "option": 8464,
+ "optional": 25411,
+ "options": 7063,
+ "optome": 35533,
+ "opul": 39858,
+ "opus": 33295,
+ "opy": 21835,
+ "or": 523,
+ "or": 541,
+ "ora": 4301,
+ "orac": 24673,
+ "oracle": 37308,
+ "oracle": 15966,
+ "orah": 40820,
+ "orail": 45120,
+ "oral": 32490,
+ "oral": 6007,
+ "orama": 33619,
+ "oran": 32209,
+ "oran": 28395,
+ "orang": 22116,
+ "orange": 13957,
+ "orange": 4287,
+ "oranges": 32417,
+ "orangu": 36112,
+ "orb": 28894,
+ "orb": 36958,
+ "orbit": 19713,
+ "orbital": 40312,
+ "orc": 44305,
+ "orca": 18631,
+ "orcas": 47676,
+ "orch": 11893,
+ "orchar": 40226,
+ "orchard": 19530,
+ "orche": 8004,
+ "orchestr": 42937,
+ "orchestra": 9573,
+ "orchestral": 40285,
+ "orchi": 23696,
+ "orchid": 18678,
+ "orchids": 28376,
+ "ord": 26903,
+ "ord": 11502,
+ "orda": 33462,
+ "ordained": 38302,
+ "order": 24613,
+ "order": 2191,
+ "ordered": 8335,
+ "ordering": 19588,
+ "orderly": 43457,
+ "orders": 6187,
+ "ordin": 4378,
+ "ordinance": 38583,
+ "ordinary": 8012,
+ "ore": 3580,
+ "ore": 1423,
+ "orean": 36696,
+ "ored": 5133,
+ "oregon": 21759,
+ "oregon": 8035,
+ "oren": 21645,
+ "oreo": 21873,
+ "oreos": 41688,
+ "ores": 17328,
+ "org": 3401,
+ "org": 5593,
+ "organ": 3338,
+ "organ": 13213,
+ "organi": 3636,
+ "organic": 24080,
+ "organic": 5980,
+ "organics": 44199,
+ "organis": 13204,
+ "organisation": 15868,
+ "organisations": 20651,
+ "organise": 36073,
+ "organised": 13191,
+ "organiser": 49141,
+ "organisers": 35778,
+ "organising": 22787,
+ "organisms": 37041,
+ "organiz": 11107,
+ "organization": 8064,
+ "organizational": 29510,
+ "organizations": 13453,
+ "organize": 19973,
+ "organized": 10681,
+ "organizer": 23905,
+ "organizers": 27191,
+ "organizing": 15779,
+ "organs": 29872,
+ "orgs": 29500,
+ "ori": 1540,
+ "ori": 8693,
+ "oria": 11474,
+ "orial": 8648,
+ "orian": 21193,
+ "oric": 43810,
+ "orice": 41341,
+ "orie": 18815,
+ "orient": 13149,
+ "orient": 30770,
+ "oriental": 23056,
+ "orientation": 16873,
+ "oriente": 40390,
+ "oriented": 24596,
+ "orienteering": 42985,
+ "ories": 5934,
+ "orig": 2273,
+ "orig": 38463,
+ "origami": 31832,
+ "origin": 2555,
+ "origin": 12372,
+ "original": 18496,
+ "original": 3117,
+ "originally": 12849,
+ "originals": 16953,
+ "originated": 41823,
+ "origins": 16291,
+ "orin": 39863,
+ "oring": 3006,
+ "orio": 24308,
+ "orioles": 21430,
+ "orion": 21765,
+ "oris": 37064,
+ "orities": 7903,
+ "ority": 5556,
+ "orium": 12015,
+ "ork": 22202,
+ "ork": 37235,
+ "orkney": 34254,
+ "orl": 39465,
+ "orlando": 32247,
+ "orlando": 7827,
+ "orleans": 11127,
+ "orm": 38464,
+ "orn": 25412,
+ "orn": 8130,
+ "ornam": 36122,
+ "ornament": 23409,
+ "ornamental": 46270,
+ "ornaments": 28968,
+ "ornate": 46865,
+ "orni": 27713,
+ "ornithology": 38275,
+ "orns": 19340,
+ "oro": 9848,
+ "oro": 14573,
+ "orous": 19286,
+ "orph": 17318,
+ "orphan": 22718,
+ "orphan": 28994,
+ "orphanage": 45196,
+ "orphaned": 46792,
+ "orphans": 36588,
+ "orphe": 39186,
+ "orr": 32977,
+ "ors": 1127,
+ "orship": 20846,
+ "ort": 1019,
+ "ortega": 39727,
+ "orth": 22584,
+ "orth": 24461,
+ "ortho": 11366,
+ "orthodon": 37730,
+ "orthodox": 19008,
+ "orthop": 42123,
+ "orthopedic": 49341,
+ "ortiz": 23544,
+ "orton": 37238,
+ "oru": 44629,
+ "oru": 31281,
+ "orum": 42724,
+ "orwell": 41218,
+ "ory": 16983,
+ "ory": 1985,
+ "os": 2211,
+ "os": 1299,
+ "osa": 16340,
+ "osa": 17237,
+ "osaka": 21347,
+ "osborne": 22402,
+ "osbourne": 43376,
+ "osc": 5092,
+ "oscar": 21157,
+ "oscar": 8191,
+ "oscars": 11098,
+ "osce": 37303,
+ "oscill": 38272,
+ "ose": 46942,
+ "ose": 22541,
+ "osh": 30717,
+ "osh": 35011,
+ "osha": 33907,
+ "oshi": 34770,
+ "osi": 25247,
+ "osi": 17636,
+ "osis": 13903,
+ "osity": 12730,
+ "oslo": 20547,
+ "osm": 31626,
+ "osman": 46539,
+ "oso": 42793,
+ "oso": 21285,
+ "osp": 24387,
+ "ospre": 49001,
+ "osprey": 37893,
+ "oss": 29362,
+ "oss": 34640,
+ "ost": 23701,
+ "ost": 18749,
+ "oste": 20632,
+ "osteo": 43163,
+ "oster": 31781,
+ "ostr": 33673,
+ "ostrich": 47640,
+ "osu": 29480,
+ "osu": 19818,
+ "oswald": 38471,
+ "ot": 1863,
+ "ot": 2062,
+ "ota": 17509,
+ "ota": 8741,
+ "otago": 45919,
+ "otaku": 40743,
+ "otas": 47616,
+ "otc": 37934,
+ "otd": 5683,
+ "ote": 28511,
+ "ote": 19744,
+ "otes": 27280,
+ "oth": 33262,
+ "oth": 33519,
+ "other": 9758,
+ "other": 1010,
+ "others": 3326,
+ "otherwise": 12376,
+ "oti": 19567,
+ "oti": 45564,
+ "otic": 9671,
+ "otis": 28246,
+ "otive": 10877,
+ "oto": 23946,
+ "oto": 23399,
+ "otp": 29822,
+ "otr": 38685,
+ "ots": 5769,
+ "ott": 10167,
+ "ott": 7936,
+ "otta": 7623,
+ "otta": 20941,
+ "ottawa": 49027,
+ "ottawa": 9019,
+ "otte": 35214,
+ "otter": 34710,
+ "otter": 22456,
+ "otters": 38883,
+ "otti": 36721,
+ "ottnews": 33995,
+ "otto": 17730,
+ "ottoman": 27503,
+ "otw": 35259,
+ "otwol": 46868,
+ "ou": 520,
+ "ou": 6544,
+ "ouat": 32954,
+ "ouch": 13493,
+ "oud": 1359,
+ "oue": 48838,
+ "ouf": 34618,
+ "ough": 4204,
+ "ough": 991,
+ "ought": 2253,
+ "oughton": 36860,
+ "oui": 39421,
+ "ouk": 21796,
+ "oul": 20253,
+ "oul": 8081,
+ "ould": 859,
+ "oulos": 32808,
+ "oun": 636,
+ "oun": 20960,
+ "ounce": 15027,
+ "ounces": 30299,
+ "ound": 2013,
+ "ound": 853,
+ "oundation": 40132,
+ "ounded": 9634,
+ "ounding": 11944,
+ "ounds": 2753,
+ "oung": 35875,
+ "oung": 25341,
+ "ounge": 29427,
+ "ount": 43801,
+ "ount": 4172,
+ "ounts": 10963,
+ "oup": 32815,
+ "our": 727,
+ "our": 581,
+ "oura": 29806,
+ "oura": 36352,
+ "ourable": 24126,
+ "ourage": 34525,
+ "oural": 45840,
+ "oured": 6956,
+ "ouri": 12696,
+ "ouring": 12000,
+ "ourism": 25496,
+ "ourke": 26480,
+ "ourlives": 37541,
+ "ouro": 41224,
+ "ours": 1491,
+ "ourse": 15415,
+ "ourselves": 10124,
+ "ourt": 22960,
+ "oury": 29484,
+ "ous": 1987,
+ "ous": 879,
+ "ouse": 32048,
+ "ouse": 7603,
+ "ouses": 33666,
+ "ously": 2501,
+ "ousness": 10689,
+ "ousy": 28302,
+ "out": 1130,
+ "out": 620,
+ "outa": 35187,
+ "outage": 27320,
+ "outages": 40353,
+ "outback": 28532,
+ "outbound": 41256,
+ "outbreak": 20103,
+ "outcome": 16552,
+ "outcomes": 14016,
+ "outdated": 38313,
+ "outdoor": 19184,
+ "outdoor": 6368,
+ "outdoors": 10469,
+ "oute": 44180,
+ "outed": 34435,
+ "outer": 30499,
+ "outer": 14188,
+ "outes": 39600,
+ "outfield": 41826,
+ "outfit": 6525,
+ "outfits": 16366,
+ "outfitters": 37725,
+ "outfy": 34920,
+ "outgoing": 27302,
+ "outh": 16933,
+ "outh": 8111,
+ "outine": 35452,
+ "outing": 11251,
+ "outlander": 45820,
+ "outlander": 17095,
+ "outlaw": 37498,
+ "outlaw": 27340,
+ "outlaws": 30935,
+ "outlet": 16855,
+ "outlets": 20822,
+ "outline": 26894,
+ "outlines": 29159,
+ "outlining": 45960,
+ "outlook": 12983,
+ "outof": 43958,
+ "outpatient": 46603,
+ "outpost": 44622,
+ "output": 17255,
+ "outra": 14262,
+ "outrage": 23577,
+ "outraged": 43402,
+ "outrageous": 29342,
+ "outre": 14373,
+ "outreach": 15297,
+ "outright": 38200,
+ "outs": 5790,
+ "outsi": 22515,
+ "outside": 47693,
+ "outside": 2782,
+ "outsider": 41196,
+ "outsiders": 41742,
+ "outskirts": 42088,
+ "outsourcing": 34543,
+ "outstanding": 6387,
+ "outta": 15807,
+ "outtuesday": 48692,
+ "outw": 34650,
+ "oux": 40960,
+ "oux": 14228,
+ "ov": 6420,
+ "ov": 8479,
+ "ova": 12762,
+ "oval": 15039,
+ "ovarian": 42913,
+ "ovation": 24333,
+ "ove": 8649,
+ "ove": 15456,
+ "oven": 44620,
+ "oven": 12579,
+ "over": 1658,
+ "over": 962,
+ "overall": 6914,
+ "overboard": 42982,
+ "overcame": 47235,
+ "overcast": 36942,
+ "overcome": 14365,
+ "overcoming": 29348,
+ "overdose": 27017,
+ "overdrive": 40088,
+ "overdue": 30240,
+ "overflow": 32885,
+ "overflowing": 45370,
+ "overhaul": 31531,
+ "overhead": 20321,
+ "overland": 38808,
+ "overlay": 44827,
+ "overload": 24327,
+ "overlook": 35767,
+ "overlooked": 27632,
+ "overlooking": 17319,
+ "overly": 28820,
+ "overnight": 9913,
+ "overpass": 44310,
+ "overrated": 38214,
+ "overs": 45774,
+ "overs": 17329,
+ "overseas": 15100,
+ "oversight": 32494,
+ "oversized": 31557,
+ "overtime": 19347,
+ "overturned": 31048,
+ "overview": 14789,
+ "overwatch": 18124,
+ "overweight": 43465,
+ "overwhel": 12204,
+ "overwhelmed": 23459,
+ "overwhelming": 20306,
+ "overwhelmingly": 43549,
+ "ovi": 32508,
+ "ovic": 22417,
+ "ovich": 27623,
+ "ovie": 47677,
+ "ovo": 41920,
+ "ovo": 18065,
+ "ovski": 26167,
+ "ow": 2032,
+ "ow": 2250,
+ "owa": 32770,
+ "owe": 19073,
+ "owed": 37641,
+ "owen": 24838,
+ "owen": 12056,
+ "owens": 20664,
+ "owes": 35069,
+ "owing": 48582,
+ "owl": 34332,
+ "owl": 9899,
+ "owls": 18247,
+ "own": 3845,
+ "own": 1758,
+ "owned": 8536,
+ "owner": 5019,
+ "owners": 7712,
+ "ownership": 16583,
+ "owning": 24661,
+ "owns": 17533,
+ "owo": 46142,
+ "ows": 27423,
+ "owski": 22573,
+ "ox": 3282,
+ "ox": 12071,
+ "oxfam": 45466,
+ "oxford": 28588,
+ "oxford": 8824,
+ "oxfordshire": 37855,
+ "oxi": 33731,
+ "oxi": 48147,
+ "oxid": 17701,
+ "oxide": 28235,
+ "oxo": 37088,
+ "oxy": 12432,
+ "oxygen": 16214,
+ "oy": 6638,
+ "oy": 12437,
+ "oya": 38894,
+ "oye": 48677,
+ "oyster": 40545,
+ "oyster": 17253,
+ "oysters": 22672,
+ "oz": 10584,
+ "oz": 6044,
+ "ozar": 31848,
+ "ozil": 41365,
+ "ozone": 37052,
+ "ozzy": 39549,
+ "p": 79,
+ "p": 335,
+ "pa": 765,
+ "pa": 2217,
+ "paa": 32812,
+ "pab": 9354,
+ "pablo": 42172,
+ "pablo": 14473,
+ "pac": 2332,
+ "pac": 7608,
+ "pace": 40600,
+ "pace": 9450,
+ "paced": 32611,
+ "pacers": 23976,
+ "paces": 43001,
+ "paci": 5699,
+ "pacific": 19723,
+ "pacific": 6654,
+ "pacing": 45202,
+ "pack": 2711,
+ "pack": 3420,
+ "package": 7053,
+ "packaged": 29656,
+ "packages": 14305,
+ "packaging": 11658,
+ "packard": 46421,
+ "packed": 5883,
+ "packer": 28209,
+ "packers": 14294,
+ "packet": 25022,
+ "packets": 40448,
+ "packing": 9829,
+ "packs": 11086,
+ "paco": 41364,
+ "pacqui": 28456,
+ "pacquiao": 30485,
+ "pact": 27182,
+ "pad": 3798,
+ "pad": 7601,
+ "padded": 42253,
+ "paddington": 33162,
+ "paddle": 38276,
+ "paddle": 20811,
+ "paddling": 40645,
+ "paddock": 29590,
+ "paddy": 33103,
+ "paddy": 19855,
+ "padi": 47037,
+ "padilla": 22380,
+ "padma": 44595,
+ "padma": 46457,
+ "padre": 38343,
+ "padres": 22829,
+ "pads": 17353,
+ "paedi": 41488,
+ "paella": 46924,
+ "paf": 47185,
+ "pafc": 49259,
+ "pag": 4151,
+ "pag": 30525,
+ "pagan": 27854,
+ "page": 14996,
+ "page": 2504,
+ "pageant": 22139,
+ "pages": 8082,
+ "pagoda": 44309,
+ "pah": 41054,
+ "pah": 26884,
+ "pai": 20624,
+ "pai": 21198,
+ "paid": 5057,
+ "paige": 33659,
+ "paige": 16022,
+ "paign": 31796,
+ "pain": 2141,
+ "pain": 4495,
+ "paine": 38069,
+ "painful": 16361,
+ "pains": 25639,
+ "paint": 7948,
+ "paint": 5185,
+ "paintball": 39730,
+ "painted": 6433,
+ "painter": 10888,
+ "painters": 35703,
+ "painting": 49164,
+ "painting": 3086,
+ "paintings": 9956,
+ "paints": 21672,
+ "pair": 19848,
+ "pair": 4038,
+ "paired": 12433,
+ "pairing": 16313,
+ "pairings": 41152,
+ "pairs": 9950,
+ "pais": 16878,
+ "paisley": 22954,
+ "pajam": 24110,
+ "pajama": 40244,
+ "pajamas": 37231,
+ "pak": 13186,
+ "pak": 9094,
+ "paki": 3438,
+ "pakistan": 10713,
+ "pakistan": 3994,
+ "pakistani": 14050,
+ "pakistanis": 45707,
+ "pakv": 38196,
+ "pal": 1850,
+ "pal": 3611,
+ "pala": 17895,
+ "palace": 6381,
+ "palaces": 45625,
+ "palad": 28371,
+ "palae": 43379,
+ "palais": 35673,
+ "palate": 34666,
+ "palawan": 48202,
+ "palazzo": 36006,
+ "pale": 4768,
+ "pale": 12518,
+ "paleo": 36741,
+ "paleo": 22198,
+ "paler": 38028,
+ "palermo": 40635,
+ "palestin": 9449,
+ "palestine": 11682,
+ "palestinian": 11764,
+ "palestinians": 21874,
+ "palette": 13901,
+ "pali": 48063,
+ "palin": 40153,
+ "palis": 44256,
+ "pality": 27296,
+ "pall": 35817,
+ "palla": 21208,
+ "palladium": 37888,
+ "pallet": 39057,
+ "palli": 28954,
+ "palliative": 46014,
+ "pally": 46073,
+ "palm": 19651,
+ "palm": 8612,
+ "palma": 29888,
+ "palmer": 40112,
+ "palmer": 13633,
+ "palms": 27059,
+ "palo": 31562,
+ "palom": 47698,
+ "palooza": 25861,
+ "pals": 11043,
+ "palsy": 46651,
+ "pam": 8228,
+ "pam": 18513,
+ "pamela": 26991,
+ "pamp": 37653,
+ "pamper": 44345,
+ "pamph": 41332,
+ "pan": 1072,
+ "pan": 7437,
+ "panam": 24606,
+ "panama": 15522,
+ "panas": 26207,
+ "panasonic": 29750,
+ "pancake": 18723,
+ "pancakes": 15308,
+ "panch": 27251,
+ "pancra": 42472,
+ "pancre": 27708,
+ "pancreatic": 49337,
+ "pancy": 41625,
+ "pand": 5631,
+ "panda": 12952,
+ "pandas": 35119,
+ "pande": 38419,
+ "pandey": 34895,
+ "pandit": 41191,
+ "pandor": 30250,
+ "pandora": 17727,
+ "pandoramusic": 42344,
+ "pane": 27470,
+ "panel": 3724,
+ "paneli": 19410,
+ "panelist": 39719,
+ "panelists": 24619,
+ "panels": 12735,
+ "panera": 48471,
+ "pang": 16756,
+ "pang": 23672,
+ "panhandle": 40919,
+ "pani": 36092,
+ "panic": 46671,
+ "panic": 14124,
+ "panini": 30410,
+ "pann": 42302,
+ "panna": 49065,
+ "pano": 36165,
+ "panor": 12962,
+ "panorama": 19763,
+ "panoramic": 22563,
+ "pans": 35204,
+ "pant": 22550,
+ "panther": 22825,
+ "panther": 13262,
+ "panthers": 10494,
+ "panties": 32515,
+ "panto": 28776,
+ "pantry": 25608,
+ "pants": 5003,
+ "panty": 44217,
+ "pany": 45567,
+ "panzer": 41159,
+ "pao": 33790,
+ "paola": 44689,
+ "paolo": 48488,
+ "paolo": 21133,
+ "pap": 1884,
+ "pap": 30756,
+ "papa": 12211,
+ "papar": 32782,
+ "paparazzi": 37842,
+ "papaya": 44098,
+ "paper": 8680,
+ "paper": 2802,
+ "paperback": 17928,
+ "papers": 8204,
+ "paperwork": 35785,
+ "papi": 35177,
+ "papp": 26361,
+ "paprika": 44793,
+ "papua": 32629,
+ "par": 699,
+ "par": 9163,
+ "para": 18355,
+ "para": 8976,
+ "parach": 23147,
+ "parachute": 30122,
+ "parad": 37143,
+ "parade": 5809,
+ "parades": 46479,
+ "paradi": 6658,
+ "paradig": 27786,
+ "paradigm": 33485,
+ "paradise": 45869,
+ "paradise": 7247,
+ "paradox": 33109,
+ "parag": 11866,
+ "paragon": 48099,
+ "paragra": 24903,
+ "paragraph": 28499,
+ "paragu": 38021,
+ "paraguay": 43579,
+ "paral": 15143,
+ "paralle": 13184,
+ "parallel": 18201,
+ "paralleled": 42520,
+ "parallels": 46101,
+ "paraly": 30255,
+ "paralym": 18727,
+ "paralympic": 30806,
+ "paralympics": 37162,
+ "paralysis": 45702,
+ "param": 12250,
+ "parame": 27106,
+ "paramedic": 34630,
+ "paramedics": 35991,
+ "parameters": 44890,
+ "paramore": 34401,
+ "paramount": 26642,
+ "parano": 30283,
+ "paranoid": 43029,
+ "paranor": 16940,
+ "paranormal": 19047,
+ "parap": 41091,
+ "paras": 15198,
+ "parasite": 42460,
+ "parasites": 46175,
+ "parc": 30914,
+ "parcel": 30367,
+ "parcels": 45589,
+ "pard": 18773,
+ "pardon": 47606,
+ "pardon": 26565,
+ "pare": 18202,
+ "pared": 5498,
+ "paren": 3106,
+ "parent": 47848,
+ "parent": 10183,
+ "parental": 28339,
+ "parenthood": 23887,
+ "parenting": 14529,
+ "parents": 3731,
+ "pares": 12420,
+ "parfait": 46140,
+ "pari": 17961,
+ "pari": 27979,
+ "paris": 13982,
+ "paris": 3445,
+ "parisagreement": 47405,
+ "parish": 47328,
+ "parish": 13020,
+ "parisi": 45081,
+ "parisian": 38512,
+ "parity": 42734,
+ "park": 4985,
+ "park": 1452,
+ "parked": 16487,
+ "parker": 31119,
+ "parker": 8365,
+ "parkin": 34868,
+ "parking": 5984,
+ "parkinson": 28129,
+ "parkland": 31287,
+ "parkrun": 25747,
+ "parks": 6873,
+ "parkway": 19882,
+ "parl": 30373,
+ "parl": 29897,
+ "parliam": 5941,
+ "parliament": 41599,
+ "parliament": 7151,
+ "parliamentary": 17912,
+ "parlor": 38253,
+ "parlour": 37829,
+ "parma": 36077,
+ "parme": 26295,
+ "parmesan": 27274,
+ "paro": 17429,
+ "parody": 24318,
+ "parole": 32158,
+ "parr": 44113,
+ "parrish": 43043,
+ "parrot": 23565,
+ "parry": 40604,
+ "parsley": 30077,
+ "parsons": 22505,
+ "part": 1872,
+ "part": 1551,
+ "parte": 48508,
+ "parth": 34790,
+ "parti": 10509,
+ "partial": 18957,
+ "partially": 21269,
+ "partic": 2871,
+ "partici": 9540,
+ "particip": 4400,
+ "participant": 27674,
+ "participants": 10237,
+ "participate": 9433,
+ "participated": 14252,
+ "participates": 46414,
+ "participating": 11535,
+ "participation": 13529,
+ "particle": 27716,
+ "particles": 27012,
+ "particul": 11408,
+ "particular": 14098,
+ "particularly": 12170,
+ "parties": 9032,
+ "parting": 32844,
+ "partisan": 20772,
+ "partist": 44713,
+ "partition": 42219,
+ "partly": 21459,
+ "partner": 5210,
+ "partner": 4568,
+ "partnered": 21402,
+ "partnering": 21182,
+ "partners": 5568,
+ "partnership": 6123,
+ "partnerships": 17418,
+ "parton": 43245,
+ "partridge": 34872,
+ "parts": 5149,
+ "party": 12877,
+ "party": 1580,
+ "partying": 25702,
+ "pas": 1341,
+ "pas": 9525,
+ "pasadena": 25892,
+ "pascal": 28626,
+ "pasco": 49220,
+ "pascu": 42692,
+ "pash": 23936,
+ "pasha": 46986,
+ "paso": 18542,
+ "pasqu": 44941,
+ "pass": 5016,
+ "pass": 3511,
+ "passage": 16477,
+ "passages": 48937,
+ "passed": 4957,
+ "passenger": 12311,
+ "passengers": 12781,
+ "passer": 48544,
+ "passes": 7633,
+ "passi": 32471,
+ "passing": 6589,
+ "passion": 8822,
+ "passion": 5332,
+ "passionate": 10947,
+ "passionately": 44028,
+ "passions": 38441,
+ "passive": 23171,
+ "passover": 38426,
+ "passport": 14739,
+ "passports": 46368,
+ "password": 20258,
+ "passwords": 43095,
+ "past": 7315,
+ "past": 2729,
+ "pasta": 10441,
+ "paste": 34765,
+ "paste": 17038,
+ "pastel": 19457,
+ "pastels": 45699,
+ "pastor": 19792,
+ "pastor": 9664,
+ "pastoral": 37191,
+ "pastors": 30959,
+ "pastr": 45478,
+ "pastries": 39409,
+ "pastry": 18582,
+ "pasture": 34764,
+ "pastures": 47793,
+ "pat": 1300,
+ "pat": 7036,
+ "patag": 29862,
+ "patagonia": 32786,
+ "patch": 29284,
+ "patch": 8721,
+ "patches": 22104,
+ "patchwork": 44675,
+ "patchy": 47488,
+ "pate": 42122,
+ "pate": 42098,
+ "patel": 14168,
+ "patent": 14692,
+ "patented": 37277,
+ "patents": 33911,
+ "paterson": 36560,
+ "path": 7408,
+ "path": 5035,
+ "pathetic": 18222,
+ "pathfinder": 35415,
+ "pathi": 34976,
+ "pathi": 27347,
+ "pathic": 49025,
+ "patho": 18534,
+ "pathology": 23290,
+ "paths": 16333,
+ "pathway": 23488,
+ "pathways": 24690,
+ "pathy": 13330,
+ "pati": 2799,
+ "pati": 26708,
+ "patience": 13575,
+ "patient": 30139,
+ "patient": 6262,
+ "patiently": 22980,
+ "patients": 5543,
+ "patil": 49187,
+ "patio": 14304,
+ "pational": 30627,
+ "patna": 45025,
+ "patory": 41859,
+ "patreon": 17165,
+ "patri": 4771,
+ "patriarch": 49054,
+ "patriarchy": 48806,
+ "patric": 12569,
+ "patrice": 40731,
+ "patricia": 18143,
+ "patrick": 12078,
+ "patrick": 5286,
+ "patricks": 46783,
+ "patriot": 28896,
+ "patriot": 15692,
+ "patrioti": 35520,
+ "patriotic": 20217,
+ "patriotism": 35807,
+ "patriots": 8707,
+ "patro": 31650,
+ "patrol": 10073,
+ "patrolling": 39344,
+ "patrols": 35978,
+ "patron": 26658,
+ "patron": 17683,
+ "patrons": 28308,
+ "pats": 24874,
+ "patsy": 46093,
+ "patt": 12637,
+ "patter": 4982,
+ "pattern": 7447,
+ "patterned": 47212,
+ "patterns": 11637,
+ "patterson": 21384,
+ "patti": 44927,
+ "patti": 26123,
+ "pattinson": 32474,
+ "patton": 29026,
+ "patty": 48741,
+ "patty": 18321,
+ "pau": 1834,
+ "pau": 35970,
+ "paul": 6035,
+ "paul": 2597,
+ "paula": 37363,
+ "paula": 16777,
+ "pauline": 30438,
+ "paulo": 48002,
+ "paulo": 21628,
+ "pauls": 41413,
+ "pauls": 40010,
+ "paulson": 48201,
+ "pause": 19439,
+ "paused": 46782,
+ "pav": 6661,
+ "pave": 37107,
+ "paved": 27898,
+ "pavel": 43152,
+ "pavement": 27669,
+ "pavilion": 13374,
+ "paving": 28651,
+ "paw": 14009,
+ "paw": 16016,
+ "pawan": 29754,
+ "pawankalyan": 33702,
+ "pawn": 43195,
+ "paws": 16714,
+ "pax": 20007,
+ "pax": 19033,
+ "paxton": 38347,
+ "pay": 2642,
+ "pay": 3345,
+ "payback": 36413,
+ "paycheck": 45078,
+ "payday": 26957,
+ "payee": 46985,
+ "payer": 41503,
+ "paying": 8341,
+ "payment": 10596,
+ "payments": 11832,
+ "payne": 12775,
+ "paypal": 21442,
+ "payroll": 31610,
+ "pays": 10845,
+ "paysoff": 48174,
+ "paytm": 45352,
+ "payton": 27348,
+ "paz": 22267,
+ "pb": 20112,
+ "pb": 10981,
+ "pba": 28205,
+ "pbb": 48567,
+ "pbb": 40589,
+ "pbc": 49191,
+ "pbl": 35166,
+ "pbr": 32998,
+ "pbs": 17908,
+ "pc": 6782,
+ "pc": 3808,
+ "pca": 35705,
+ "pcb": 26235,
+ "pcc": 36059,
+ "pci": 38957,
+ "pcm": 47436,
+ "pcr": 35704,
+ "pcs": 11917,
+ "pcso": 31963,
+ "pct": 22168,
+ "pd": 4387,
+ "pd": 4675,
+ "pdates": 16842,
+ "pdc": 40498,
+ "pdf": 15181,
+ "pdp": 24601,
+ "pdt": 21743,
+ "pdx": 25470,
+ "pdx": 16153,
+ "pe": 661,
+ "pe": 956,
+ "pea": 13915,
+ "peabo": 34083,
+ "peabody": 41244,
+ "peac": 34615,
+ "peace": 6249,
+ "peace": 3021,
+ "peaceful": 9461,
+ "peacefully": 30530,
+ "peacekeeping": 43630,
+ "peach": 10522,
+ "peach": 11538,
+ "peaches": 27216,
+ "peak": 18572,
+ "peak": 6026,
+ "peakdistrict": 41289,
+ "peake": 24810,
+ "peaked": 36391,
+ "peaks": 14067,
+ "pean": 11563,
+ "peanu": 25843,
+ "peanut": 12491,
+ "peanuts": 26503,
+ "pear": 4910,
+ "pear": 18820,
+ "pearce": 25996,
+ "pearl": 21806,
+ "pearl": 8560,
+ "pearljam": 46739,
+ "pearls": 19581,
+ "pears": 39565,
+ "pearson": 20461,
+ "peas": 15937,
+ "peasant": 40621,
+ "peasants": 48788,
+ "peat": 26914,
+ "pebble": 28056,
+ "pebbles": 40155,
+ "pec": 32447,
+ "pec": 17611,
+ "pecan": 32177,
+ "peck": 25186,
+ "peck": 29234,
+ "pecker": 30169,
+ "peckham": 45863,
+ "pecu": 34200,
+ "peculiar": 42808,
+ "ped": 13197,
+ "ped": 2966,
+ "pedago": 34590,
+ "pedagogy": 48072,
+ "pedal": 32943,
+ "pedal": 19621,
+ "pedals": 38535,
+ "pede": 12862,
+ "pede": 19560,
+ "pedestri": 30027,
+ "pedestrian": 18256,
+ "pedestrians": 33895,
+ "pedi": 12967,
+ "pedia": 11733,
+ "pediatric": 48431,
+ "pediatric": 22071,
+ "pedic": 35319,
+ "pedic": 44528,
+ "pedro": 29963,
+ "pedro": 15114,
+ "peds": 45377,
+ "pee": 12988,
+ "pee": 11196,
+ "peed": 47369,
+ "peek": 46323,
+ "peek": 7569,
+ "peeking": 48771,
+ "peel": 34386,
+ "peel": 17158,
+ "peeled": 33533,
+ "peeling": 48649,
+ "peep": 25425,
+ "peep": 16857,
+ "peeps": 11681,
+ "peer": 32416,
+ "peer": 14432,
+ "peers": 21626,
+ "pees": 31830,
+ "peg": 32182,
+ "peg": 11207,
+ "pegas": 30018,
+ "pegasus": 37822,
+ "peggy": 24271,
+ "pei": 48166,
+ "pei": 12917,
+ "pel": 4286,
+ "pel": 7006,
+ "pele": 44105,
+ "pelican": 34131,
+ "pelicans": 29363,
+ "pell": 46981,
+ "pelle": 31267,
+ "pelled": 32506,
+ "pellegr": 38529,
+ "pellets": 48240,
+ "pelo": 40192,
+ "pelo": 40238,
+ "pelosi": 22169,
+ "pelvic": 45646,
+ "pemb": 19880,
+ "pembro": 24084,
+ "pembroke": 36702,
+ "pembroke": 40044,
+ "pembrokeshire": 40695,
+ "pen": 1501,
+ "pen": 5356,
+ "pena": 35788,
+ "penalties": 25417,
+ "penalty": 11491,
+ "penang": 29545,
+ "penc": 20065,
+ "pence": 18002,
+ "pencil": 41303,
+ "pencil": 11200,
+ "pencils": 21909,
+ "pend": 3052,
+ "pendant": 12415,
+ "pendants": 44117,
+ "pending": 12770,
+ "pendleton": 44272,
+ "pendu": 45336,
+ "penelope": 36703,
+ "penetr": 26058,
+ "peng": 42955,
+ "peng": 39200,
+ "pengu": 8854,
+ "penguin": 28249,
+ "penguin": 14952,
+ "penguins": 16557,
+ "peninsu": 13464,
+ "peninsula": 14070,
+ "penn": 7760,
+ "penn": 11128,
+ "pennant": 43971,
+ "penned": 45077,
+ "penney": 47856,
+ "pennies": 43094,
+ "pennsylvania": 13673,
+ "penny": 20400,
+ "penny": 11388,
+ "pens": 13307,
+ "pens": 13310,
+ "pensac": 30925,
+ "pensacola": 33573,
+ "pension": 32840,
+ "pension": 17764,
+ "pensions": 29773,
+ "penske": 47154,
+ "pent": 10699,
+ "pent": 22725,
+ "pentagon": 23133,
+ "pente": 33165,
+ "penthouse": 32673,
+ "penultimate": 36553,
+ "peop": 1030,
+ "people": 10573,
+ "people": 1047,
+ "peoples": 28241,
+ "peoples": 14627,
+ "peopleschoice": 32418,
+ "peoplesvote": 45830,
+ "peoria": 36985,
+ "pep": 12761,
+ "pep": 14898,
+ "pepe": 24778,
+ "pepp": 34425,
+ "pepper": 14861,
+ "pepper": 8253,
+ "peppermint": 30321,
+ "pepperoni": 47307,
+ "peppers": 14650,
+ "pepsi": 21307,
+ "per": 703,
+ "per": 1284,
+ "pera": 26294,
+ "perce": 24135,
+ "perceived": 38436,
+ "percent": 16328,
+ "percent": 9017,
+ "percentage": 19477,
+ "percep": 28017,
+ "perception": 20591,
+ "perceptions": 38138,
+ "perch": 34281,
+ "perched": 40071,
+ "percu": 41722,
+ "percussion": 23980,
+ "percy": 23940,
+ "pere": 8665,
+ "pere": 36300,
+ "pered": 24509,
+ "peregr": 37479,
+ "peregrine": 44546,
+ "pereira": 43927,
+ "peren": 24564,
+ "perenni": 26996,
+ "perennial": 34038,
+ "perez": 15107,
+ "perf": 22816,
+ "perfe": 1624,
+ "perfec": 6599,
+ "perfect": 17261,
+ "perfect": 1878,
+ "perfection": 9646,
+ "perfectly": 8037,
+ "perfecto": 42898,
+ "perfor": 2311,
+ "perform": 3866,
+ "perform": 5940,
+ "performan": 8973,
+ "performance": 2714,
+ "performances": 9553,
+ "performed": 9997,
+ "performer": 17061,
+ "performers": 18476,
+ "performing": 5170,
+ "performs": 13839,
+ "perfu": 14214,
+ "perfume": 17525,
+ "perhaps": 9297,
+ "peri": 12618,
+ "peri": 44068,
+ "perience": 19302,
+ "peril": 40119,
+ "peril": 48301,
+ "perimeter": 38499,
+ "pering": 29746,
+ "perio": 5101,
+ "period": 6131,
+ "periodic": 36476,
+ "periods": 24401,
+ "periph": 35308,
+ "peripheral": 43901,
+ "peris": 19461,
+ "periscope": 21668,
+ "perk": 33424,
+ "perkins": 20057,
+ "perks": 17660,
+ "perl": 44018,
+ "perm": 47847,
+ "perman": 9018,
+ "permanent": 11144,
+ "permanently": 25584,
+ "perme": 42456,
+ "permission": 15822,
+ "permit": 21950,
+ "permits": 33267,
+ "permitted": 44380,
+ "pero": 23551,
+ "perpe": 15749,
+ "perpetr": 33376,
+ "perpetu": 30132,
+ "perpetual": 32018,
+ "perrie": 32691,
+ "perry": 28478,
+ "perry": 7899,
+ "pers": 3688,
+ "pers": 10710,
+ "perse": 27498,
+ "persecu": 22878,
+ "persecution": 32009,
+ "perseverance": 29820,
+ "persi": 11509,
+ "persian": 19859,
+ "persist": 19412,
+ "persist": 40938,
+ "persistence": 34588,
+ "persistent": 29028,
+ "person": 3510,
+ "person": 2533,
+ "persona": 18401,
+ "personal": 10114,
+ "personal": 4121,
+ "personalised": 24186,
+ "personalities": 27888,
+ "personality": 10386,
+ "personalized": 17845,
+ "personally": 13885,
+ "personnel": 14546,
+ "persons": 14592,
+ "perspec": 17997,
+ "perspective": 8996,
+ "perspectives": 18777,
+ "persu": 20972,
+ "pert": 36970,
+ "pert": 16306,
+ "perth": 19067,
+ "perth": 11011,
+ "peru": 20612,
+ "peru": 12964,
+ "peruvian": 30822,
+ "pes": 38368,
+ "pes": 2598,
+ "pesa": 47409,
+ "pesc": 44044,
+ "pesh": 33184,
+ "peshaw": 28524,
+ "peshawar": 29230,
+ "pesky": 42512,
+ "pesos": 47872,
+ "pessi": 43902,
+ "pest": 20130,
+ "pest": 9425,
+ "pesticide": 48481,
+ "pesticides": 37868,
+ "pesto": 26186,
+ "pests": 41919,
+ "pet": 2167,
+ "pet": 3703,
+ "peta": 28785,
+ "petal": 38430,
+ "petal": 40469,
+ "petals": 26064,
+ "petday": 45314,
+ "pete": 14479,
+ "pete": 8571,
+ "peter": 5093,
+ "peter": 3696,
+ "peterborough": 26012,
+ "peters": 16336,
+ "petersburg": 21052,
+ "petersen": 39794,
+ "peterson": 16877,
+ "peth": 48920,
+ "petit": 36437,
+ "petit": 21276,
+ "petite": 27213,
+ "petition": 10975,
+ "petitions": 43536,
+ "petr": 29808,
+ "petra": 31300,
+ "petre": 47179,
+ "petri": 31831,
+ "petro": 8716,
+ "petrol": 18149,
+ "petroleum": 22063,
+ "petron": 42875,
+ "pets": 7663,
+ "pett": 27051,
+ "petti": 48001,
+ "petting": 44334,
+ "petty": 17324,
+ "peu": 21411,
+ "peuge": 22893,
+ "peugeot": 24129,
+ "pew": 21608,
+ "pew": 30783,
+ "pewdie": 41882,
+ "pewdiepie": 42563,
+ "pex": 43765,
+ "pey": 14966,
+ "pey": 30933,
+ "peyton": 49254,
+ "peyton": 20307,
+ "pez": 45798,
+ "pez": 10482,
+ "pf": 16680,
+ "pf": 12572,
+ "pfa": 47839,
+ "pfc": 35007,
+ "pff": 44121,
+ "pfi": 29810,
+ "pfw": 31229,
+ "pg": 12476,
+ "pg": 5211,
+ "pga": 13351,
+ "pgat": 36514,
+ "pgatour": 40094,
+ "pgh": 44862,
+ "pgh": 30031,
+ "pgs": 49204,
+ "ph": 745,
+ "ph": 2042,
+ "pha": 4443,
+ "pha": 26255,
+ "phal": 19962,
+ "phan": 8731,
+ "phan": 40126,
+ "phant": 36998,
+ "phantom": 37688,
+ "phantom": 14490,
+ "phar": 5570,
+ "phara": 35792,
+ "pharaoh": 40437,
+ "pharm": 45761,
+ "pharma": 17831,
+ "pharmac": 8193,
+ "pharmaceu": 19490,
+ "pharmaceutical": 25217,
+ "pharmaceuticals": 44623,
+ "pharmacist": 41024,
+ "pharmacists": 44337,
+ "pharmacy": 15293,
+ "pharo": 42308,
+ "pharoah": 49287,
+ "pharrell": 31316,
+ "phase": 8304,
+ "phases": 35337,
+ "phat": 42492,
+ "phc": 41102,
+ "phd": 20875,
+ "phd": 8472,
+ "phdchat": 39564,
+ "phdlife": 39638,
+ "phe": 4787,
+ "phe": 19853,
+ "pheasant": 41983,
+ "phee": 41292,
+ "phel": 23711,
+ "phelps": 27128,
+ "phen": 7718,
+ "pheno": 47336,
+ "phenom": 31673,
+ "phenom": 39618,
+ "phenomen": 11304,
+ "phenomena": 41538,
+ "phenomenal": 15035,
+ "phenomenon": 24464,
+ "pher": 9194,
+ "pher": 19828,
+ "phers": 29531,
+ "pherson": 36421,
+ "phew": 10295,
+ "phi": 2239,
+ "phi": 12220,
+ "phia": 9228,
+ "phic": 3977,
+ "phie": 30237,
+ "phies": 17062,
+ "phil": 2821,
+ "phil": 6199,
+ "phila": 47443,
+ "philadel": 9428,
+ "philadelphia": 9749,
+ "philanthro": 16587,
+ "philanthropist": 44153,
+ "philanthropy": 25047,
+ "philately": 33695,
+ "phile": 36543,
+ "philharmon": 25228,
+ "philharmonic": 31699,
+ "phili": 4277,
+ "philia": 46654,
+ "philip": 20748,
+ "philip": 11074,
+ "philipp": 5623,
+ "philipp": 47591,
+ "philippe": 20942,
+ "philippine": 17629,
+ "philippines": 8149,
+ "philips": 25175,
+ "phill": 42346,
+ "phill": 48272,
+ "philli": 6456,
+ "phillies": 18748,
+ "phillip": 48832,
+ "phillip": 19323,
+ "phillips": 11041,
+ "philly": 19545,
+ "philly": 7785,
+ "philos": 8395,
+ "philosop": 20349,
+ "philosoph": 10187,
+ "philosopher": 25220,
+ "philosophical": 32628,
+ "philosophy": 12213,
+ "phils": 38573,
+ "phin": 33816,
+ "phine": 40985,
+ "phins": 40210,
+ "phish": 36897,
+ "phishing": 36546,
+ "phl": 25603,
+ "pho": 816,
+ "pho": 22707,
+ "phobia": 28749,
+ "phoe": 22673,
+ "phoebe": 27582,
+ "phoeni": 6778,
+ "phoenix": 20615,
+ "phoenix": 7793,
+ "phol": 48140,
+ "phon": 19602,
+ "phon": 31115,
+ "phone": 15486,
+ "phone": 1951,
+ "phones": 6351,
+ "phony": 31925,
+ "phora": 31363,
+ "phosp": 22638,
+ "photo": 1153,
+ "photo": 1125,
+ "photobomb": 37075,
+ "photobook": 41894,
+ "photog": 28115,
+ "photogenic": 36108,
+ "photogra": 36754,
+ "photograph": 1688,
+ "photograph": 8853,
+ "photographed": 11573,
+ "photographer": 5748,
+ "photographers": 17141,
+ "photographic": 22053,
+ "photographing": 30074,
+ "photographs": 15759,
+ "photography": 33183,
+ "photography": 2108,
+ "photom": 32223,
+ "photoo": 11106,
+ "photooftheday": 11933,
+ "photos": 2479,
+ "photoshoot": 11121,
+ "photoshop": 12419,
+ "photoshopped": 35738,
+ "phouse": 27848,
+ "php": 17370,
+ "phra": 12777,
+ "phrase": 18809,
+ "phrases": 35264,
+ "phs": 16495,
+ "phu": 21274,
+ "phuket": 34028,
+ "phx": 35466,
+ "phx": 29507,
+ "phy": 6484,
+ "phy": 4292,
+ "phyl": 35600,
+ "phyllis": 37844,
+ "phys": 3734,
+ "phys": 37894,
+ "physi": 13782,
+ "physic": 46641,
+ "physical": 44127,
+ "physical": 6671,
+ "physically": 18105,
+ "physician": 21055,
+ "physicians": 26702,
+ "physicist": 29052,
+ "physics": 9369,
+ "physio": 29574,
+ "physio": 29177,
+ "physiology": 32349,
+ "physique": 42884,
+ "phyto": 42197,
+ "pi": 741,
+ "pi": 5357,
+ "pia": 8918,
+ "pian": 24637,
+ "pianist": 21048,
+ "piano": 49278,
+ "piano": 7894,
+ "pianos": 47904,
+ "piazza": 28496,
+ "pic": 901,
+ "pic": 1282,
+ "pical": 5482,
+ "picard": 48507,
+ "picasso": 21481,
+ "piccad": 33876,
+ "piccadilly": 37287,
+ "piccollage": 43621,
+ "pick": 6379,
+ "pick": 3142,
+ "picked": 6018,
+ "picker": 43105,
+ "pickering": 47605,
+ "picket": 33559,
+ "picking": 9545,
+ "pickle": 24570,
+ "pickled": 21705,
+ "pickles": 25001,
+ "picks": 8551,
+ "pickup": 15382,
+ "pickups": 33383,
+ "picnic": 12007,
+ "pico": 23363,
+ "picoftheday": 18319,
+ "pics": 2559,
+ "pict": 18778,
+ "pictorial": 40640,
+ "picture": 11663,
+ "picture": 1674,
+ "pictured": 7647,
+ "pictures": 3646,
+ "picturesque": 24894,
+ "pid": 5225,
+ "piday": 48056,
+ "pie": 12065,
+ "pie": 5319,
+ "piece": 39632,
+ "piece": 2754,
+ "pieces": 6194,
+ "pied": 24686,
+ "pied": 12713,
+ "piedmont": 39691,
+ "pier": 5641,
+ "pier": 11348,
+ "pierc": 49216,
+ "pierce": 48462,
+ "pierce": 16782,
+ "pierced": 32799,
+ "piercing": 22557,
+ "piero": 43125,
+ "pierre": 34670,
+ "pierre": 11985,
+ "piers": 29030,
+ "pies": 6898,
+ "pieter": 44801,
+ "pietro": 42169,
+ "piff": 40719,
+ "pig": 12009,
+ "pig": 9619,
+ "pigeon": 18008,
+ "pigeons": 32910,
+ "piggy": 28245,
+ "pigment": 40284,
+ "pigs": 16228,
+ "pik": 48539,
+ "pika": 47372,
+ "pikach": 27268,
+ "pikachu": 28107,
+ "pike": 33457,
+ "pike": 14011,
+ "pil": 2893,
+ "pil": 20645,
+ "pilates": 29518,
+ "pile": 44403,
+ "pile": 13930,
+ "piled": 26873,
+ "piles": 31968,
+ "pilgri": 13966,
+ "pilgrim": 32662,
+ "pilgrimage": 24335,
+ "pilgrims": 31370,
+ "piling": 43050,
+ "pilip": 27234,
+ "pilipinas": 32392,
+ "pill": 14830,
+ "pill": 19226,
+ "pillar": 17322,
+ "pillars": 22054,
+ "pillow": 42237,
+ "pillow": 12182,
+ "pillows": 26499,
+ "pills": 23964,
+ "pilo": 37526,
+ "pilot": 31619,
+ "pilot": 6687,
+ "pilots": 15586,
+ "pilsner": 47153,
+ "pim": 15285,
+ "pim": 35472,
+ "pimp": 35789,
+ "pin": 2629,
+ "pin": 5164,
+ "pinball": 31679,
+ "pinch": 26114,
+ "pine": 9398,
+ "pine": 7374,
+ "pineapple": 14831,
+ "pines": 20338,
+ "ping": 23720,
+ "ping": 2089,
+ "pinion": 40557,
+ "pink": 11151,
+ "pink": 3360,
+ "pinkfloyd": 48520,
+ "pinky": 29803,
+ "pinn": 31448,
+ "pinnacle": 32754,
+ "pinned": 12165,
+ "pinning": 44515,
+ "pino": 36633,
+ "pinot": 41399,
+ "pinot": 21146,
+ "pinoy": 43578,
+ "pinoy": 35258,
+ "pins": 14619,
+ "pinst": 41173,
+ "pint": 42537,
+ "pint": 13584,
+ "pinterest": 15379,
+ "pinto": 35992,
+ "pints": 27935,
+ "pinup": 37349,
+ "pio": 22108,
+ "pion": 36728,
+ "pion": 29190,
+ "pione": 7975,
+ "pioneer": 34892,
+ "pioneer": 12459,
+ "pioneering": 25933,
+ "pioneers": 22383,
+ "pious": 42441,
+ "pip": 30854,
+ "pipe": 29333,
+ "pipe": 10459,
+ "pipel": 12387,
+ "pipeline": 14151,
+ "pipelines": 39683,
+ "piper": 47052,
+ "piper": 16293,
+ "pipes": 16991,
+ "piping": 40744,
+ "pippa": 47672,
+ "pir": 4351,
+ "pir": 38899,
+ "piracy": 39452,
+ "piran": 49034,
+ "pirate": 38680,
+ "pirate": 13592,
+ "pirates": 10442,
+ "pire": 16613,
+ "pires": 14988,
+ "pis": 9230,
+ "pis": 44441,
+ "pisa": 43632,
+ "pisces": 45982,
+ "piss": 20818,
+ "pissed": 17989,
+ "pist": 15556,
+ "pist": 32826,
+ "pistachi": 29760,
+ "pistachio": 36320,
+ "pistol": 20480,
+ "piston": 48236,
+ "pistons": 27242,
+ "pistor": 48162,
+ "pit": 2946,
+ "pit": 7476,
+ "pita": 27070,
+ "pitbull": 25295,
+ "pitch": 8992,
+ "pitch": 5872,
+ "pitched": 28447,
+ "pitcher": 13445,
+ "pitchers": 27835,
+ "pitches": 21005,
+ "pitching": 16455,
+ "piti": 47568,
+ "pits": 24144,
+ "pitt": 7607,
+ "pitt": 15599,
+ "pitts": 9531,
+ "pittsburgh": 10453,
+ "pity": 24380,
+ "pius": 39988,
+ "pivo": 18009,
+ "pivot": 31805,
+ "pivotal": 31432,
+ "pix": 6185,
+ "pix": 13088,
+ "pixar": 27493,
+ "pixel": 14384,
+ "pixel": 13241,
+ "pixelart": 18516,
+ "pixels": 34099,
+ "pixie": 35573,
+ "piyu": 30772,
+ "piyush": 36191,
+ "piyushgoyal": 45318,
+ "pizz": 3897,
+ "pizza": 4474,
+ "pizzas": 30647,
+ "pizzeria": 44174,
+ "pj": 12524,
+ "pj": 17179,
+ "pjnet": 22011,
+ "pjs": 36009,
+ "pk": 10149,
+ "pk": 10991,
+ "pkg": 49011,
+ "pkk": 47480,
+ "pknot": 41779,
+ "pkwy": 36827,
+ "pl": 712,
+ "pl": 5678,
+ "pla": 841,
+ "pla": 19945,
+ "plac": 2331,
+ "place": 14884,
+ "place": 1445,
+ "placed": 9729,
+ "placement": 16724,
+ "placements": 43885,
+ "placer": 49170,
+ "places": 4448,
+ "placing": 18531,
+ "plague": 25360,
+ "plaid": 23291,
+ "plain": 22776,
+ "plain": 10709,
+ "plains": 16345,
+ "plan": 1740,
+ "plan": 2970,
+ "pland": 24801,
+ "plane": 22728,
+ "plane": 5363,
+ "planes": 12581,
+ "planet": 16833,
+ "planet": 5172,
+ "planetary": 28361,
+ "planets": 22315,
+ "plank": 30991,
+ "plankton": 48249,
+ "plann": 6409,
+ "planned": 8169,
+ "planner": 18083,
+ "planners": 33664,
+ "planning": 4446,
+ "plano": 34063,
+ "plans": 4181,
+ "plant": 8521,
+ "plant": 3912,
+ "plantation": 20014,
+ "plantbased": 33720,
+ "planted": 14286,
+ "planter": 34453,
+ "planters": 43661,
+ "planting": 13922,
+ "plants": 5829,
+ "plaque": 16097,
+ "plaques": 45610,
+ "plar": 26754,
+ "plas": 45673,
+ "plasma": 24999,
+ "plaster": 31980,
+ "plastic": 15645,
+ "plastic": 6102,
+ "plasticpollution": 47129,
+ "plastics": 20999,
+ "plasticsurgery": 48555,
+ "plat": 3172,
+ "plata": 46456,
+ "plate": 28744,
+ "plate": 5135,
+ "plateau": 29301,
+ "plated": 21161,
+ "plates": 11485,
+ "platform": 5549,
+ "platforms": 13551,
+ "platin": 10267,
+ "plating": 44564,
+ "platinum": 10979,
+ "plato": 41101,
+ "platoon": 41254,
+ "platt": 44459,
+ "platt": 40097,
+ "platte": 46785,
+ "platter": 29071,
+ "platz": 40878,
+ "plau": 39139,
+ "play": 1222,
+ "play": 1453,
+ "playa": 23756,
+ "playable": 33885,
+ "playback": 39194,
+ "playbook": 34856,
+ "playboy": 24383,
+ "played": 3432,
+ "player": 24503,
+ "player": 2477,
+ "players": 3030,
+ "playful": 23871,
+ "playground": 15861,
+ "playhouse": 23254,
+ "playin": 24674,
+ "playing": 47368,
+ "playing": 1629,
+ "playlist": 9180,
+ "playlists": 47183,
+ "playo": 5804,
+ "playoff": 9655,
+ "playoffs": 9548,
+ "plays": 5134,
+ "playstation": 11332,
+ "playtime": 43037,
+ "playwright": 32070,
+ "plaza": 8943,
+ "plc": 16827,
+ "ple": 926,
+ "ple": 1619,
+ "plea": 21956,
+ "plead": 47539,
+ "pleads": 31425,
+ "plear": 21362,
+ "pleas": 8481,
+ "pleas": 48740,
+ "pleasant": 12271,
+ "please": 41074,
+ "please": 1474,
+ "pleased": 6107,
+ "pleasing": 32893,
+ "pleasure": 5854,
+ "pleasures": 29513,
+ "pledge": 11507,
+ "pledged": 36799,
+ "pledges": 26746,
+ "pledis": 41202,
+ "plein": 43429,
+ "plenary": 19891,
+ "plenty": 7524,
+ "pler": 17677,
+ "ples": 6248,
+ "pless": 39821,
+ "pless": 17059,
+ "plets": 43230,
+ "plex": 23765,
+ "plex": 15241,
+ "pley": 19543,
+ "pli": 30001,
+ "pli": 45797,
+ "plic": 5806,
+ "plicity": 19823,
+ "plight": 40317,
+ "plin": 44531,
+ "plin": 32335,
+ "pline": 25376,
+ "pling": 12899,
+ "plings": 31184,
+ "pll": 47629,
+ "pll": 25266,
+ "pln": 48755,
+ "plo": 1778,
+ "plo": 43523,
+ "plor": 34695,
+ "plot": 9918,
+ "plots": 25672,
+ "plotting": 30751,
+ "plough": 33811,
+ "plow": 38363,
+ "pls": 5572,
+ "plu": 2052,
+ "plug": 12628,
+ "plugged": 23261,
+ "plugin": 31278,
+ "plugins": 48797,
+ "plugs": 28083,
+ "plum": 26267,
+ "plum": 16202,
+ "plumb": 21769,
+ "plumber": 43478,
+ "plumbing": 24647,
+ "plume": 39495,
+ "plun": 15122,
+ "plunge": 26506,
+ "plur": 44664,
+ "plus": 3097,
+ "plush": 18926,
+ "pluto": 26380,
+ "ply": 17249,
+ "ply": 28705,
+ "plying": 36071,
+ "plym": 11907,
+ "plymouth": 13786,
+ "plz": 10538,
+ "pm": 13699,
+ "pm": 990,
+ "pmi": 41206,
+ "pmln": 23208,
+ "pmo": 18782,
+ "pmoindia": 20374,
+ "pms": 44223,
+ "pn": 14431,
+ "pn": 13774,
+ "pnc": 37148,
+ "pne": 30966,
+ "pneu": 28714,
+ "pneumonia": 42906,
+ "png": 20992,
+ "pnp": 25972,
+ "pnpp": 42175,
+ "pnw": 31521,
+ "po": 628,
+ "po": 3057,
+ "poa": 43912,
+ "poached": 27665,
+ "poaching": 35140,
+ "poc": 13232,
+ "poc": 27780,
+ "pocaly": 37987,
+ "pocalypse": 42307,
+ "poche": 38336,
+ "poche": 39022,
+ "pocket": 29147,
+ "pocket": 8504,
+ "pockets": 19566,
+ "pocon": 41850,
+ "pod": 3583,
+ "pod": 7446,
+ "podcast": 39654,
+ "podcast": 4294,
+ "podcasting": 40106,
+ "podcasts": 19392,
+ "pode": 33368,
+ "poder": 24960,
+ "podernfamily": 26620,
+ "podi": 32853,
+ "podium": 14093,
+ "pods": 18776,
+ "poe": 4746,
+ "poe": 19254,
+ "poem": 9436,
+ "poems": 15577,
+ "poet": 41019,
+ "poet": 9872,
+ "poetic": 26365,
+ "poetry": 20192,
+ "poetry": 6038,
+ "poetryday": 39255,
+ "poets": 19804,
+ "pof": 40850,
+ "poff": 28236,
+ "pogba": 25998,
+ "poign": 29682,
+ "poignant": 32138,
+ "poin": 9074,
+ "point": 13280,
+ "point": 2301,
+ "pointe": 24631,
+ "pointed": 20703,
+ "pointer": 29883,
+ "pointers": 36760,
+ "pointing": 19233,
+ "pointless": 33586,
+ "points": 3396,
+ "pois": 17008,
+ "poise": 45087,
+ "poised": 27354,
+ "poison": 30722,
+ "poison": 17074,
+ "poisoned": 43624,
+ "poisoning": 25750,
+ "poisonous": 37131,
+ "pok": 15387,
+ "poke": 6892,
+ "poke": 23186,
+ "pokemon": 16239,
+ "pokemon": 9528,
+ "pokemongo": 23985,
+ "poker": 30735,
+ "poker": 11865,
+ "pokes": 40221,
+ "poking": 49169,
+ "poké": 20656,
+ "pokémon": 22066,
+ "pol": 977,
+ "pol": 7649,
+ "pola": 43876,
+ "poland": 9834,
+ "polar": 21432,
+ "polar": 12214,
+ "polari": 27919,
+ "polaris": 37965,
+ "polarized": 48437,
+ "polaro": 25237,
+ "polaroid": 30427,
+ "poldark": 41322,
+ "pole": 26682,
+ "pole": 8170,
+ "poles": 22585,
+ "poli": 9675,
+ "poli": 5414,
+ "polic": 16126,
+ "police": 15535,
+ "police": 2120,
+ "policeman": 37713,
+ "policemen": 47946,
+ "polici": 10819,
+ "policies": 10993,
+ "policing": 20969,
+ "policy": 30173,
+ "policy": 4660,
+ "polio": 30533,
+ "polis": 16133,
+ "polish": 46941,
+ "polish": 9632,
+ "polished": 21478,
+ "polishing": 43629,
+ "polit": 2247,
+ "politan": 15337,
+ "polite": 31497,
+ "politi": 40597,
+ "politic": 33333,
+ "political": 37744,
+ "political": 4197,
+ "politically": 24323,
+ "politician": 15960,
+ "politicians": 12914,
+ "politico": 39403,
+ "politics": 4929,
+ "polk": 33317,
+ "polka": 29476,
+ "poll": 7032,
+ "pollen": 27651,
+ "pollin": 19152,
+ "pollinators": 36599,
+ "polling": 18024,
+ "pollo": 42755,
+ "pollock": 37614,
+ "polls": 11813,
+ "pollu": 8370,
+ "polluted": 43346,
+ "pollution": 10384,
+ "polly": 31204,
+ "polo": 35928,
+ "polo": 10229,
+ "poly": 6833,
+ "poly": 18367,
+ "polye": 31730,
+ "polyester": 38514,
+ "polym": 23626,
+ "polymer": 29993,
+ "polyne": 38892,
+ "polyvore": 24771,
+ "pom": 7548,
+ "pom": 24280,
+ "pome": 27963,
+ "pomegran": 29326,
+ "pomegranate": 32415,
+ "pomer": 35156,
+ "pomona": 41690,
+ "pompe": 18352,
+ "pompeii": 47775,
+ "pompeo": 34351,
+ "pompey": 35079,
+ "pon": 3809,
+ "pon": 22391,
+ "ponce": 43637,
+ "pond": 10750,
+ "ponder": 36863,
+ "pondering": 47395,
+ "ponds": 31033,
+ "pone": 32183,
+ "pong": 40546,
+ "pong": 17710,
+ "ponies": 34157,
+ "pons": 41255,
+ "pont": 47563,
+ "pont": 22997,
+ "ponte": 40892,
+ "ponti": 15527,
+ "pontiac": 25373,
+ "pontifex": 33566,
+ "ponty": 45152,
+ "pony": 24438,
+ "pony": 12678,
+ "ponytail": 43265,
+ "poo": 6601,
+ "poo": 14389,
+ "pooch": 37037,
+ "poodle": 34961,
+ "pooh": 27103,
+ "pooja": 35676,
+ "pool": 12484,
+ "pool": 2831,
+ "poole": 26290,
+ "pools": 18736,
+ "poolside": 35509,
+ "poon": 33799,
+ "poon": 36178,
+ "poop": 23310,
+ "poor": 14528,
+ "poor": 3665,
+ "poorest": 40771,
+ "poorly": 21101,
+ "pop": 6530,
+ "pop": 2852,
+ "popart": 47425,
+ "popcorn": 15034,
+ "pope": 16994,
+ "pope": 9283,
+ "popefrancis": 37254,
+ "poplar": 38726,
+ "popo": 38835,
+ "popo": 35572,
+ "popp": 13156,
+ "popped": 14934,
+ "poppies": 30385,
+ "poppin": 28536,
+ "popping": 18152,
+ "poppins": 41216,
+ "poppy": 32194,
+ "poppy": 15447,
+ "pops": 11705,
+ "popsic": 38481,
+ "popu": 3785,
+ "popul": 6593,
+ "popular": 15854,
+ "popular": 4368,
+ "popularity": 19235,
+ "populated": 38420,
+ "population": 8423,
+ "populations": 23797,
+ "populism": 48998,
+ "populist": 49376,
+ "popup": 33053,
+ "por": 817,
+ "por": 7697,
+ "pora": 23537,
+ "porcel": 19409,
+ "porcelain": 20451,
+ "porch": 17154,
+ "pore": 28267,
+ "pork": 40379,
+ "pork": 7897,
+ "poro": 48110,
+ "porridge": 34924,
+ "porsch": 48009,
+ "porsche": 44049,
+ "porsche": 8783,
+ "port": 1641,
+ "port": 1418,
+ "porta": 45037,
+ "portable": 11949,
+ "portage": 32087,
+ "portal": 14982,
+ "porte": 28654,
+ "ported": 16879,
+ "porter": 28319,
+ "porter": 10318,
+ "porters": 15670,
+ "portfoli": 45766,
+ "portfolio": 11938,
+ "porth": 37425,
+ "porti": 45760,
+ "porting": 26052,
+ "portion": 13739,
+ "portions": 22914,
+ "portland": 38366,
+ "portland": 8880,
+ "portman": 34755,
+ "porto": 24853,
+ "porto": 18947,
+ "portobello": 48025,
+ "portra": 4175,
+ "portrait": 39312,
+ "portrait": 5352,
+ "portraits": 14203,
+ "portray": 46282,
+ "portrayal": 39238,
+ "portrayed": 36093,
+ "ports": 7734,
+ "portsm": 17063,
+ "portsmouth": 19074,
+ "portu": 7159,
+ "portugal": 9503,
+ "portugue": 17498,
+ "portuguese": 18019,
+ "pos": 1780,
+ "pos": 11839,
+ "pose": 25478,
+ "pose": 4230,
+ "posed": 5206,
+ "posei": 47270,
+ "poser": 46899,
+ "poses": 9773,
+ "posey": 34852,
+ "posh": 26748,
+ "posing": 10518,
+ "posit": 28793,
+ "positi": 7895,
+ "position": 4657,
+ "positioned": 34482,
+ "positioning": 30657,
+ "positions": 12188,
+ "positive": 21811,
+ "positive": 4844,
+ "positively": 24688,
+ "positivity": 19966,
+ "poss": 39745,
+ "posse": 17414,
+ "posse": 28413,
+ "possess": 36810,
+ "possessed": 36220,
+ "possession": 16154,
+ "possessions": 40588,
+ "possi": 2521,
+ "possibilities": 17932,
+ "possibility": 18517,
+ "possible": 3134,
+ "possibly": 8601,
+ "possum": 38575,
+ "post": 3489,
+ "post": 1549,
+ "postage": 27570,
+ "postal": 21687,
+ "postcard": 14785,
+ "postcards": 23922,
+ "postdoc": 41013,
+ "posted": 4752,
+ "poster": 22881,
+ "poster": 3574,
+ "posters": 9673,
+ "postgame": 34873,
+ "postgraduate": 31997,
+ "posthum": 42410,
+ "posting": 7559,
+ "postman": 38285,
+ "postpon": 23247,
+ "postponed": 25097,
+ "posts": 7824,
+ "postseason": 24521,
+ "posture": 29681,
+ "posure": 35539,
+ "pot": 3547,
+ "pot": 5168,
+ "potam": 45825,
+ "potassi": 36889,
+ "potassium": 37147,
+ "potat": 5975,
+ "potato": 8527,
+ "potatoes": 11567,
+ "potd": 28765,
+ "pote": 41869,
+ "poten": 4454,
+ "potent": 26082,
+ "potenti": 44104,
+ "potential": 5100,
+ "potentially": 16508,
+ "potholes": 47506,
+ "potion": 46055,
+ "potom": 38848,
+ "potomac": 43372,
+ "pots": 19234,
+ "pott": 28698,
+ "potted": 48581,
+ "potter": 24975,
+ "potter": 9026,
+ "pottery": 18396,
+ "potts": 39839,
+ "potty": 43569,
+ "potus": 8740,
+ "pou": 9423,
+ "pouch": 26811,
+ "poul": 22485,
+ "poultry": 31005,
+ "poun": 33719,
+ "pound": 33809,
+ "pound": 10674,
+ "pounding": 46544,
+ "pounds": 10752,
+ "pour": 33112,
+ "pour": 8180,
+ "poured": 26621,
+ "pouring": 16098,
+ "pours": 26005,
+ "pout": 39621,
+ "poutine": 43768,
+ "pov": 25731,
+ "pover": 8432,
+ "pover": 29464,
+ "poverty": 9095,
+ "pow": 1317,
+ "pow": 17745,
+ "powder": 32427,
+ "powder": 9674,
+ "powe": 36955,
+ "powell": 13305,
+ "power": 2789,
+ "power": 1807,
+ "powerball": 47803,
+ "powered": 45442,
+ "powered": 7332,
+ "powerful": 4875,
+ "powerhouse": 22858,
+ "powering": 16231,
+ "powerof": 31961,
+ "powerpoint": 38940,
+ "powerrangers": 40620,
+ "powers": 9422,
+ "pox": 43649,
+ "poy": 34737,
+ "poyn": 47655,
+ "poz": 39953,
+ "pp": 604,
+ "pp": 4186,
+ "ppa": 10416,
+ "ppard": 23391,
+ "ppc": 27778,
+ "ppe": 24573,
+ "ppe": 11867,
+ "pped": 1873,
+ "ppel": 46523,
+ "ppen": 30663,
+ "pper": 6719,
+ "pper": 2440,
+ "ppers": 5232,
+ "ppery": 27833,
+ "ppet": 20744,
+ "ppets": 25849,
+ "ppg": 27433,
+ "ppi": 9594,
+ "ppie": 33795,
+ "ppin": 8076,
+ "pping": 22214,
+ "pping": 1682,
+ "ppings": 35687,
+ "ppl": 6758,
+ "pple": 12302,
+ "ppm": 42053,
+ "ppo": 10215,
+ "ppor": 37613,
+ "ppp": 14017,
+ "pps": 10683,
+ "ppv": 38864,
+ "ppy": 30360,
+ "ppy": 3860,
+ "pr": 766,
+ "pr": 4150,
+ "pra": 1865,
+ "pra": 19285,
+ "prab": 17901,
+ "prabhas": 29959,
+ "prabhu": 31529,
+ "prac": 2243,
+ "practi": 29995,
+ "practic": 5495,
+ "practical": 10792,
+ "practically": 25588,
+ "practice": 3349,
+ "practiced": 36749,
+ "practices": 9040,
+ "practicing": 12750,
+ "practise": 38938,
+ "practising": 36478,
+ "practiti": 19909,
+ "practitioner": 32591,
+ "practitioners": 29045,
+ "prada": 29456,
+ "pradesh": 15384,
+ "prado": 44141,
+ "prag": 31025,
+ "prague": 14940,
+ "prairi": 12629,
+ "prairie": 14753,
+ "praise": 10013,
+ "praised": 27649,
+ "praises": 23049,
+ "praising": 36961,
+ "prakash": 43708,
+ "prakash": 25366,
+ "pram": 47774,
+ "pran": 20048,
+ "prank": 23654,
+ "pras": 41562,
+ "prasad": 29562,
+ "prat": 23069,
+ "prati": 45773,
+ "pratt": 37863,
+ "pratt": 23396,
+ "prawn": 33102,
+ "prawns": 34903,
+ "pray": 12671,
+ "pray": 6041,
+ "prayed": 34665,
+ "prayer": 41452,
+ "prayer": 6583,
+ "prayers": 8393,
+ "prayfor": 18443,
+ "praying": 11550,
+ "prays": 46602,
+ "prc": 28781,
+ "pre": 679,
+ "pre": 2900,
+ "preach": 22545,
+ "preacher": 29357,
+ "preaching": 23642,
+ "precau": 36532,
+ "precautions": 47845,
+ "prece": 15361,
+ "preci": 5470,
+ "precin": 27908,
+ "precinct": 32587,
+ "precious": 8226,
+ "precipit": 27463,
+ "precipitation": 33399,
+ "precise": 24457,
+ "precisely": 34954,
+ "precision": 44021,
+ "precision": 15621,
+ "pred": 40370,
+ "predat": 13364,
+ "predator": 20653,
+ "predators": 25569,
+ "prede": 38454,
+ "predecess": 38963,
+ "predic": 4876,
+ "predict": 16900,
+ "predictable": 25344,
+ "predicted": 18702,
+ "predicting": 30414,
+ "prediction": 16296,
+ "predictions": 15125,
+ "predictive": 29798,
+ "predicts": 25960,
+ "preds": 40125,
+ "pree": 47026,
+ "preet": 30131,
+ "prefe": 14542,
+ "prefecture": 32890,
+ "prefer": 33426,
+ "prefer": 11450,
+ "preference": 35057,
+ "preferences": 38118,
+ "preferred": 18772,
+ "prefers": 38528,
+ "pregame": 18575,
+ "pregn": 7190,
+ "pregnancy": 12769,
+ "pregnant": 11195,
+ "prehistoric": 32750,
+ "prejudice": 28337,
+ "preli": 15523,
+ "prelimin": 19990,
+ "preliminary": 20997,
+ "prelims": 43223,
+ "prelude": 42966,
+ "prem": 32090,
+ "prem": 21724,
+ "premature": 39253,
+ "premi": 2413,
+ "premier": 16996,
+ "premier": 5539,
+ "premiere": 5367,
+ "premiered": 27652,
+ "premieres": 19907,
+ "premiering": 32615,
+ "premierleague": 22608,
+ "premiers": 44883,
+ "premiership": 23665,
+ "premiosm": 38460,
+ "premiosmtvmiaw": 38630,
+ "premise": 45952,
+ "premises": 27266,
+ "premium": 8011,
+ "pren": 20801,
+ "preneur": 46288,
+ "preorder": 16703,
+ "preorders": 45985,
+ "prep": 6430,
+ "prep": 7277,
+ "prepa": 26270,
+ "prepaid": 42934,
+ "prepar": 4968,
+ "preparation": 11651,
+ "preparations": 19135,
+ "prepare": 7014,
+ "prepared": 7677,
+ "preparedness": 29492,
+ "prepares": 16375,
+ "preparing": 7365,
+ "prepped": 34379,
+ "prepping": 16459,
+ "preps": 14765,
+ "prequel": 40461,
+ "pres": 1385,
+ "pres": 8529,
+ "presale": 27135,
+ "presby": 30447,
+ "presbyter": 33959,
+ "presbyterian": 35370,
+ "preschool": 24354,
+ "prescott": 29392,
+ "prescri": 14851,
+ "prescribed": 36968,
+ "prescription": 23061,
+ "preseason": 13813,
+ "presen": 16742,
+ "presence": 8848,
+ "present": 2344,
+ "present": 2881,
+ "presentation": 4594,
+ "presentations": 16998,
+ "presented": 4587,
+ "presenter": 18587,
+ "presenters": 32759,
+ "presenting": 5339,
+ "presents": 4215,
+ "preserv": 17616,
+ "preservation": 21074,
+ "preserve": 15570,
+ "preserved": 23161,
+ "preserves": 44881,
+ "preserving": 32315,
+ "presi": 1697,
+ "presiden": 43374,
+ "presidency": 18077,
+ "president": 19900,
+ "president": 1940,
+ "presidente": 47363,
+ "presidenti": 48297,
+ "presidential": 8503,
+ "presidents": 16726,
+ "presiding": 45298,
+ "presley": 30013,
+ "press": 4124,
+ "press": 2124,
+ "pressed": 20080,
+ "presser": 27826,
+ "presses": 33748,
+ "pressing": 20893,
+ "pressure": 6083,
+ "pressures": 38487,
+ "prest": 41840,
+ "presti": 12245,
+ "prestige": 29328,
+ "prestigious": 15888,
+ "presto": 42211,
+ "preston": 37335,
+ "preston": 15179,
+ "presu": 21667,
+ "presumably": 42562,
+ "pret": 9652,
+ "preten": 15871,
+ "pretend": 18111,
+ "pretending": 21306,
+ "pretoria": 36080,
+ "prett": 46667,
+ "prettier": 31745,
+ "prettiest": 22866,
+ "pretty": 18286,
+ "pretty": 2111,
+ "pretz": 24890,
+ "pretzel": 36707,
+ "pretzels": 45468,
+ "prev": 20274,
+ "prevail": 31637,
+ "prevalence": 41729,
+ "prevalent": 46260,
+ "preven": 29382,
+ "prevent": 26436,
+ "prevent": 7968,
+ "preventable": 44250,
+ "prevented": 35356,
+ "preventing": 21756,
+ "prevention": 9500,
+ "preventive": 40949,
+ "prevents": 31746,
+ "preview": 4449,
+ "previews": 20279,
+ "previous": 9252,
+ "previously": 13359,
+ "prey": 17131,
+ "prez": 17956,
+ "pri": 955,
+ "pri": 23400,
+ "pric": 24275,
+ "price": 13254,
+ "price": 2827,
+ "priced": 16934,
+ "priceless": 15743,
+ "prices": 5954,
+ "pricing": 14800,
+ "prick": 43921,
+ "prick": 46516,
+ "pride": 15323,
+ "pride": 3436,
+ "pridemonth": 41410,
+ "prie": 22477,
+ "priest": 38756,
+ "priest": 14222,
+ "priests": 30005,
+ "prim": 22004,
+ "prima": 35611,
+ "prima": 33277,
+ "primal": 36604,
+ "primar": 21579,
+ "primaries": 46126,
+ "primarily": 29465,
+ "primark": 48329,
+ "primary": 35024,
+ "primary": 5814,
+ "primavera": 44899,
+ "prime": 14162,
+ "prime": 5183,
+ "primed": 45694,
+ "primer": 22388,
+ "primetime": 29763,
+ "primitive": 37467,
+ "primo": 43215,
+ "primrose": 45891,
+ "prin": 1588,
+ "prince": 9457,
+ "prince": 4735,
+ "princes": 45329,
+ "princes": 30136,
+ "princess": 24123,
+ "princess": 5079,
+ "princesses": 34161,
+ "princeton": 22433,
+ "princi": 5129,
+ "principal": 33599,
+ "principal": 8860,
+ "principals": 27524,
+ "principle": 19595,
+ "principles": 13755,
+ "print": 17851,
+ "print": 3557,
+ "printable": 29648,
+ "printed": 7978,
+ "printer": 14521,
+ "printers": 27881,
+ "printing": 7369,
+ "printmaking": 38669,
+ "prints": 7704,
+ "prior": 20328,
+ "prior": 10572,
+ "priorit": 47773,
+ "prioriti": 28822,
+ "priorities": 15232,
+ "prioritize": 46715,
+ "priority": 12451,
+ "priory": 38665,
+ "prisc": 32468,
+ "priscilla": 42396,
+ "prise": 23343,
+ "prism": 49311,
+ "prism": 34356,
+ "prison": 9281,
+ "prison": 6622,
+ "prisoner": 21427,
+ "prisoners": 17460,
+ "prisons": 26607,
+ "pristine": 30618,
+ "prit": 41668,
+ "prit": 37523,
+ "prith": 39173,
+ "prius": 43561,
+ "priv": 3270,
+ "privacy": 10437,
+ "private": 20362,
+ "private": 4439,
+ "privately": 32970,
+ "privati": 27379,
+ "privi": 8367,
+ "privileg": 18015,
+ "privilege": 11537,
+ "privileged": 18166,
+ "prix": 10875,
+ "priya": 31275,
+ "priyan": 16488,
+ "priyanka": 31959,
+ "priyankach": 30030,
+ "priyankachopra": 30264,
+ "prize": 48222,
+ "prize": 4521,
+ "prized": 38769,
+ "prizes": 9268,
+ "prk": 37094,
+ "pro": 644,
+ "pro": 2630,
+ "proactive": 33364,
+ "prob": 17706,
+ "prob": 24007,
+ "probab": 3907,
+ "probability": 32637,
+ "probable": 42444,
+ "probably": 4047,
+ "probation": 36531,
+ "probe": 14359,
+ "probes": 48564,
+ "probiotics": 49395,
+ "proble": 2719,
+ "problem": 4324,
+ "problematic": 33767,
+ "problems": 4671,
+ "probs": 16330,
+ "probz": 34243,
+ "proc": 38417,
+ "proce": 4076,
+ "procedu": 18204,
+ "procedural": 48177,
+ "procedure": 20163,
+ "procedures": 21109,
+ "proceed": 26664,
+ "proceed": 33894,
+ "proceedings": 26953,
+ "proceeds": 11882,
+ "process": 17291,
+ "process": 4078,
+ "processed": 23816,
+ "processes": 15169,
+ "processing": 11737,
+ "procession": 26288,
+ "processor": 22838,
+ "processors": 43634,
+ "proclaimed": 34489,
+ "proclamation": 32065,
+ "procra": 25361,
+ "procrastin": 25586,
+ "procrastination": 42825,
+ "procreate": 39336,
+ "proctor": 47204,
+ "procu": 21001,
+ "procurement": 23733,
+ "prod": 44349,
+ "prod": 11991,
+ "prodi": 27759,
+ "prodigy": 31973,
+ "produ": 27852,
+ "produc": 1471,
+ "produce": 7529,
+ "produced": 7479,
+ "producer": 7064,
+ "producers": 13883,
+ "produces": 19940,
+ "producing": 13579,
+ "product": 32602,
+ "product": 4306,
+ "production": 4146,
+ "productions": 14166,
+ "productive": 9697,
+ "productivity": 12800,
+ "products": 3964,
+ "prof": 15043,
+ "prof": 5488,
+ "profe": 2611,
+ "profess": 5486,
+ "professi": 3705,
+ "profession": 8104,
+ "profession": 19671,
+ "professional": 46007,
+ "professional": 4774,
+ "professionalism": 41252,
+ "professionally": 33892,
+ "professionals": 10165,
+ "professor": 47302,
+ "professor": 6092,
+ "professors": 27758,
+ "profici": 34685,
+ "profile": 14291,
+ "profile": 6444,
+ "profiles": 22070,
+ "profiling": 37123,
+ "profit": 16941,
+ "profit": 7909,
+ "profitable": 25465,
+ "profits": 13410,
+ "profound": 48245,
+ "profound": 22998,
+ "profs": 19260,
+ "prog": 22219,
+ "progno": 46070,
+ "program": 4162,
+ "program": 2737,
+ "programme": 6322,
+ "programmer": 37001,
+ "programmes": 20468,
+ "programming": 10831,
+ "programs": 7345,
+ "progre": 7069,
+ "progress": 4421,
+ "progressi": 23297,
+ "progressing": 32346,
+ "progression": 24772,
+ "progressive": 12208,
+ "progressives": 41709,
+ "prohi": 41124,
+ "prohib": 45040,
+ "prohibition": 34440,
+ "proj": 39156,
+ "proje": 48345,
+ "projec": 1610,
+ "project": 15911,
+ "project": 1965,
+ "projected": 22873,
+ "projection": 22384,
+ "projections": 34638,
+ "projector": 27816,
+ "projects": 5090,
+ "proli": 19710,
+ "prolife": 32126,
+ "prolifer": 39018,
+ "prolific": 27839,
+ "prolly": 45968,
+ "prolon": 35379,
+ "prolonged": 41972,
+ "prom": 40363,
+ "prom": 7944,
+ "prome": 34355,
+ "promen": 33578,
+ "promenade": 35522,
+ "promethe": 44183,
+ "promin": 35217,
+ "prominent": 19172,
+ "promis": 3963,
+ "promise": 6745,
+ "promised": 11516,
+ "promises": 12064,
+ "promising": 14183,
+ "promo": 3037,
+ "promo": 6755,
+ "promos": 35044,
+ "promote": 47384,
+ "promote": 8003,
+ "promoted": 16395,
+ "promoter": 33081,
+ "promotes": 20169,
+ "promoting": 9695,
+ "promotion": 9259,
+ "promotional": 17619,
+ "promotions": 19142,
+ "promp": 11671,
+ "prompt": 20198,
+ "prompted": 45746,
+ "prompts": 33490,
+ "proms": 37759,
+ "pron": 13285,
+ "prone": 30964,
+ "pronoun": 23022,
+ "pronounce": 40489,
+ "pronounced": 34109,
+ "pronto": 44296,
+ "proof": 17020,
+ "proof": 5248,
+ "proofing": 35679,
+ "proofs": 41023,
+ "prop": 19123,
+ "prop": 16254,
+ "propag": 12151,
+ "propaganda": 14718,
+ "propane": 45546,
+ "propel": 48439,
+ "propeller": 47404,
+ "proper": 3577,
+ "proper": 8205,
+ "properly": 12560,
+ "properties": 10922,
+ "property": 26486,
+ "property": 5043,
+ "prophe": 9662,
+ "prophecy": 32501,
+ "prophet": 15549,
+ "prophetic": 47476,
+ "prophets": 39441,
+ "propor": 35016,
+ "proportion": 35775,
+ "proportions": 39391,
+ "propos": 9455,
+ "proposal": 12139,
+ "proposals": 20568,
+ "propose": 28471,
+ "proposed": 10615,
+ "proposes": 27133,
+ "proposing": 42631,
+ "proposition": 44780,
+ "propri": 28243,
+ "props": 15249,
+ "propulsion": 49380,
+ "pros": 33925,
+ "pros": 14147,
+ "prosciutto": 46565,
+ "prose": 47063,
+ "prose": 28675,
+ "prosecco": 28839,
+ "prosecu": 12136,
+ "prosecution": 30902,
+ "prosecutor": 23736,
+ "prosecutors": 31656,
+ "prosp": 24242,
+ "prospec": 12693,
+ "prospect": 11211,
+ "prospective": 28034,
+ "prospects": 15372,
+ "prosper": 16121,
+ "prosper": 33526,
+ "prosperity": 17203,
+ "prosperous": 28252,
+ "prost": 47923,
+ "prostate": 28808,
+ "prostatec": 49064,
+ "prosthetic": 44602,
+ "prostitu": 37333,
+ "protag": 28950,
+ "protagonist": 38183,
+ "prote": 1845,
+ "protec": 5640,
+ "protect": 25563,
+ "protect": 4817,
+ "protected": 12266,
+ "protecting": 11710,
+ "protection": 6238,
+ "protections": 33772,
+ "protective": 17028,
+ "protector": 20441,
+ "protectors": 45039,
+ "protects": 21889,
+ "protein": 8088,
+ "proteins": 28661,
+ "protest": 6279,
+ "protestant": 46945,
+ "protested": 48089,
+ "protester": 42073,
+ "protesters": 12660,
+ "protesting": 18788,
+ "protestors": 27822,
+ "protests": 12450,
+ "proto": 8672,
+ "proto": 44958,
+ "protocol": 19938,
+ "protocols": 39631,
+ "proton": 40009,
+ "prototype": 16675,
+ "prototyping": 42081,
+ "prou": 5739,
+ "proud": 11080,
+ "proud": 1679,
+ "prouder": 39585,
+ "proudest": 46806,
+ "proudly": 11203,
+ "proudof": 48184,
+ "proudtobe": 35043,
+ "prov": 23772,
+ "prov": 35021,
+ "prove": 10107,
+ "proved": 16473,
+ "proven": 35405,
+ "proven": 14569,
+ "provence": 28067,
+ "prover": 18312,
+ "proverb": 34419,
+ "proverbs": 27016,
+ "proves": 16119,
+ "provi": 2289,
+ "provide": 4832,
+ "provided": 9046,
+ "providence": 19331,
+ "provider": 14409,
+ "providers": 17120,
+ "provides": 7161,
+ "providing": 7250,
+ "provin": 12074,
+ "province": 8978,
+ "provinces": 35050,
+ "provincial": 16002,
+ "proving": 18055,
+ "provision": 30148,
+ "provisional": 36008,
+ "provisions": 39269,
+ "provo": 15367,
+ "provoc": 31618,
+ "provocative": 43809,
+ "provoking": 25510,
+ "provost": 36627,
+ "prow": 38737,
+ "prowrestling": 39825,
+ "prox": 41616,
+ "proxim": 31436,
+ "proximity": 38298,
+ "proxy": 31680,
+ "prs": 23879,
+ "pru": 12961,
+ "pruitt": 39453,
+ "prun": 29029,
+ "pruning": 48133,
+ "pry": 31965,
+ "pryor": 43375,
+ "ps": 3982,
+ "ps": 814,
+ "psa": 14031,
+ "psal": 13859,
+ "psalm": 17995,
+ "psalms": 35003,
+ "psb": 37017,
+ "psc": 43118,
+ "psd": 28810,
+ "pse": 19737,
+ "pse": 5423,
+ "pseu": 24919,
+ "pseudo": 46618,
+ "psg": 17123,
+ "psi": 45848,
+ "psi": 24533,
+ "psic": 29299,
+ "psis": 33041,
+ "psl": 21373,
+ "psn": 36781,
+ "pso": 27045,
+ "pson": 7487,
+ "psori": 44688,
+ "psp": 32769,
+ "pss": 35718,
+ "pss": 42535,
+ "psst": 47814,
+ "pst": 12692,
+ "psu": 41286,
+ "psu": 28338,
+ "psv": 44530,
+ "psy": 3576,
+ "psy": 11056,
+ "psych": 31041,
+ "psych": 20509,
+ "psyched": 19932,
+ "psyched": 35199,
+ "psychedelic": 23292,
+ "psychi": 18147,
+ "psychiatric": 30578,
+ "psychiatry": 39706,
+ "psychic": 24916,
+ "psycho": 6472,
+ "psycho": 22154,
+ "psychological": 18153,
+ "psychologist": 32827,
+ "psychology": 12352,
+ "psychop": 30112,
+ "psychotic": 48774,
+ "pt": 11139,
+ "pt": 1459,
+ "pta": 11586,
+ "ptbo": 40481,
+ "ptc": 44646,
+ "pte": 47804,
+ "pter": 49323,
+ "pti": 29375,
+ "pti": 10491,
+ "ptic": 20670,
+ "ption": 3479,
+ "ptions": 24963,
+ "pto": 31372,
+ "pto": 34092,
+ "pton": 19780,
+ "pts": 5886,
+ "ptsd": 23973,
+ "ptv": 42402,
+ "pu": 755,
+ "pu": 11780,
+ "pub": 20720,
+ "pub": 6301,
+ "puberty": 44122,
+ "pubg": 31496,
+ "publ": 3434,
+ "publi": 1617,
+ "public": 3592,
+ "public": 2122,
+ "publica": 49007,
+ "publication": 13538,
+ "publications": 27334,
+ "publichealth": 35872,
+ "publicity": 20831,
+ "publicly": 18554,
+ "publish": 19032,
+ "published": 4311,
+ "publisher": 20455,
+ "publishers": 25222,
+ "publishes": 35633,
+ "publishing": 10994,
+ "publix": 47985,
+ "pubs": 21099,
+ "puc": 48779,
+ "puck": 17550,
+ "pud": 39234,
+ "pudding": 14025,
+ "puddle": 33545,
+ "pue": 20161,
+ "pueblo": 33076,
+ "puer": 8968,
+ "puerto": 12289,
+ "puertor": 22757,
+ "puertorico": 26356,
+ "puff": 44477,
+ "puff": 17184,
+ "puffin": 47632,
+ "puffs": 47453,
+ "puffy": 49245,
+ "pug": 20950,
+ "pug": 17739,
+ "pugchat": 42266,
+ "pugh": 41302,
+ "puglia": 38345,
+ "pugs": 39425,
+ "puj": 46163,
+ "puja": 33753,
+ "puk": 31811,
+ "pul": 2469,
+ "pul": 40512,
+ "pula": 45856,
+ "puli": 47293,
+ "pulit": 27745,
+ "pulitzer": 31419,
+ "pull": 20155,
+ "pull": 6857,
+ "pulled": 8525,
+ "pulling": 12897,
+ "pullman": 40203,
+ "pullover": 44020,
+ "pulls": 16041,
+ "pulmon": 32613,
+ "pulmonary": 39132,
+ "pulp": 25410,
+ "pulse": 40091,
+ "pulse": 12485,
+ "pulses": 42177,
+ "pulsion": 35398,
+ "pum": 37497,
+ "puma": 20858,
+ "pump": 5179,
+ "pump": 9173,
+ "pumped": 12796,
+ "pumping": 25150,
+ "pumpkin": 36386,
+ "pumpkin": 8842,
+ "pumpkins": 23787,
+ "pumps": 18540,
+ "pun": 2707,
+ "pun": 19929,
+ "punc": 43907,
+ "punch": 29332,
+ "punch": 10730,
+ "punched": 31689,
+ "punches": 35279,
+ "punching": 33468,
+ "punctu": 31565,
+ "punctuation": 47051,
+ "pundit": 41466,
+ "pune": 32593,
+ "pune": 14488,
+ "pung": 45420,
+ "puni": 11479,
+ "punish": 34569,
+ "punished": 31598,
+ "punisher": 38509,
+ "punishment": 19099,
+ "punjab": 19405,
+ "punjab": 12883,
+ "punjabi": 25430,
+ "punk": 28933,
+ "punk": 7246,
+ "punks": 47171,
+ "puns": 35231,
+ "punt": 32699,
+ "punta": 34112,
+ "punter": 47092,
+ "pup": 11926,
+ "pup": 11302,
+ "pupil": 27265,
+ "pupils": 13628,
+ "pupp": 7116,
+ "puppet": 18439,
+ "puppets": 28475,
+ "puppies": 14820,
+ "puppy": 25431,
+ "puppy": 6829,
+ "puppylove": 40849,
+ "pups": 20778,
+ "pur": 1727,
+ "pur": 6265,
+ "pura": 25596,
+ "puram": 46174,
+ "purcell": 46065,
+ "purch": 8384,
+ "purchase": 5481,
+ "purchased": 13399,
+ "purchases": 21887,
+ "purchasing": 20718,
+ "purdu": 40691,
+ "purdue": 22280,
+ "pure": 14202,
+ "pure": 5979,
+ "puree": 45474,
+ "purely": 32459,
+ "puremichigan": 39783,
+ "purest": 45497,
+ "purge": 33514,
+ "puri": 16910,
+ "puri": 21974,
+ "purification": 47724,
+ "purity": 29780,
+ "purple": 17837,
+ "purple": 5496,
+ "purpose": 33492,
+ "purpose": 7391,
+ "purposes": 22020,
+ "purr": 49262,
+ "purr": 46343,
+ "purse": 16480,
+ "pursue": 19463,
+ "pursuing": 26424,
+ "pursuit": 16469,
+ "purée": 40981,
+ "pus": 13841,
+ "pusa": 40825,
+ "push": 16028,
+ "push": 6831,
+ "pushaw": 35407,
+ "pushaward": 35448,
+ "pushawards": 47184,
+ "pushed": 16155,
+ "pushes": 23828,
+ "pushing": 11549,
+ "put": 29535,
+ "put": 1983,
+ "putin": 10693,
+ "putnam": 40235,
+ "puts": 7898,
+ "putt": 30279,
+ "putter": 44723,
+ "putting": 5154,
+ "puzz": 19760,
+ "puzzle": 12875,
+ "puzzles": 27986,
+ "pv": 14517,
+ "pv": 13495,
+ "pvc": 26959,
+ "pvp": 44172,
+ "pvt": 29898,
+ "pw": 19419,
+ "pw": 16067,
+ "pwc": 22965,
+ "px": 24790,
+ "px": 10262,
+ "pxrtg": 36262,
+ "py": 4005,
+ "py": 7504,
+ "pye": 31099,
+ "pyeongchang": 36066,
+ "pyg": 41450,
+ "pyram": 14405,
+ "pyramid": 18725,
+ "pyramids": 36877,
+ "pyrene": 36740,
+ "pyrenees": 39744,
+ "pyro": 39762,
+ "python": 13370,
+ "pz": 48361,
+ "pé": 43167,
+ "q": 80,
+ "q": 336,
+ "qa": 24944,
+ "qa": 16360,
+ "qad": 27844,
+ "qadri": 35672,
+ "qaeda": 31246,
+ "qanda": 48672,
+ "qanon": 19182,
+ "qant": 35404,
+ "qantas": 43250,
+ "qatar": 32804,
+ "qatar": 10872,
+ "qb": 8073,
+ "qbs": 38188,
+ "qc": 17406,
+ "qe": 30974,
+ "qf": 27215,
+ "qi": 25054,
+ "qi": 11256,
+ "qing": 46522,
+ "qing": 34339,
+ "ql": 28366,
+ "qld": 23039,
+ "qld": 13765,
+ "qldpol": 42296,
+ "qm": 42148,
+ "qotd": 24504,
+ "qpr": 24788,
+ "qq": 31960,
+ "qr": 18193,
+ "qs": 14364,
+ "qt": 15013,
+ "qtr": 44803,
+ "qu": 666,
+ "qu": 28646,
+ "qua": 20363,
+ "quack": 45575,
+ "quad": 11656,
+ "quad": 13419,
+ "quadcopter": 39792,
+ "quadru": 35831,
+ "quaid": 34265,
+ "quail": 34392,
+ "quaint": 45976,
+ "quake": 8421,
+ "quaker": 43395,
+ "quakes": 24572,
+ "qual": 9979,
+ "qual": 32405,
+ "qualcomm": 38683,
+ "quali": 4574,
+ "qualification": 21508,
+ "qualifications": 35225,
+ "qualified": 11927,
+ "qualifier": 18733,
+ "qualifiers": 21388,
+ "qualifies": 35820,
+ "qualify": 17019,
+ "qualifying": 11895,
+ "qualitative": 45847,
+ "qualities": 20488,
+ "quality": 28545,
+ "quality": 3027,
+ "quan": 11669,
+ "quan": 27490,
+ "quand": 28198,
+ "quant": 15050,
+ "quanti": 31540,
+ "quantitative": 40583,
+ "quantities": 33917,
+ "quantity": 26920,
+ "quantum": 15320,
+ "quar": 3856,
+ "quare": 42549,
+ "quarry": 27601,
+ "quart": 7851,
+ "quarter": 8816,
+ "quarter": 6632,
+ "quarterback": 16545,
+ "quarterfinal": 37992,
+ "quarterfinals": 28971,
+ "quarterly": 23350,
+ "quarters": 10146,
+ "quartet": 18056,
+ "quartz": 17752,
+ "quat": 25715,
+ "quattro": 40300,
+ "quay": 40276,
+ "quay": 17304,
+ "que": 1147,
+ "que": 2319,
+ "quebec": 15373,
+ "queen": 6407,
+ "queen": 2997,
+ "queenof": 44398,
+ "queens": 22943,
+ "queens": 9330,
+ "queensland": 15168,
+ "queer": 38874,
+ "queer": 18161,
+ "quel": 39774,
+ "quel": 21879,
+ "quen": 23876,
+ "quen": 38324,
+ "quent": 23808,
+ "quentin": 27530,
+ "quer": 17378,
+ "quer": 26859,
+ "quered": 23210,
+ "queries": 32958,
+ "querque": 30338,
+ "query": 27464,
+ "ques": 25328,
+ "ques": 7715,
+ "queso": 40110,
+ "quest": 31653,
+ "quest": 4846,
+ "questi": 2391,
+ "question": 18961,
+ "question": 4382,
+ "questionable": 30733,
+ "questioned": 31847,
+ "questioning": 24887,
+ "questions": 3883,
+ "quests": 44611,
+ "quet": 8513,
+ "quets": 39055,
+ "quetta": 38326,
+ "quette": 18993,
+ "queu": 32705,
+ "queue": 18549,
+ "queues": 40649,
+ "queuing": 44082,
+ "quez": 18677,
+ "quezon": 41117,
+ "qui": 1912,
+ "qui": 18046,
+ "quic": 26474,
+ "quiche": 47723,
+ "quick": 5969,
+ "quick": 3712,
+ "quicker": 29211,
+ "quickest": 37734,
+ "quickly": 7787,
+ "quid": 30732,
+ "quie": 43875,
+ "quien": 43482,
+ "quiere": 42723,
+ "quiero": 32567,
+ "quiet": 17853,
+ "quiet": 7557,
+ "quietly": 22208,
+ "quig": 44690,
+ "quil": 12305,
+ "quill": 48951,
+ "quilt": 23977,
+ "quilted": 46052,
+ "quin": 8607,
+ "quin": 17167,
+ "quincy": 27640,
+ "quind": 32339,
+ "quinn": 12306,
+ "quinoa": 26703,
+ "quins": 39701,
+ "quint": 26898,
+ "quinta": 47446,
+ "quinte": 22098,
+ "quintess": 37538,
+ "quintet": 35125,
+ "quipment": 42813,
+ "quir": 15943,
+ "quirky": 25044,
+ "quis": 15064,
+ "quist": 25128,
+ "quit": 19358,
+ "quit": 11140,
+ "quite": 4135,
+ "quito": 35828,
+ "quits": 32505,
+ "quitting": 33871,
+ "quity": 33133,
+ "quiz": 31197,
+ "quiz": 8344,
+ "quizz": 35041,
+ "quo": 3046,
+ "quo": 28127,
+ "quoi": 45549,
+ "quot": 5452,
+ "quot": 47587,
+ "quota": 42097,
+ "quotation": 49195,
+ "quote": 15446,
+ "quote": 4020,
+ "quoted": 27706,
+ "quoteoftheday": 19975,
+ "quotes": 5808,
+ "quoting": 31651,
+ "qur": 37782,
+ "quran": 19690,
+ "qureshi": 46307,
+ "qvist": 42322,
+ "qx": 45038,
+ "r": 81,
+ "r": 337,
+ "ra": 559,
+ "ra": 1735,
+ "raa": 44344,
+ "rab": 14816,
+ "rab": 33224,
+ "rabb": 6875,
+ "rabbi": 20959,
+ "rabbit": 10274,
+ "rabbits": 27028,
+ "rabhu": 25806,
+ "rable": 10182,
+ "rac": 1773,
+ "rac": 30462,
+ "raccoon": 29516,
+ "race": 10978,
+ "race": 2471,
+ "racec": 18814,
+ "racecourse": 25036,
+ "raced": 36021,
+ "racer": 16798,
+ "racers": 33603,
+ "races": 8605,
+ "raceway": 24650,
+ "rach": 6876,
+ "rach": 33429,
+ "racha": 21952,
+ "racha": 35022,
+ "rachael": 29095,
+ "rachel": 13511,
+ "rachel": 8029,
+ "raci": 33381,
+ "racial": 13801,
+ "racially": 43577,
+ "racing": 23306,
+ "racing": 3699,
+ "racism": 11276,
+ "racist": 9684,
+ "racists": 41777,
+ "rack": 24600,
+ "rack": 12034,
+ "racket": 37691,
+ "racks": 21191,
+ "rad": 4473,
+ "rad": 8238,
+ "rada": 30437,
+ "radar": 9672,
+ "radcliffe": 33096,
+ "rade": 44494,
+ "rade": 17911,
+ "rader": 45002,
+ "radford": 45800,
+ "radha": 43122,
+ "radi": 5772,
+ "radial": 42028,
+ "radiance": 45670,
+ "radiant": 25614,
+ "radiation": 18210,
+ "radiator": 39372,
+ "radic": 18082,
+ "radical": 13712,
+ "radicals": 45903,
+ "radio": 7176,
+ "radio": 2638,
+ "radioactive": 34704,
+ "radiodisney": 36483,
+ "radiohead": 39472,
+ "radiology": 29684,
+ "radios": 43669,
+ "radish": 37789,
+ "radius": 37570,
+ "rado": 29784,
+ "rae": 21646,
+ "rae": 15051,
+ "rael": 45390,
+ "raer": 44561,
+ "raf": 11495,
+ "raf": 11490,
+ "rafa": 14352,
+ "rafa": 24850,
+ "rafael": 38221,
+ "rafael": 19216,
+ "rafaelnadal": 49219,
+ "raff": 34900,
+ "raffic": 32928,
+ "raffle": 13752,
+ "raffles": 43489,
+ "rafi": 35304,
+ "raft": 9233,
+ "rafting": 36309,
+ "rag": 13958,
+ "rag": 20687,
+ "rage": 8593,
+ "rages": 34253,
+ "ragh": 35642,
+ "ragha": 40972,
+ "raging": 25015,
+ "ragn": 24125,
+ "ragnar": 34385,
+ "ragnarok": 41856,
+ "ragon": 34768,
+ "rags": 47838,
+ "rah": 12277,
+ "rah": 8766,
+ "raheem": 43317,
+ "rahim": 24152,
+ "rahman": 19680,
+ "rahu": 13129,
+ "rahul": 37239,
+ "rahul": 17440,
+ "rahulg": 27510,
+ "rahulgandhi": 28293,
+ "rai": 9165,
+ "rai": 9638,
+ "raid": 6877,
+ "raided": 43417,
+ "raider": 27368,
+ "raider": 21455,
+ "raidernation": 47901,
+ "raiders": 11817,
+ "raids": 26655,
+ "rail": 4573,
+ "rail": 6879,
+ "raila": 47273,
+ "railminindia": 35557,
+ "railroad": 17080,
+ "rails": 23427,
+ "railway": 27614,
+ "railway": 7856,
+ "railwayana": 46750,
+ "railways": 20765,
+ "raim": 45785,
+ "rain": 3128,
+ "rain": 2443,
+ "raina": 30564,
+ "rainbow": 24562,
+ "rainbow": 6286,
+ "rainbows": 30483,
+ "raine": 49038,
+ "raine": 6871,
+ "rained": 32310,
+ "rainf": 15024,
+ "rainfall": 15350,
+ "rainforest": 22823,
+ "rainier": 37850,
+ "raining": 13964,
+ "rains": 14272,
+ "rainy": 10222,
+ "rais": 14729,
+ "raise": 24249,
+ "raise": 5078,
+ "raised": 6027,
+ "raiser": 33555,
+ "raises": 13297,
+ "raisethe": 47109,
+ "raisin": 36864,
+ "raising": 6883,
+ "raj": 5958,
+ "raj": 10813,
+ "raja": 46069,
+ "raja": 19150,
+ "rajan": 46595,
+ "rajas": 16185,
+ "rajasthan": 18017,
+ "raje": 21899,
+ "rajesh": 43602,
+ "raji": 27569,
+ "rajini": 29600,
+ "rajini": 40622,
+ "rajinikanth": 32922,
+ "rajiv": 40197,
+ "rajkumar": 49304,
+ "rajput": 47572,
+ "raju": 47029,
+ "rak": 13523,
+ "rak": 26287,
+ "rake": 26825,
+ "rake": 32712,
+ "rakesh": 41083,
+ "ral": 8062,
+ "ral": 1406,
+ "rale": 14192,
+ "raleigh": 18207,
+ "rall": 23249,
+ "rallies": 25230,
+ "rally": 18882,
+ "rally": 5041,
+ "rallying": 36836,
+ "ralph": 25290,
+ "ralph": 12234,
+ "ram": 1976,
+ "ram": 2007,
+ "rama": 22112,
+ "ramad": 12736,
+ "ramadan": 15547,
+ "ramadhan": 47415,
+ "raman": 39816,
+ "ramapho": 43963,
+ "ramaphosa": 44993,
+ "ramatta": 49112,
+ "rambo": 41855,
+ "ramcharan": 45275,
+ "rame": 47745,
+ "ramen": 18892,
+ "ramesh": 48640,
+ "ramesh": 40186,
+ "rami": 43016,
+ "ramirez": 23877,
+ "ramon": 27958,
+ "ramone": 47201,
+ "ramos": 21046,
+ "ramp": 14271,
+ "rampage": 32077,
+ "rampant": 41985,
+ "ramps": 35257,
+ "rams": 10292,
+ "ramsay": 26259,
+ "ramsey": 19215,
+ "ran": 1433,
+ "ran": 4031,
+ "rana": 22143,
+ "ranbir": 40881,
+ "rance": 29034,
+ "ranch": 43955,
+ "ranch": 10659,
+ "rancho": 26258,
+ "rand": 5628,
+ "rand": 18718,
+ "randall": 23639,
+ "rande": 21469,
+ "randolph": 29899,
+ "random": 11396,
+ "random": 6160,
+ "randomly": 17272,
+ "rands": 39153,
+ "randy": 29479,
+ "randy": 13279,
+ "rane": 28852,
+ "rang": 4043,
+ "rang": 24377,
+ "range": 13627,
+ "range": 3818,
+ "ranger": 31472,
+ "ranger": 13593,
+ "rangers": 7664,
+ "ranges": 25685,
+ "ranging": 25946,
+ "rani": 29264,
+ "rani": 22631,
+ "rank": 11501,
+ "ranked": 8307,
+ "rankin": 37539,
+ "ranking": 12347,
+ "rankings": 12596,
+ "ranks": 14469,
+ "rano": 18608,
+ "rans": 46259,
+ "ransom": 28523,
+ "ransom": 34646,
+ "ransomware": 33815,
+ "rant": 46467,
+ "rant": 9819,
+ "rants": 34014,
+ "ranveer": 32402,
+ "ranveer": 41482,
+ "ranveerofficial": 42116,
+ "rao": 16913,
+ "rap": 7773,
+ "rap": 7348,
+ "rape": 46099,
+ "rape": 10070,
+ "raped": 23700,
+ "rapha": 22754,
+ "raphael": 30091,
+ "rapi": 8610,
+ "rapid": 47697,
+ "rapid": 12205,
+ "rapidly": 16710,
+ "rapids": 18848,
+ "raping": 44926,
+ "rapist": 33360,
+ "rapp": 19283,
+ "rapper": 11860,
+ "rappers": 30315,
+ "rapping": 42864,
+ "raps": 37887,
+ "raptor": 26762,
+ "raptors": 17035,
+ "raq": 39787,
+ "raq": 43312,
+ "raqqa": 47074,
+ "raquel": 44338,
+ "rar": 26819,
+ "rar": 24605,
+ "rard": 21012,
+ "rare": 18992,
+ "rare": 3865,
+ "rarely": 17315,
+ "rarest": 43237,
+ "rarity": 45862,
+ "ras": 23492,
+ "ras": 8224,
+ "rasc": 30085,
+ "rascal": 43481,
+ "rash": 14917,
+ "rash": 30608,
+ "rashad": 46527,
+ "rasheed": 41638,
+ "rashi": 19426,
+ "rashid": 26757,
+ "rasp": 10487,
+ "raspberries": 37742,
+ "raspberry": 40162,
+ "raspberry": 13615,
+ "raspberrypi": 43934,
+ "rass": 45654,
+ "rasta": 47002,
+ "rat": 3806,
+ "rat": 8985,
+ "rata": 28568,
+ "ratchet": 25078,
+ "rate": 5068,
+ "rated": 8183,
+ "rates": 6864,
+ "rath": 18268,
+ "rath": 39772,
+ "rather": 5252,
+ "rati": 11486,
+ "rating": 10567,
+ "ratings": 14176,
+ "ratio": 15893,
+ "ration": 27002,
+ "ration": 35662,
+ "rational": 33086,
+ "ratna": 49078,
+ "ratri": 32288,
+ "rats": 19043,
+ "ratt": 20737,
+ "ratt": 34785,
+ "rattle": 40824,
+ "rattle": 41839,
+ "rau": 27744,
+ "raul": 30218,
+ "raun": 41169,
+ "rav": 14367,
+ "rav": 23606,
+ "rave": 38784,
+ "rave": 17601,
+ "ravel": 27927,
+ "raven": 10269,
+ "raven": 16803,
+ "ravens": 17946,
+ "ravi": 22947,
+ "ravi": 19538,
+ "ravin": 39099,
+ "raving": 45807,
+ "raviol": 41104,
+ "ravioli": 43460,
+ "raw": 10166,
+ "raw": 6323,
+ "rawlings": 40662,
+ "rax": 38520,
+ "ray": 5312,
+ "ray": 3077,
+ "raya": 29991,
+ "raymond": 16683,
+ "rayn": 47852,
+ "rayon": 47900,
+ "rays": 11064,
+ "raz": 9700,
+ "raz": 19087,
+ "raza": 37724,
+ "razer": 33832,
+ "razor": 24934,
+ "razor": 21300,
+ "razz": 43769,
+ "rb": 12740,
+ "rb": 7477,
+ "rbc": 37500,
+ "rbi": 15687,
+ "rbs": 29102,
+ "rc": 7575,
+ "rc": 7457,
+ "rca": 33942,
+ "rcb": 45240,
+ "rcmp": 31489,
+ "rcn": 49370,
+ "rctid": 49223,
+ "rd": 13501,
+ "rd": 1973,
+ "rda": 45755,
+ "rdr": 44364,
+ "rds": 32378,
+ "re": 515,
+ "re": 810,
+ "rea": 11521,
+ "reach": 4483,
+ "reach": 4279,
+ "reached": 6878,
+ "reaches": 14462,
+ "reaching": 11358,
+ "react": 36566,
+ "react": 15065,
+ "reacted": 42515,
+ "reacting": 40595,
+ "reaction": 7189,
+ "reactions": 18438,
+ "reactive": 42072,
+ "reactjs": 46173,
+ "reactor": 32037,
+ "reacts": 23115,
+ "read": 933,
+ "read": 1199,
+ "reader": 9884,
+ "readers": 10335,
+ "readiness": 28131,
+ "reading": 17556,
+ "reading": 2337,
+ "readingfc": 47428,
+ "readings": 23361,
+ "reads": 6597,
+ "ready": 17351,
+ "ready": 1112,
+ "reagan": 17767,
+ "real": 2017,
+ "real": 1532,
+ "realdonaldtrump": 7025,
+ "reale": 5930,
+ "realest": 45855,
+ "realestate": 32937,
+ "realestate": 6569,
+ "reali": 4185,
+ "realis": 38114,
+ "realise": 14773,
+ "realised": 17945,
+ "realising": 39537,
+ "realism": 20024,
+ "realist": 30248,
+ "realistic": 16157,
+ "realities": 32443,
+ "reality": 46802,
+ "reality": 5004,
+ "realization": 40402,
+ "realize": 7538,
+ "realized": 10489,
+ "realizes": 42918,
+ "realizing": 23284,
+ "reall": 39686,
+ "really": 43249,
+ "really": 1414,
+ "realm": 23083,
+ "realmadrid": 27866,
+ "realms": 43033,
+ "realness": 46761,
+ "realtime": 44002,
+ "realtime": 38203,
+ "realtor": 18038,
+ "realtors": 31759,
+ "realty": 20471,
+ "ream": 37242,
+ "ream": 15219,
+ "rean": 48477,
+ "reap": 31334,
+ "reaper": 29922,
+ "rear": 39652,
+ "rear": 10223,
+ "reas": 9121,
+ "reason": 12882,
+ "reason": 3893,
+ "reasonable": 18558,
+ "reasonably": 38589,
+ "reasoning": 30341,
+ "reasons": 5686,
+ "reau": 32398,
+ "reb": 12370,
+ "reb": 18796,
+ "reba": 48543,
+ "rebate": 43817,
+ "rebe": 25227,
+ "rebec": 10774,
+ "rebecca": 12892,
+ "rebel": 8185,
+ "rebel": 12248,
+ "rebellion": 22170,
+ "rebels": 13623,
+ "rebirth": 33303,
+ "reboot": 22385,
+ "reborn": 30229,
+ "reboun": 43381,
+ "rebound": 31280,
+ "rebounds": 19190,
+ "rebs": 28164,
+ "rebu": 43162,
+ "rebuild": 20022,
+ "rebuilding": 30880,
+ "rebuilt": 33137,
+ "rec": 1020,
+ "rec": 11243,
+ "recall": 15151,
+ "recalled": 32142,
+ "recalling": 47855,
+ "recalls": 24740,
+ "recap": 29816,
+ "recap": 8337,
+ "recaps": 47997,
+ "recard": 35536,
+ "rece": 1890,
+ "recei": 2148,
+ "receip": 38503,
+ "receipt": 30479,
+ "receipts": 41181,
+ "receive": 4800,
+ "received": 4178,
+ "receiver": 17659,
+ "receivers": 45294,
+ "receives": 10027,
+ "receiving": 7252,
+ "recent": 3969,
+ "recently": 4482,
+ "recep": 17450,
+ "reception": 8364,
+ "receptions": 46881,
+ "receptor": 41835,
+ "recess": 38182,
+ "recession": 27176,
+ "recharge": 29396,
+ "rechargeable": 37516,
+ "reci": 2037,
+ "recipe": 28923,
+ "recipe": 4614,
+ "recipeoftheday": 38727,
+ "recipes": 9243,
+ "recipi": 10136,
+ "recipient": 13703,
+ "recipients": 18940,
+ "recipro": 41789,
+ "recital": 23457,
+ "recite": 48824,
+ "reck": 11715,
+ "reckless": 26284,
+ "reckon": 23854,
+ "recl": 42277,
+ "reclaim": 35969,
+ "reclaimed": 32648,
+ "reco": 2535,
+ "reco": 46038,
+ "recogn": 6343,
+ "recogni": 5329,
+ "recognise": 19824,
+ "recognised": 20986,
+ "recognising": 48423,
+ "recognition": 9415,
+ "recognizable": 47240,
+ "recognize": 10905,
+ "recognized": 9929,
+ "recognizes": 26909,
+ "recognizing": 19666,
+ "recomm": 4540,
+ "recommend": 11628,
+ "recommend": 8942,
+ "recommendation": 20118,
+ "recommendations": 16516,
+ "recommended": 11100,
+ "recommending": 44301,
+ "recommends": 22940,
+ "recon": 15371,
+ "recon": 28996,
+ "reconciliation": 26451,
+ "reconstruction": 24955,
+ "recor": 1723,
+ "record": 21328,
+ "record": 2717,
+ "recorded": 9392,
+ "recorder": 26747,
+ "recording": 48237,
+ "recording": 6942,
+ "recordings": 19715,
+ "records": 4529,
+ "recover": 16785,
+ "recovered": 16444,
+ "recovering": 19005,
+ "recovers": 47935,
+ "recovery": 6591,
+ "recre": 22148,
+ "recreate": 29775,
+ "recreated": 40888,
+ "recreating": 48224,
+ "recreation": 17331,
+ "recreational": 24329,
+ "recru": 4745,
+ "recruit": 9011,
+ "recruit": 15585,
+ "recruited": 36518,
+ "recruiter": 43120,
+ "recruiters": 46542,
+ "recruiting": 10533,
+ "recruitment": 10541,
+ "recruits": 22647,
+ "recs": 33069,
+ "rectan": 43041,
+ "rectangular": 43321,
+ "rector": 41585,
+ "recu": 26798,
+ "recur": 19983,
+ "recurring": 35912,
+ "recy": 6790,
+ "recycla": 40659,
+ "recyclable": 48907,
+ "recycle": 19366,
+ "recycled": 16829,
+ "recycling": 12566,
+ "red": 1893,
+ "red": 736,
+ "redbubble": 46137,
+ "redbull": 29483,
+ "redbull": 29219,
+ "redcarpet": 32259,
+ "redcross": 30659,
+ "redd": 22149,
+ "redd": 40618,
+ "redding": 41061,
+ "reddish": 43383,
+ "reddit": 15226,
+ "reddy": 23028,
+ "rede": 10913,
+ "redeem": 37449,
+ "redefining": 46352,
+ "redemption": 20233,
+ "redesign": 24188,
+ "redesigned": 33111,
+ "redevelopment": 30322,
+ "redhead": 36267,
+ "redi": 7976,
+ "redman": 44753,
+ "redmond": 39627,
+ "rednation": 28180,
+ "rednationrising": 28262,
+ "redneck": 39105,
+ "redness": 22626,
+ "redo": 42524,
+ "redon": 48506,
+ "redro": 37722,
+ "reds": 11221,
+ "redskins": 19023,
+ "redsox": 19144,
+ "reduc": 5015,
+ "reduce": 6604,
+ "reduced": 10821,
+ "reduces": 20539,
+ "reducing": 13836,
+ "reduction": 12219,
+ "reductions": 48263,
+ "redux": 43014,
+ "redvelvet": 41845,
+ "redwings": 31058,
+ "redwood": 31748,
+ "ree": 9282,
+ "ree": 5813,
+ "reebok": 26734,
+ "reece": 30457,
+ "reed": 26209,
+ "reed": 10435,
+ "reedus": 32865,
+ "reef": 46557,
+ "reef": 15624,
+ "reefs": 34459,
+ "reel": 34467,
+ "reel": 17166,
+ "reels": 48127,
+ "reem": 48891,
+ "reen": 21638,
+ "reen": 23679,
+ "rees": 18314,
+ "reese": 20929,
+ "reeves": 23060,
+ "ref": 4067,
+ "ref": 9591,
+ "refe": 5624,
+ "refer": 18425,
+ "refer": 22325,
+ "referee": 20398,
+ "referees": 45583,
+ "referen": 13535,
+ "reference": 10214,
+ "references": 24009,
+ "referendum": 16732,
+ "referr": 47784,
+ "referral": 30219,
+ "referred": 22969,
+ "referring": 29797,
+ "refers": 30069,
+ "refill": 37859,
+ "refin": 13455,
+ "refined": 26098,
+ "refinery": 31393,
+ "refining": 48406,
+ "reflec": 4608,
+ "reflect": 13373,
+ "reflected": 28732,
+ "reflecting": 19700,
+ "reflection": 11884,
+ "reflections": 16647,
+ "reflective": 27008,
+ "reflects": 15821,
+ "reflex": 45756,
+ "reflex": 36050,
+ "reform": 45678,
+ "reform": 8875,
+ "reformation": 45119,
+ "reformed": 40880,
+ "reforms": 19274,
+ "refr": 34850,
+ "refre": 11995,
+ "refresh": 17836,
+ "refresh": 23288,
+ "refreshed": 35925,
+ "refresher": 41481,
+ "refreshing": 14159,
+ "refreshments": 31127,
+ "refriger": 21076,
+ "refrigerator": 36662,
+ "refs": 35595,
+ "refu": 3545,
+ "refuge": 5638,
+ "refuge": 17432,
+ "refugee": 11556,
+ "refugees": 42687,
+ "refugees": 8316,
+ "refund": 28899,
+ "refur": 15519,
+ "refurbi": 18259,
+ "refurbished": 26190,
+ "refurbishment": 35803,
+ "refusal": 46547,
+ "refuse": 16412,
+ "refused": 17190,
+ "refuses": 20085,
+ "refusing": 26704,
+ "reg": 5472,
+ "reg": 12353,
+ "regain": 37510,
+ "regal": 31512,
+ "regal": 25028,
+ "regan": 34062,
+ "regar": 5881,
+ "regard": 21801,
+ "regarded": 32017,
+ "regarding": 8493,
+ "regardless": 17220,
+ "regards": 23079,
+ "regatta": 26316,
+ "regen": 46545,
+ "regency": 29341,
+ "regeneration": 29257,
+ "regent": 30455,
+ "regents": 46710,
+ "regg": 12757,
+ "reggae": 37821,
+ "reggae": 15214,
+ "reggie": 21872,
+ "regi": 1608,
+ "regime": 11378,
+ "regiment": 18603,
+ "regin": 23287,
+ "regina": 16841,
+ "region": 16542,
+ "region": 4341,
+ "regional": 5552,
+ "regionals": 26043,
+ "regions": 14530,
+ "regis": 28094,
+ "register": 3967,
+ "registered": 10254,
+ "registering": 33510,
+ "registr": 29193,
+ "registration": 7302,
+ "registrations": 38423,
+ "registry": 30020,
+ "rego": 47351,
+ "regram": 30329,
+ "regrann": 48802,
+ "regre": 8627,
+ "regression": 43733,
+ "regret": 14374,
+ "regrets": 23231,
+ "regu": 3411,
+ "regui": 46722,
+ "regul": 11847,
+ "regular": 14882,
+ "regular": 6307,
+ "regularly": 17263,
+ "regulat": 14575,
+ "regulate": 33494,
+ "regulated": 31384,
+ "regulating": 48156,
+ "regulation": 14267,
+ "regulations": 16654,
+ "regulator": 30364,
+ "regulators": 35837,
+ "regulatory": 17717,
+ "reh": 21492,
+ "reha": 10193,
+ "rehab": 16973,
+ "rehabil": 17930,
+ "rehabilitation": 21042,
+ "rehear": 7273,
+ "rehearsal": 11482,
+ "rehearsals": 17977,
+ "rehearsing": 23125,
+ "rehman": 39206,
+ "rei": 15343,
+ "rei": 26033,
+ "reic": 41230,
+ "reich": 48589,
+ "reich": 28929,
+ "reid": 45125,
+ "reid": 11744,
+ "reig": 13092,
+ "reign": 41419,
+ "reign": 14827,
+ "reigning": 28409,
+ "reigns": 21217,
+ "reiki": 46960,
+ "reilly": 28120,
+ "reim": 35421,
+ "reimagined": 46799,
+ "reimbur": 39857,
+ "rein": 9240,
+ "rein": 45009,
+ "reina": 43847,
+ "reinde": 23810,
+ "reindeer": 25072,
+ "reinfor": 48161,
+ "reinforced": 41909,
+ "reinst": 33969,
+ "reinvent": 38171,
+ "reissue": 34042,
+ "reiter": 35394,
+ "rejec": 9958,
+ "reject": 22435,
+ "rejected": 17505,
+ "rejection": 32264,
+ "rejects": 23155,
+ "rejo": 20150,
+ "rejoice": 24712,
+ "rejuven": 26332,
+ "rek": 47542,
+ "rek": 19201,
+ "rel": 1825,
+ "rel": 5233,
+ "rela": 4362,
+ "reland": 15220,
+ "relat": 27192,
+ "relatable": 31010,
+ "relate": 17520,
+ "related": 5880,
+ "relates": 36064,
+ "relating": 27373,
+ "relation": 4561,
+ "relation": 16207,
+ "relations": 10100,
+ "relationship": 47239,
+ "relationship": 5837,
+ "relationships": 10610,
+ "relative": 17265,
+ "relatively": 18351,
+ "relatives": 21981,
+ "relax": 6777,
+ "relax": 9035,
+ "relaxation": 22194,
+ "relaxed": 18999,
+ "relaxing": 10256,
+ "relay": 12403,
+ "relays": 28404,
+ "rele": 1602,
+ "release": 29100,
+ "release": 2706,
+ "released": 3410,
+ "releases": 7393,
+ "releasethe": 44008,
+ "releasing": 10321,
+ "releg": 23378,
+ "relegated": 45884,
+ "relegation": 35040,
+ "relent": 22213,
+ "relentless": 27207,
+ "relessly": 33927,
+ "relev": 9349,
+ "relevance": 31400,
+ "relevant": 10568,
+ "reli": 2674,
+ "reliability": 27220,
+ "reliable": 13714,
+ "reliance": 27727,
+ "relic": 27802,
+ "relics": 43208,
+ "relief": 7518,
+ "relies": 41579,
+ "relieve": 28623,
+ "relieved": 36597,
+ "religi": 4940,
+ "religion": 8803,
+ "religions": 31189,
+ "religious": 8289,
+ "relish": 35550,
+ "relive": 23939,
+ "reliving": 47558,
+ "rell": 28802,
+ "rell": 7127,
+ "rella": 9952,
+ "relle": 31390,
+ "reloaded": 38908,
+ "relocated": 46791,
+ "relocation": 39198,
+ "rels": 23320,
+ "relu": 32058,
+ "reluct": 32549,
+ "reluctant": 45552,
+ "rely": 4158,
+ "relying": 42168,
+ "rem": 15098,
+ "rem": 21637,
+ "rema": 4569,
+ "remain": 29144,
+ "remain": 6415,
+ "remainder": 41672,
+ "remained": 23714,
+ "remaining": 11392,
+ "remains": 6807,
+ "remake": 16234,
+ "remark": 11136,
+ "remarkable": 12404,
+ "remarkably": 39087,
+ "remarks": 15001,
+ "remastered": 24932,
+ "rematch": 26473,
+ "rembrandt": 45972,
+ "reme": 20071,
+ "remedi": 18442,
+ "remedies": 25581,
+ "remedy": 25794,
+ "remem": 7966,
+ "rememb": 7062,
+ "remember": 22045,
+ "remember": 2195,
+ "remembered": 11763,
+ "remembering": 8135,
+ "remembers": 12551,
+ "remembrance": 40321,
+ "remembrance": 15860,
+ "remembranceday": 48333,
+ "rement": 7173,
+ "rements": 12667,
+ "remi": 41693,
+ "remin": 3216,
+ "remind": 9868,
+ "reminded": 12309,
+ "reminder": 5565,
+ "reminders": 34121,
+ "reminding": 19976,
+ "reminds": 8303,
+ "remington": 43527,
+ "reminis": 17723,
+ "reminiscent": 41704,
+ "reminiscing": 32552,
+ "remix": 8519,
+ "remixes": 31011,
+ "remn": 29127,
+ "remnants": 39032,
+ "remo": 4064,
+ "remo": 33259,
+ "remodel": 34159,
+ "remodel": 37495,
+ "remodeling": 41432,
+ "remote": 47163,
+ "remote": 9687,
+ "remotely": 32375,
+ "removable": 44095,
+ "removal": 13679,
+ "remove": 9709,
+ "removed": 10289,
+ "remover": 44267,
+ "removes": 29018,
+ "removing": 18504,
+ "remy": 30434,
+ "ren": 737,
+ "ren": 2596,
+ "rena": 12591,
+ "renais": 15409,
+ "renaissance": 16007,
+ "renal": 36096,
+ "renamed": 31535,
+ "renault": 17600,
+ "rence": 19245,
+ "rence": 1553,
+ "rences": 8545,
+ "rend": 33932,
+ "rend": 22851,
+ "render": 39752,
+ "render": 13024,
+ "rendered": 23652,
+ "rendering": 21339,
+ "renders": 39419,
+ "rendez": 43293,
+ "rendezvous": 45644,
+ "rendition": 28891,
+ "rendon": 46272,
+ "rendous": 49403,
+ "rends": 38842,
+ "rene": 15438,
+ "rene": 12597,
+ "renee": 23480,
+ "reneg": 29909,
+ "renegade": 41229,
+ "renergy": 37151,
+ "renew": 6645,
+ "renew": 22015,
+ "renewable": 31269,
+ "renewable": 15941,
+ "renewableenergy": 33357,
+ "renewables": 21619,
+ "renewal": 21270,
+ "renewed": 20524,
+ "renfre": 45043,
+ "reng": 36795,
+ "reno": 11520,
+ "reno": 12831,
+ "renov": 9984,
+ "renovated": 23839,
+ "renovation": 17121,
+ "renovations": 31311,
+ "renowned": 14727,
+ "rens": 18183,
+ "renshaw": 44445,
+ "rent": 17377,
+ "rent": 1609,
+ "rental": 12193,
+ "rentals": 24105,
+ "rented": 35932,
+ "rential": 31692,
+ "renting": 37662,
+ "rently": 2615,
+ "rents": 31109,
+ "reo": 15963,
+ "reo": 26854,
+ "reon": 15761,
+ "reopen": 26883,
+ "reopened": 32868,
+ "reopening": 36663,
+ "reopens": 40644,
+ "rep": 4229,
+ "rep": 6487,
+ "repair": 8419,
+ "repaired": 32953,
+ "repairing": 38534,
+ "repairs": 16297,
+ "repar": 34065,
+ "repe": 5785,
+ "repeal": 42622,
+ "repeal": 23938,
+ "repeat": 10192,
+ "repeated": 27904,
+ "repeatedly": 26630,
+ "repeating": 33834,
+ "repeats": 39158,
+ "repell": 46235,
+ "repent": 47261,
+ "reper": 29085,
+ "repet": 38533,
+ "repl": 13047,
+ "replac": 6069,
+ "replace": 9466,
+ "replaceable": 47762,
+ "replaced": 13200,
+ "replacement": 10835,
+ "replaces": 27781,
+ "replacing": 18647,
+ "replay": 16875,
+ "repleni": 44839,
+ "replic": 21651,
+ "replica": 18125,
+ "replied": 24238,
+ "replies": 18808,
+ "reply": 8965,
+ "replying": 47599,
+ "repor": 2628,
+ "report": 2417,
+ "reported": 7598,
+ "reportedly": 10953,
+ "reporter": 11019,
+ "reporters": 18454,
+ "reporting": 9218,
+ "reports": 4908,
+ "reposit": 41276,
+ "repository": 46977,
+ "repost": 33147,
+ "repost": 7217,
+ "repostapp": 38388,
+ "reposting": 20223,
+ "reppin": 19163,
+ "repping": 22574,
+ "repre": 3397,
+ "represent": 8293,
+ "represent": 8406,
+ "representation": 13520,
+ "representative": 13175,
+ "representatives": 15591,
+ "represented": 12299,
+ "representing": 7561,
+ "represents": 14433,
+ "repri": 31854,
+ "reproduction": 35714,
+ "reproductive": 25522,
+ "reps": 14265,
+ "reptile": 36938,
+ "reptiles": 38679,
+ "republic": 6376,
+ "republic": 7185,
+ "republican": 9842,
+ "republicans": 12384,
+ "repur": 41852,
+ "req": 42411,
+ "requ": 10664,
+ "reque": 9539,
+ "request": 7813,
+ "requested": 16199,
+ "requesting": 33245,
+ "requests": 17087,
+ "requi": 4863,
+ "requiem": 40316,
+ "require": 14437,
+ "required": 8500,
+ "requirement": 27146,
+ "requirements": 12860,
+ "requires": 13396,
+ "requiring": 33425,
+ "requis": 42602,
+ "rer": 41295,
+ "rer": 3407,
+ "rera": 14301,
+ "rero": 21860,
+ "rers": 18869,
+ "res": 4466,
+ "res": 934,
+ "resc": 3956,
+ "rescheduled": 43553,
+ "rescu": 8618,
+ "rescue": 28567,
+ "rescue": 5718,
+ "rescued": 11919,
+ "rescues": 32439,
+ "rescuing": 43770,
+ "rese": 13000,
+ "resear": 6090,
+ "research": 25694,
+ "research": 2379,
+ "researched": 42733,
+ "researcher": 18334,
+ "researchers": 9522,
+ "researching": 24544,
+ "reseller": 35391,
+ "resemb": 16916,
+ "resemblance": 26856,
+ "resemble": 37230,
+ "resembles": 35417,
+ "reser": 16420,
+ "reserv": 11906,
+ "reservation": 20289,
+ "reservations": 19307,
+ "reserve": 6911,
+ "reserved": 19796,
+ "reserves": 19705,
+ "reservoir": 20574,
+ "reset": 26250,
+ "resh": 47432,
+ "reshi": 39435,
+ "resi": 2152,
+ "residen": 22311,
+ "residence": 11672,
+ "residences": 38855,
+ "residency": 18545,
+ "resident": 9016,
+ "residente": 44637,
+ "residentevil": 48393,
+ "residential": 11002,
+ "residents": 6008,
+ "resign": 23584,
+ "resignation": 24779,
+ "resigned": 31014,
+ "resigns": 29738,
+ "resil": 10932,
+ "resili": 39212,
+ "resilience": 15271,
+ "resilient": 24694,
+ "resin": 24156,
+ "resist": 37345,
+ "resist": 9587,
+ "resistance": 7392,
+ "resistant": 17542,
+ "resisting": 43679,
+ "resolution": 9977,
+ "resolutions": 26816,
+ "resolve": 20787,
+ "resolved": 28807,
+ "reson": 18092,
+ "resonance": 42310,
+ "resort": 6594,
+ "resorts": 18839,
+ "resource": 43729,
+ "resource": 9760,
+ "resources": 6723,
+ "respec": 7466,
+ "respect": 31411,
+ "respect": 4916,
+ "respected": 19126,
+ "respectful": 24379,
+ "respecting": 36172,
+ "respective": 25817,
+ "respectively": 28794,
+ "respects": 23553,
+ "respir": 20771,
+ "respiratory": 24483,
+ "respon": 2421,
+ "respond": 12355,
+ "responded": 21121,
+ "respondents": 49253,
+ "responders": 25155,
+ "responding": 18037,
+ "responds": 17436,
+ "response": 5399,
+ "responses": 19006,
+ "responsi": 5490,
+ "responsibilities": 30375,
+ "responsibility": 11272,
+ "responsible": 8936,
+ "responsibly": 33675,
+ "responsive": 21544,
+ "ress": 34651,
+ "ress": 13629,
+ "resso": 15133,
+ "rest": 10974,
+ "rest": 2539,
+ "restart": 37378,
+ "restaur": 3775,
+ "restaurant": 41930,
+ "restaurant": 4489,
+ "restaurants": 11714,
+ "rested": 46020,
+ "resting": 18044,
+ "restless": 36724,
+ "restling": 30076,
+ "resto": 11118,
+ "resto": 41666,
+ "restock": 34060,
+ "restocked": 36966,
+ "restor": 8984,
+ "restoration": 11989,
+ "restorative": 46509,
+ "restore": 14008,
+ "restored": 14238,
+ "restoring": 24406,
+ "restra": 25424,
+ "restric": 11036,
+ "restricted": 27197,
+ "restriction": 44282,
+ "restrictions": 19884,
+ "restroom": 43423,
+ "restructuring": 43260,
+ "rests": 33775,
+ "resu": 10095,
+ "resul": 2655,
+ "result": 5659,
+ "resulted": 26449,
+ "resulting": 24581,
+ "results": 3790,
+ "resume": 15077,
+ "resumes": 30268,
+ "resur": 14865,
+ "resurg": 45962,
+ "resurgence": 47692,
+ "resurrec": 18487,
+ "resurrection": 25811,
+ "resusc": 47523,
+ "ret": 20500,
+ "ret": 10048,
+ "reta": 20153,
+ "retail": 14910,
+ "retail": 6455,
+ "retailer": 22549,
+ "retailers": 19418,
+ "retain": 24430,
+ "retained": 42737,
+ "retaining": 35571,
+ "retains": 42583,
+ "retali": 33101,
+ "retar": 29964,
+ "retarded": 44111,
+ "retention": 26247,
+ "rethink": 29078,
+ "rethinking": 42951,
+ "reti": 4721,
+ "retin": 31270,
+ "retina": 36919,
+ "retire": 18846,
+ "retired": 11477,
+ "retirement": 9205,
+ "retires": 29060,
+ "retiring": 21200,
+ "retrac": 32735,
+ "retreat": 11210,
+ "retri": 16918,
+ "retriever": 28394,
+ "retro": 6535,
+ "retro": 7755,
+ "retrogamer": 47220,
+ "retrogaming": 11316,
+ "retrospective": 27105,
+ "rett": 41082,
+ "rett": 8425,
+ "rette": 33066,
+ "return": 43042,
+ "return": 3458,
+ "returned": 10476,
+ "returning": 9290,
+ "returns": 5020,
+ "retwee": 48190,
+ "retweet": 3195,
+ "retweeted": 12705,
+ "retweeting": 32345,
+ "retweets": 10160,
+ "rety": 41550,
+ "reu": 20255,
+ "reu": 40371,
+ "reuben": 40450,
+ "reunion": 10247,
+ "reunite": 26179,
+ "reunited": 13516,
+ "reusable": 30395,
+ "reuse": 26535,
+ "reut": 15210,
+ "reuters": 15569,
+ "rev": 8424,
+ "rev": 11789,
+ "revamp": 29819,
+ "revamped": 36420,
+ "revan": 45277,
+ "reve": 3115,
+ "reveal": 8052,
+ "revealed": 7171,
+ "revealing": 21321,
+ "reveals": 6621,
+ "revel": 14133,
+ "revelation": 24053,
+ "revelations": 36163,
+ "reven": 10171,
+ "revenge": 12717,
+ "revenue": 10637,
+ "revenues": 33348,
+ "rever": 14829,
+ "rever": 41913,
+ "revere": 44187,
+ "reverend": 34407,
+ "revers": 20726,
+ "reversal": 33367,
+ "reverse": 12812,
+ "reversed": 42485,
+ "reversi": 31601,
+ "reversible": 34212,
+ "revi": 8317,
+ "review": 2268,
+ "reviewed": 16678,
+ "reviewer": 36409,
+ "reviewers": 48195,
+ "reviewing": 20458,
+ "reviews": 7227,
+ "revise": 46801,
+ "revised": 22806,
+ "revising": 46882,
+ "revision": 20335,
+ "revisit": 26568,
+ "revisited": 34302,
+ "revisiting": 33144,
+ "revit": 26367,
+ "revitalization": 46923,
+ "revival": 14142,
+ "revive": 26450,
+ "revived": 42912,
+ "revo": 28660,
+ "revol": 13447,
+ "revolt": 31697,
+ "revolu": 4900,
+ "revolution": 17699,
+ "revolution": 6644,
+ "revolutionary": 14734,
+ "revolver": 38747,
+ "revolving": 47230,
+ "revs": 49286,
+ "revue": 43428,
+ "rew": 37564,
+ "rewar": 15857,
+ "reward": 11223,
+ "rewarded": 27163,
+ "rewarding": 23351,
+ "rewards": 15235,
+ "rewatch": 35610,
+ "rewatching": 41287,
+ "rewind": 26867,
+ "rewrite": 45218,
+ "rex": 13002,
+ "rex": 10904,
+ "rexperience": 33924,
+ "rey": 9681,
+ "rey": 4517,
+ "reyes": 18255,
+ "reykja": 47571,
+ "reyn": 11998,
+ "reynolds": 14309,
+ "reys": 48284,
+ "rez": 27597,
+ "rez": 15192,
+ "reza": 35888,
+ "rf": 35529,
+ "rf": 16368,
+ "rfc": 19003,
+ "rfid": 40204,
+ "rg": 33055,
+ "rg": 14897,
+ "rgb": 36128,
+ "rgv": 33685,
+ "rh": 8745,
+ "rh": 22404,
+ "rha": 19473,
+ "rhapso": 32532,
+ "rhapsody": 35774,
+ "rhe": 9186,
+ "rhea": 28612,
+ "rhetor": 24359,
+ "rhetoric": 29985,
+ "rhett": 42984,
+ "rheu": 42953,
+ "rhi": 21212,
+ "rhin": 12269,
+ "rhine": 22863,
+ "rhine": 44833,
+ "rhinestone": 30450,
+ "rhino": 41744,
+ "rhino": 20056,
+ "rhinos": 30671,
+ "rho": 7637,
+ "rhode": 39302,
+ "rhode": 27907,
+ "rhodes": 17785,
+ "rhon": 25882,
+ "rhonda": 46100,
+ "rhp": 27199,
+ "rhs": 24551,
+ "rhu": 23897,
+ "rhubarb": 30213,
+ "rhy": 7740,
+ "rhyme": 37356,
+ "rhymes": 33143,
+ "rhys": 28647,
+ "rhyth": 27069,
+ "rhythm": 16172,
+ "rhythmic": 46386,
+ "rhythms": 40872,
+ "ri": 553,
+ "ri": 2574,
+ "ria": 3650,
+ "rial": 15200,
+ "rian": 7788,
+ "rib": 44634,
+ "rib": 18298,
+ "riba": 44992,
+ "ribb": 10081,
+ "ribbon": 12114,
+ "ribbons": 35271,
+ "ribe": 46115,
+ "ribs": 17519,
+ "ric": 920,
+ "ric": 4798,
+ "rica": 14230,
+ "rical": 18109,
+ "rican": 30958,
+ "ricardo": 23140,
+ "ricci": 35783,
+ "ricciardo": 49282,
+ "rice": 36362,
+ "rice": 4741,
+ "rich": 5223,
+ "rich": 4021,
+ "richar": 9350,
+ "richard": 9080,
+ "richard": 4470,
+ "richards": 11372,
+ "richardson": 15984,
+ "riche": 23286,
+ "richer": 34138,
+ "riches": 37093,
+ "richest": 25572,
+ "richi": 38934,
+ "richie": 19797,
+ "richland": 43079,
+ "richmond": 34143,
+ "richmond": 11292,
+ "richter": 37591,
+ "rick": 6237,
+ "rick": 3064,
+ "ricket": 46161,
+ "ricket": 23671,
+ "ricks": 23111,
+ "ricky": 19188,
+ "ricky": 12814,
+ "rico": 37962,
+ "rico": 11362,
+ "ricotta": 38473,
+ "rics": 7353,
+ "ricul": 6980,
+ "rid": 18103,
+ "rid": 9874,
+ "ridd": 21990,
+ "ridden": 32025,
+ "riddle": 31839,
+ "ride": 15816,
+ "ride": 2994,
+ "rider": 31056,
+ "rider": 9707,
+ "riders": 10826,
+ "rides": 11308,
+ "ridg": 42646,
+ "ridge": 16580,
+ "ridge": 6352,
+ "ridic": 9624,
+ "ridiculous": 12659,
+ "ridiculously": 25661,
+ "ridin": 47869,
+ "riding": 6765,
+ "ridley": 27883,
+ "rie": 14824,
+ "rie": 5322,
+ "ried": 7552,
+ "riel": 26696,
+ "rien": 35237,
+ "rier": 40714,
+ "rier": 13336,
+ "ries": 28179,
+ "ries": 3059,
+ "riesling": 36372,
+ "rif": 7044,
+ "riff": 30359,
+ "rifle": 15354,
+ "rifles": 25678,
+ "rift": 26681,
+ "rig": 18462,
+ "rig": 13871,
+ "riga": 36626,
+ "rigged": 35897,
+ "rigging": 38160,
+ "riggs": 40328,
+ "righ": 15391,
+ "right": 13341,
+ "right": 1155,
+ "righte": 20762,
+ "righteous": 28169,
+ "righteousness": 42481,
+ "rightful": 42601,
+ "rightly": 42669,
+ "rights": 3336,
+ "rigid": 43138,
+ "rigor": 36788,
+ "rigorous": 41654,
+ "rigs": 42893,
+ "rihanna": 13744,
+ "rij": 41097,
+ "rik": 31136,
+ "rik": 27832,
+ "rika": 28580,
+ "ril": 12270,
+ "ril": 2388,
+ "riley": 35056,
+ "riley": 12260,
+ "rill": 23705,
+ "rilla": 43956,
+ "rilla": 18685,
+ "rim": 28147,
+ "rim": 12199,
+ "rime": 27064,
+ "rimin": 11527,
+ "rimo": 47817,
+ "rims": 34327,
+ "rin": 5859,
+ "rin": 11739,
+ "rina": 12869,
+ "rine": 24952,
+ "ring": 8318,
+ "ring": 2540,
+ "ringed": 44712,
+ "ringer": 35761,
+ "ringing": 26035,
+ "ringo": 38845,
+ "rings": 5751,
+ "rington": 12455,
+ "rink": 21497,
+ "rinka": 47316,
+ "rino": 47188,
+ "rinse": 48320,
+ "rio": 15681,
+ "rio": 5782,
+ "rion": 31623,
+ "rion": 34046,
+ "rios": 32814,
+ "riot": 32636,
+ "riot": 14218,
+ "riots": 24844,
+ "rious": 6340,
+ "rip": 10353,
+ "rip": 4243,
+ "ripe": 22832,
+ "ripley": 41589,
+ "ripp": 25276,
+ "ripped": 17815,
+ "ripper": 35347,
+ "ripping": 29126,
+ "ripple": 24825,
+ "rips": 30182,
+ "rir": 36792,
+ "ris": 6108,
+ "ris": 1999,
+ "rise": 13641,
+ "rise": 3151,
+ "risen": 23653,
+ "risers": 44983,
+ "rises": 13362,
+ "riseup": 35760,
+ "rish": 18378,
+ "rish": 18927,
+ "rishi": 48434,
+ "rising": 30452,
+ "rising": 5448,
+ "risis": 37998,
+ "risk": 27967,
+ "risk": 4213,
+ "risking": 48155,
+ "risks": 12474,
+ "risky": 27630,
+ "risotto": 31471,
+ "rist": 40610,
+ "rit": 5156,
+ "rit": 17333,
+ "rita": 16178,
+ "ritchie": 30997,
+ "rite": 39318,
+ "rite": 18429,
+ "rites": 36160,
+ "rith": 48169,
+ "rith": 48850,
+ "riti": 32904,
+ "rito": 19379,
+ "ritos": 33507,
+ "ritt": 26092,
+ "ritter": 34854,
+ "ritu": 13391,
+ "ritual": 19712,
+ "rituals": 31145,
+ "ritz": 39151,
+ "ritz": 25627,
+ "rium": 33884,
+ "riv": 25113,
+ "rival": 13412,
+ "rival": 15629,
+ "rivalry": 19511,
+ "rivals": 15135,
+ "rive": 27588,
+ "rive": 34917,
+ "river": 5239,
+ "river": 2473,
+ "rivera": 18275,
+ "riverdale": 28304,
+ "riverfront": 44439,
+ "rivers": 10723,
+ "riverside": 15809,
+ "riveting": 44024,
+ "riviera": 25851,
+ "rix": 43407,
+ "rix": 9483,
+ "riya": 36908,
+ "riyad": 31564,
+ "riyadh": 33577,
+ "riz": 18426,
+ "riz": 35411,
+ "rizal": 41555,
+ "rizio": 40191,
+ "rizz": 34826,
+ "rizzo": 49076,
+ "rj": 26016,
+ "rj": 20949,
+ "rk": 38725,
+ "rk": 21422,
+ "rl": 18041,
+ "rl": 14590,
+ "rlly": 43222,
+ "rly": 25954,
+ "rm": 20202,
+ "rm": 8431,
+ "rmb": 49097,
+ "rms": 40529,
+ "rn": 13206,
+ "rn": 7666,
+ "rna": 24566,
+ "rnb": 31556,
+ "rnc": 35309,
+ "rnli": 29748,
+ "ro": 532,
+ "ro": 2795,
+ "roa": 8313,
+ "roach": 31073,
+ "road": 4370,
+ "road": 1759,
+ "roadhouse": 47891,
+ "roadmap": 30111,
+ "roads": 6189,
+ "roadsafety": 39992,
+ "roadshow": 21168,
+ "roadside": 26928,
+ "roadster": 28920,
+ "roadto": 24681,
+ "roadtrip": 15094,
+ "roadway": 42744,
+ "roam": 34045,
+ "roaming": 29240,
+ "roano": 34184,
+ "roanoke": 36587,
+ "roar": 34193,
+ "roar": 18483,
+ "roaring": 26428,
+ "roast": 11404,
+ "roasted": 10479,
+ "roasting": 32228,
+ "rob": 2668,
+ "rob": 6442,
+ "robb": 14059,
+ "robb": 39673,
+ "robbed": 24163,
+ "robber": 35545,
+ "robbers": 40852,
+ "robbery": 16393,
+ "robbi": 44898,
+ "robbie": 37200,
+ "robbie": 15970,
+ "robbing": 47569,
+ "robbins": 23461,
+ "robby": 44128,
+ "robe": 23116,
+ "rober": 4532,
+ "robert": 8811,
+ "robert": 3929,
+ "roberta": 43373,
+ "roberto": 42645,
+ "roberto": 16227,
+ "roberts": 10366,
+ "robertson": 17643,
+ "robes": 29304,
+ "robi": 16743,
+ "robin": 6681,
+ "robin": 7988,
+ "robins": 35502,
+ "robinson": 8523,
+ "robles": 47646,
+ "roblo": 27481,
+ "roblox": 37798,
+ "robo": 4672,
+ "robo": 36057,
+ "robot": 46089,
+ "robot": 8797,
+ "robotic": 23975,
+ "robotics": 13546,
+ "robots": 13473,
+ "robson": 31113,
+ "robust": 22780,
+ "robyn": 34533,
+ "roc": 3268,
+ "roc": 13776,
+ "rocco": 30009,
+ "roch": 23788,
+ "rochdale": 41880,
+ "roche": 31776,
+ "rochelle": 40161,
+ "rochester": 18057,
+ "rock": 2640,
+ "rock": 2172,
+ "rockab": 39353,
+ "rockabilly": 45019,
+ "rocke": 19914,
+ "rocked": 16116,
+ "rockefeller": 35476,
+ "rocker": 29008,
+ "rockers": 32338,
+ "rocket": 25435,
+ "rocket": 8383,
+ "rockets": 13292,
+ "rockford": 41039,
+ "rockies": 20621,
+ "rockin": 12073,
+ "rocking": 7081,
+ "rockn": 24442,
+ "rocknroll": 27840,
+ "rocks": 6135,
+ "rockstar": 23603,
+ "rockstar": 18000,
+ "rockstargames": 27516,
+ "rockstars": 46639,
+ "rockthe": 49363,
+ "rockwell": 34747,
+ "rocky": 33481,
+ "rocky": 9648,
+ "rod": 9712,
+ "rod": 8291,
+ "roddy": 42332,
+ "rode": 18449,
+ "rodeo": 18250,
+ "rodgers": 17612,
+ "rodi": 49100,
+ "rodney": 21753,
+ "rodri": 11053,
+ "rodrigo": 33944,
+ "rodriguez": 14057,
+ "rods": 28618,
+ "roe": 27671,
+ "roe": 9996,
+ "rof": 33029,
+ "rofl": 48228,
+ "roft": 45212,
+ "rog": 34269,
+ "rog": 34017,
+ "rogen": 23380,
+ "roger": 13929,
+ "roger": 7735,
+ "rogerfederer": 40182,
+ "rogers": 10661,
+ "rogue": 32575,
+ "rogue": 15162,
+ "roh": 14933,
+ "roh": 29840,
+ "rohan": 39848,
+ "rohing": 23600,
+ "rohingya": 26146,
+ "rohit": 44649,
+ "rohit": 24299,
+ "roi": 21877,
+ "rok": 36807,
+ "rol": 3393,
+ "rol": 7818,
+ "roland": 33713,
+ "roland": 19569,
+ "role": 18485,
+ "role": 3414,
+ "roles": 11871,
+ "rolex": 21093,
+ "rolf": 48606,
+ "roll": 4711,
+ "roll": 3341,
+ "rolled": 11982,
+ "roller": 21034,
+ "roller": 12342,
+ "rollercoaster": 38248,
+ "rollers": 36941,
+ "rollin": 27545,
+ "rolling": 24250,
+ "rolling": 6347,
+ "rollingstones": 41309,
+ "rollins": 27724,
+ "rollout": 47710,
+ "rollover": 39214,
+ "rolls": 8614,
+ "rolltide": 28101,
+ "rom": 11377,
+ "rom": 19205,
+ "roma": 44134,
+ "roma": 11631,
+ "romain": 48897,
+ "roman": 4416,
+ "roman": 7370,
+ "romance": 7215,
+ "romania": 15884,
+ "romanian": 30866,
+ "romano": 38409,
+ "romans": 23066,
+ "romantic": 41457,
+ "romantic": 8821,
+ "rome": 9406,
+ "rome": 5243,
+ "romeo": 14429,
+ "romero": 23694,
+ "romney": 19287,
+ "romo": 32248,
+ "romper": 43699,
+ "ron": 2393,
+ "ron": 3372,
+ "rona": 42385,
+ "ronal": 46194,
+ "ronald": 15683,
+ "ronaldo": 13463,
+ "ronan": 34971,
+ "rond": 31935,
+ "ronda": 37436,
+ "rondo": 43756,
+ "rone": 48082,
+ "rone": 32763,
+ "roni": 47234,
+ "ronnie": 45257,
+ "ronnie": 16421,
+ "rons": 19536,
+ "ront": 48881,
+ "roo": 1249,
+ "roo": 31227,
+ "rood": 38007,
+ "roof": 9120,
+ "roof": 6449,
+ "roofing": 24415,
+ "roofs": 34635,
+ "rooftop": 16319,
+ "rook": 35918,
+ "rookie": 9771,
+ "rookies": 31917,
+ "room": 8845,
+ "room": 1530,
+ "roomie": 36851,
+ "roommate": 19825,
+ "roommates": 37323,
+ "rooms": 6328,
+ "rooney": 17712,
+ "roos": 32938,
+ "roosevel": 17644,
+ "roosevelt": 18488,
+ "rooster": 46263,
+ "rooster": 30926,
+ "roosters": 43693,
+ "root": 25930,
+ "root": 9728,
+ "rooted": 30428,
+ "rooting": 25523,
+ "roots": 8084,
+ "rop": 43401,
+ "rope": 9953,
+ "ropes": 30506,
+ "ror": 8668,
+ "ror": 2843,
+ "rors": 12072,
+ "rory": 42804,
+ "rory": 17813,
+ "ros": 5288,
+ "ros": 6930,
+ "rosa": 14393,
+ "rosal": 30397,
+ "rosario": 33640,
+ "rosary": 33098,
+ "rosberg": 46037,
+ "rose": 6146,
+ "rose": 3568,
+ "roseanne": 47528,
+ "rosel": 33616,
+ "rosemary": 19472,
+ "rosen": 13214,
+ "rosen": 36424,
+ "rosenberg": 43558,
+ "rosenthal": 46990,
+ "roses": 9061,
+ "rosetta": 43800,
+ "rosewood": 38686,
+ "rosie": 43049,
+ "rosie": 16888,
+ "ross": 8801,
+ "ross": 2158,
+ "rosse": 11602,
+ "rossi": 24817,
+ "rosso": 33023,
+ "roster": 12487,
+ "roswell": 45116,
+ "rosy": 46705,
+ "rosé": 28006,
+ "rot": 10055,
+ "rot": 9643,
+ "rotar": 45959,
+ "rotary": 14654,
+ "rotating": 32265,
+ "rotation": 18089,
+ "rotc": 32252,
+ "roth": 17741,
+ "roth": 19139,
+ "rother": 23174,
+ "rotherham": 37687,
+ "rothschild": 45089,
+ "roti": 46940,
+ "roto": 34698,
+ "rotor": 42991,
+ "rots": 16642,
+ "rott": 34806,
+ "rotten": 24324,
+ "rotter": 22614,
+ "rotterdam": 23422,
+ "rotun": 42970,
+ "rou": 2964,
+ "rou": 34783,
+ "roud": 28375,
+ "rouge": 16209,
+ "rough": 11699,
+ "rough": 8511,
+ "roughly": 21910,
+ "roughs": 37598,
+ "rouhani": 39912,
+ "roulette": 39930,
+ "roun": 5602,
+ "round": 9403,
+ "round": 2522,
+ "roundabout": 29953,
+ "rounded": 26973,
+ "rounder": 37024,
+ "rounding": 40208,
+ "rounds": 11242,
+ "roundtable": 19386,
+ "roundup": 17503,
+ "roup": 29220,
+ "rourke": 38753,
+ "rous": 33645,
+ "rous": 34531,
+ "rousey": 46267,
+ "rout": 7502,
+ "rout": 41778,
+ "route": 5261,
+ "router": 29962,
+ "routes": 14923,
+ "routine": 12319,
+ "routines": 44074,
+ "routing": 44086,
+ "roux": 43416,
+ "rov": 23971,
+ "rove": 30130,
+ "rover": 12776,
+ "rovers": 16373,
+ "row": 5275,
+ "row": 1044,
+ "rowan": 26240,
+ "rowdy": 32141,
+ "rowe": 28323,
+ "rowed": 22615,
+ "rower": 43345,
+ "rowers": 41806,
+ "rowing": 12807,
+ "rowland": 33037,
+ "rowley": 48793,
+ "rowling": 29371,
+ "rown": 22287,
+ "rown": 25060,
+ "rows": 9409,
+ "rox": 14111,
+ "rox": 41033,
+ "roxy": 28093,
+ "roy": 2128,
+ "roy": 6354,
+ "royal": 6691,
+ "royal": 3853,
+ "royale": 20630,
+ "royalnavy": 41545,
+ "royals": 13335,
+ "royalties": 48660,
+ "royalty": 18296,
+ "royalwedding": 27461,
+ "royce": 18444,
+ "royd": 41476,
+ "royo": 39357,
+ "roz": 28989,
+ "roz": 37250,
+ "rp": 17305,
+ "rp": 8174,
+ "rpa": 41872,
+ "rpg": 12445,
+ "rpm": 23715,
+ "rps": 49215,
+ "rr": 5311,
+ "rr": 9126,
+ "rrp": 36967,
+ "rrr": 18267,
+ "rrrr": 25561,
+ "rrrr": 34444,
+ "rs": 6978,
+ "rs": 1724,
+ "rsa": 29437,
+ "rsc": 48524,
+ "rsd": 34426,
+ "rsi": 39046,
+ "rsl": 44752,
+ "rsp": 16381,
+ "rspb": 38508,
+ "rspb": 36727,
+ "rspca": 45643,
+ "rss": 46466,
+ "rss": 22350,
+ "rstats": 38700,
+ "rsvp": 9774,
+ "rt": 8959,
+ "rt": 8991,
+ "rtc": 31648,
+ "rte": 33822,
+ "rte": 23322,
+ "rtg": 22028,
+ "rti": 47549,
+ "rtr": 43999,
+ "rts": 8496,
+ "rtw": 34673,
+ "ru": 681,
+ "ru": 13735,
+ "rub": 15862,
+ "rub": 22586,
+ "rubb": 19597,
+ "rubbed": 45239,
+ "rubber": 31131,
+ "rubber": 11331,
+ "rubbing": 41262,
+ "rubbish": 21108,
+ "rubble": 42230,
+ "ruben": 44058,
+ "ruben": 29722,
+ "rubi": 27856,
+ "rubin": 34128,
+ "rubio": 24244,
+ "rubs": 43422,
+ "ruby": 24552,
+ "ruby": 11493,
+ "ruck": 27449,
+ "rucker": 45402,
+ "rud": 35256,
+ "rudd": 31836,
+ "rude": 16548,
+ "rudi": 48360,
+ "rudol": 40927,
+ "rudolf": 46835,
+ "rudolph": 30119,
+ "rudy": 38226,
+ "rudy": 22131,
+ "rue": 38024,
+ "rue": 19276,
+ "rufc": 45084,
+ "ruff": 28177,
+ "ruff": 30304,
+ "rufus": 39322,
+ "rug": 4217,
+ "rug": 19220,
+ "rugby": 15091,
+ "rugby": 4964,
+ "rugbyleague": 44419,
+ "ruger": 48655,
+ "rugged": 25225,
+ "rugs": 29946,
+ "rui": 46974,
+ "ruin": 16256,
+ "ruined": 17231,
+ "ruining": 29952,
+ "ruins": 16094,
+ "ruiz": 27873,
+ "ruk": 46628,
+ "rukh": 43075,
+ "rukh": 27631,
+ "rule": 31643,
+ "rule": 6175,
+ "ruled": 16324,
+ "ruler": 26286,
+ "rulers": 45328,
+ "rules": 5272,
+ "ruling": 14690,
+ "rum": 9223,
+ "rum": 11233,
+ "rumb": 42432,
+ "rumble": 18900,
+ "rumi": 31428,
+ "rumor": 22254,
+ "rumored": 36694,
+ "rumors": 16160,
+ "rumour": 34296,
+ "rumours": 20716,
+ "rump": 29366,
+ "run": 1639,
+ "run": 1934,
+ "runaway": 28851,
+ "runchat": 25838,
+ "rundown": 41100,
+ "rune": 33882,
+ "rune": 49244,
+ "runner": 37370,
+ "runner": 7913,
+ "runners": 10571,
+ "runnin": 43130,
+ "running": 24451,
+ "running": 2761,
+ "runoff": 38564,
+ "runs": 5586,
+ "runway": 13927,
+ "rup": 7996,
+ "rup": 14980,
+ "rupaul": 44211,
+ "rupee": 43916,
+ "rupees": 44110,
+ "rupert": 25625,
+ "rupt": 23055,
+ "ruption": 35403,
+ "rural": 28801,
+ "rural": 8737,
+ "rus": 35811,
+ "rus": 5998,
+ "rush": 12148,
+ "rush": 6973,
+ "rushed": 28104,
+ "rusher": 48745,
+ "rushes": 47217,
+ "rushing": 20284,
+ "russ": 6285,
+ "russ": 20764,
+ "russell": 26122,
+ "russell": 8150,
+ "russi": 2600,
+ "russia": 4018,
+ "russian": 30731,
+ "russian": 4868,
+ "russians": 25413,
+ "russo": 30679,
+ "rust": 28682,
+ "rust": 14212,
+ "rustic": 19822,
+ "rusty": 43966,
+ "rusty": 22646,
+ "rut": 14973,
+ "rut": 39102,
+ "rutger": 49029,
+ "rutgers": 28934,
+ "ruth": 15798,
+ "ruth": 12029,
+ "ruther": 26676,
+ "rutherford": 31070,
+ "ruthless": 36063,
+ "rutland": 46024,
+ "ruto": 43702,
+ "ruz": 23275,
+ "rv": 17135,
+ "rv": 17951,
+ "rva": 24278,
+ "rw": 9085,
+ "rw": 22926,
+ "rwa": 47452,
+ "rwand": 31758,
+ "rwanda": 15427,
+ "rwby": 39698,
+ "rwc": 32321,
+ "rx": 41188,
+ "rx": 15945,
+ "ry": 1511,
+ "ry": 913,
+ "ryan": 8682,
+ "ryan": 4053,
+ "ryanair": 43526,
+ "ryder": 43564,
+ "ryder": 21805,
+ "rye": 24015,
+ "rye": 17409,
+ "rying": 7838,
+ "ryn": 37728,
+ "ryo": 24460,
+ "rys": 21654,
+ "ryu": 46656,
+ "ryu": 34604,
+ "ré": 29106,
+ "s": 82,
+ "s": 338,
+ "sa": 774,
+ "sa": 1344,
+ "saa": 13429,
+ "saab": 27158,
+ "saad": 36530,
+ "saas": 25761,
+ "saat": 33151,
+ "sab": 3233,
+ "sab": 23213,
+ "saba": 38344,
+ "sabah": 32854,
+ "saban": 41620,
+ "sabar": 47102,
+ "sabbath": 26008,
+ "sabc": 30010,
+ "sabcnews": 41093,
+ "saber": 46822,
+ "saber": 25624,
+ "sabha": 23431,
+ "sabi": 47073,
+ "sabine": 44062,
+ "sable": 19224,
+ "sabot": 30700,
+ "sabotage": 40496,
+ "sabre": 35110,
+ "sabres": 29620,
+ "sabrin": 37029,
+ "sabrina": 24994,
+ "sac": 3632,
+ "sac": 12905,
+ "sach": 30168,
+ "sacha": 49010,
+ "sachin": 47527,
+ "sachin": 30297,
+ "sachs": 31451,
+ "sack": 28964,
+ "sack": 14979,
+ "sacked": 27519,
+ "sacks": 26441,
+ "sacram": 13334,
+ "sacramento": 16065,
+ "sacred": 40612,
+ "sacred": 12477,
+ "sacri": 15283,
+ "sacrif": 12117,
+ "sacrific": 16919,
+ "sacrifice": 12556,
+ "sacrificed": 31116,
+ "sacrifices": 28858,
+ "sacrificing": 48146,
+ "sad": 2810,
+ "sad": 3719,
+ "saddened": 27720,
+ "saddest": 34925,
+ "saddle": 30469,
+ "saddle": 20283,
+ "sade": 27429,
+ "sadh": 40955,
+ "sadi": 22207,
+ "sadie": 30333,
+ "sadiq": 44107,
+ "sadler": 45600,
+ "sadly": 11603,
+ "sadness": 20399,
+ "sae": 38633,
+ "sae": 34883,
+ "saeed": 29745,
+ "saf": 2125,
+ "saf": 25760,
+ "safar": 23443,
+ "safari": 14091,
+ "safarilive": 34816,
+ "safc": 27998,
+ "safe": 2901,
+ "safe": 2996,
+ "safeguard": 42249,
+ "safeguarding": 47451,
+ "safely": 11513,
+ "safer": 40124,
+ "safer": 15504,
+ "safest": 38973,
+ "safety": 19050,
+ "safety": 3406,
+ "safetyfirst": 43608,
+ "saffron": 27529,
+ "sag": 6609,
+ "sag": 30048,
+ "saga": 15758,
+ "sagan": 37193,
+ "sagar": 42518,
+ "sage": 25800,
+ "sage": 7509,
+ "sages": 25979,
+ "sagin": 47097,
+ "sagitt": 44685,
+ "sagu": 44708,
+ "sah": 30943,
+ "sah": 26342,
+ "saha": 36062,
+ "sahara": 24599,
+ "saharan": 44255,
+ "sahi": 24608,
+ "sahib": 34150,
+ "sai": 16048,
+ "sai": 10886,
+ "said": 40319,
+ "said": 1946,
+ "saif": 44164,
+ "saig": 36328,
+ "saigon": 41081,
+ "sail": 7528,
+ "sail": 12156,
+ "sailed": 43047,
+ "sailing": 11003,
+ "sailor": 28002,
+ "sailor": 16076,
+ "sailormoon": 40673,
+ "sailors": 25355,
+ "sails": 27526,
+ "sain": 21226,
+ "sain": 40378,
+ "sains": 24860,
+ "sainsbury": 45879,
+ "sainsburys": 36934,
+ "saint": 11274,
+ "saint": 5599,
+ "saints": 8769,
+ "saintsfc": 31102,
+ "sair": 46600,
+ "sair": 30971,
+ "saire": 28087,
+ "saison": 33256,
+ "sait": 48008,
+ "saj": 33580,
+ "sak": 11511,
+ "sak": 35900,
+ "saka": 33609,
+ "sake": 12874,
+ "sakh": 43945,
+ "saki": 40514,
+ "saku": 37550,
+ "sakura": 24162,
+ "sal": 980,
+ "sal": 6126,
+ "sala": 17300,
+ "salaam": 46773,
+ "salad": 6188,
+ "salads": 30948,
+ "salah": 22516,
+ "salam": 19007,
+ "salam": 33963,
+ "salamat": 44696,
+ "salami": 46885,
+ "salaries": 33132,
+ "salary": 16312,
+ "salazar": 45988,
+ "sale": 17786,
+ "sale": 1690,
+ "saleh": 38353,
+ "salem": 48194,
+ "salem": 16884,
+ "sales": 13347,
+ "sales": 3765,
+ "salesforce": 22680,
+ "salesman": 37633,
+ "salford": 25629,
+ "sali": 15411,
+ "salim": 42760,
+ "salinas": 41990,
+ "saline": 46918,
+ "salis": 20667,
+ "salis": 39378,
+ "salisbury": 24763,
+ "sall": 27122,
+ "sall": 20883,
+ "salle": 23738,
+ "sally": 29542,
+ "sally": 13349,
+ "salman": 13754,
+ "salman": 16219,
+ "salmankhan": 15177,
+ "salmon": 37040,
+ "salmon": 9137,
+ "salom": 38268,
+ "salon": 33916,
+ "salon": 11105,
+ "saloon": 26038,
+ "sals": 16307,
+ "salsa": 16442,
+ "salt": 12763,
+ "salt": 6611,
+ "salted": 26313,
+ "saltlife": 47809,
+ "salts": 40559,
+ "saltwater": 43616,
+ "salty": 20678,
+ "salu": 31711,
+ "salud": 46867,
+ "salut": 44998,
+ "salute": 44908,
+ "salute": 9747,
+ "salutes": 32762,
+ "salv": 8299,
+ "salvador": 20874,
+ "salvage": 33131,
+ "salvation": 19534,
+ "salvatore": 38772,
+ "salz": 33594,
+ "salzburg": 43396,
+ "sam": 1644,
+ "sam": 3730,
+ "sama": 19272,
+ "samanth": 11465,
+ "samantha": 15466,
+ "samanthap": 38266,
+ "samanthaprabhu": 38643,
+ "samar": 21820,
+ "samaritan": 45495,
+ "samba": 37190,
+ "same": 23062,
+ "same": 2208,
+ "samheughan": 36255,
+ "sami": 48400,
+ "sami": 24322,
+ "sammy": 31091,
+ "sammy": 16758,
+ "samo": 30006,
+ "samoa": 34932,
+ "samp": 31225,
+ "sample": 9542,
+ "sampler": 40629,
+ "samples": 13387,
+ "sampling": 19522,
+ "sampson": 39983,
+ "sams": 44667,
+ "samson": 34659,
+ "samsun": 47875,
+ "samsung": 35369,
+ "samsung": 8115,
+ "samu": 7646,
+ "samuel": 30612,
+ "samuel": 12787,
+ "samurai": 21739,
+ "san": 1489,
+ "san": 2223,
+ "sana": 19434,
+ "sanantonio": 34714,
+ "sanat": 29091,
+ "sanatomy": 36052,
+ "sanc": 7398,
+ "sance": 15930,
+ "sanchez": 13971,
+ "sanctioned": 43032,
+ "sanctions": 17790,
+ "sanctu": 12712,
+ "sanctuary": 14044,
+ "sand": 2147,
+ "sand": 5094,
+ "sandal": 36445,
+ "sandal": 42185,
+ "sandals": 20731,
+ "sandalwood": 47502,
+ "sandeep": 46973,
+ "sander": 34111,
+ "sanders": 10429,
+ "sanderson": 36198,
+ "sandi": 44249,
+ "sandiego": 45997,
+ "sandiego": 15793,
+ "sandman": 45730,
+ "sando": 35921,
+ "sandoval": 44157,
+ "sandra": 33733,
+ "sandra": 13415,
+ "sandro": 42389,
+ "sands": 5936,
+ "sandstone": 36796,
+ "sandwich": 17050,
+ "sandwich": 8687,
+ "sandwiches": 19667,
+ "sandy": 29679,
+ "sandy": 10355,
+ "sane": 23419,
+ "sanford": 32330,
+ "sanfrancisco": 20254,
+ "sang": 13235,
+ "sang": 11684,
+ "sange": 12466,
+ "sangria": 42665,
+ "sani": 39137,
+ "sani": 34492,
+ "sanitary": 33842,
+ "sanitation": 25414,
+ "saniti": 43987,
+ "sanity": 30517,
+ "sanjay": 31712,
+ "sanjay": 25796,
+ "sanje": 40405,
+ "sanjose": 45971,
+ "sank": 43692,
+ "sano": 34053,
+ "sans": 16982,
+ "sansk": 39689,
+ "sanskrit": 48083,
+ "sant": 8356,
+ "sant": 23120,
+ "santa": 22175,
+ "santa": 4555,
+ "santac": 28876,
+ "santam": 45627,
+ "santana": 27033,
+ "santander": 46476,
+ "santi": 13856,
+ "santiago": 16568,
+ "santo": 29631,
+ "santo": 18400,
+ "santor": 28448,
+ "santorini": 39573,
+ "santos": 16582,
+ "sany": 47679,
+ "sao": 28026,
+ "sap": 8089,
+ "sap": 11591,
+ "sapi": 40016,
+ "sapp": 13427,
+ "sapp": 40729,
+ "sapphire": 22044,
+ "sar": 1808,
+ "sar": 9424,
+ "sara": 37196,
+ "sara": 10063,
+ "sarab": 40716,
+ "sarac": 35722,
+ "sarah": 9086,
+ "sarah": 5327,
+ "saraj": 42592,
+ "sarajevo": 48211,
+ "saras": 20373,
+ "sarasota": 31990,
+ "sarato": 24845,
+ "saratoga": 29496,
+ "sarawak": 47331,
+ "sarcasm": 37246,
+ "sarcastic": 48639,
+ "sardar": 41786,
+ "sarde": 43925,
+ "sardin": 27383,
+ "sardinia": 41025,
+ "sare": 13051,
+ "saree": 30860,
+ "sargent": 34864,
+ "sari": 42327,
+ "sari": 20261,
+ "saries": 47586,
+ "sarkar": 30673,
+ "sarko": 33658,
+ "sarkodie": 42848,
+ "sarmy": 20954,
+ "sart": 33006,
+ "sary": 15398,
+ "sas": 3960,
+ "sas": 5235,
+ "sash": 35656,
+ "sasha": 46078,
+ "sasha": 20894,
+ "sasia": 44751,
+ "sask": 47091,
+ "sask": 30416,
+ "saskat": 17102,
+ "saskatchewan": 23899,
+ "saskatoon": 31128,
+ "sass": 31351,
+ "sassy": 20827,
+ "sat": 1382,
+ "sat": 3279,
+ "sata": 41520,
+ "satan": 19446,
+ "satanic": 38224,
+ "satchel": 45908,
+ "sate": 35749,
+ "satell": 9031,
+ "satellite": 10316,
+ "satellites": 28483,
+ "sath": 29675,
+ "sathletics": 30154,
+ "sati": 7038,
+ "satin": 21803,
+ "sation": 23674,
+ "sations": 31232,
+ "satire": 29875,
+ "satis": 9906,
+ "satisf": 22941,
+ "satisfaction": 19925,
+ "satisfied": 18101,
+ "satisfy": 29444,
+ "satisfying": 23755,
+ "sato": 34376,
+ "satu": 45283,
+ "satur": 1634,
+ "saturated": 32466,
+ "saturday": 12537,
+ "saturday": 1748,
+ "saturdaymorning": 29053,
+ "saturdaymotivation": 40843,
+ "saturdays": 18930,
+ "saturn": 17312,
+ "saty": 39426,
+ "sau": 2096,
+ "sau": 19455,
+ "sauce": 5520,
+ "saucer": 42272,
+ "sauces": 40367,
+ "saucy": 46684,
+ "saudi": 24511,
+ "saudi": 8548,
+ "saudiarabia": 28680,
+ "sauer": 46333,
+ "saul": 47623,
+ "saul": 23252,
+ "sault": 40361,
+ "sauna": 35460,
+ "saunders": 23794,
+ "saur": 13227,
+ "saura": 46532,
+ "saurus": 22118,
+ "saus": 36121,
+ "sausage": 11855,
+ "sausages": 31593,
+ "sauté": 36290,
+ "sautéed": 38517,
+ "sauvi": 30116,
+ "sauvignon": 32745,
+ "sav": 2248,
+ "sav": 26533,
+ "sava": 40198,
+ "savag": 43039,
+ "savage": 11859,
+ "savannah": 18662,
+ "save": 5895,
+ "save": 2673,
+ "saved": 7137,
+ "saveour": 33390,
+ "saver": 20987,
+ "savers": 31416,
+ "saves": 12907,
+ "savethe": 18031,
+ "savi": 14721,
+ "saving": 28498,
+ "saving": 6979,
+ "savings": 10651,
+ "savior": 24762,
+ "saviour": 35800,
+ "savor": 48071,
+ "savory": 32992,
+ "savoury": 49071,
+ "savoy": 39552,
+ "savvy": 29278,
+ "saw": 12429,
+ "saw": 2425,
+ "sawa": 39613,
+ "sawards": 29012,
+ "sawyer": 27726,
+ "sax": 14169,
+ "sax": 23766,
+ "saxon": 31856,
+ "saxophon": 43760,
+ "saxophone": 32296,
+ "say": 3047,
+ "say": 1451,
+ "saya": 35170,
+ "sayang": 46322,
+ "sayers": 44116,
+ "sayin": 23662,
+ "saying": 4455,
+ "says": 1563,
+ "saz": 35577,
+ "sb": 5576,
+ "sb": 4977,
+ "sba": 44970,
+ "sback": 43840,
+ "sband": 27539,
+ "sbaseball": 46491,
+ "sbball": 39190,
+ "sbc": 31404,
+ "sberg": 20358,
+ "sbi": 41369,
+ "sbk": 39211,
+ "sboro": 18909,
+ "sbridge": 49228,
+ "sbs": 18883,
+ "sbu": 48075,
+ "sbu": 46281,
+ "sburg": 7390,
+ "sburgh": 48205,
+ "sbury": 14081,
+ "sby": 26519,
+ "sby": 10287,
+ "sc": 663,
+ "sc": 3219,
+ "sca": 11001,
+ "scab": 31716,
+ "scaf": 28981,
+ "scafe": 45574,
+ "scaffolding": 41687,
+ "scal": 10859,
+ "scala": 37997,
+ "scalable": 44084,
+ "scale": 37817,
+ "scale": 5879,
+ "scaled": 41923,
+ "scales": 22891,
+ "scaling": 29116,
+ "scallo": 19936,
+ "scallop": 39544,
+ "scallops": 31430,
+ "scalp": 38898,
+ "scam": 17620,
+ "scam": 13215,
+ "scamp": 28451,
+ "scams": 34395,
+ "scan": 10650,
+ "scan": 11261,
+ "scanada": 27121,
+ "scand": 8110,
+ "scandal": 35420,
+ "scandal": 11622,
+ "scandals": 45490,
+ "scandin": 32014,
+ "scandinavian": 35661,
+ "scanned": 43719,
+ "scanner": 24185,
+ "scanning": 24092,
+ "scans": 31251,
+ "scap": 35883,
+ "scape": 36005,
+ "scape": 12314,
+ "scapes": 31933,
+ "scar": 4171,
+ "scar": 18088,
+ "scarborough": 24254,
+ "scarce": 38572,
+ "scarcity": 45812,
+ "scare": 33536,
+ "scare": 15920,
+ "scarec": 38814,
+ "scarecrow": 46504,
+ "scared": 9870,
+ "scares": 34096,
+ "scarf": 13365,
+ "scari": 27050,
+ "scariest": 37213,
+ "scarlet": 20389,
+ "scarlett": 28325,
+ "scars": 20747,
+ "scarves": 29249,
+ "scary": 9250,
+ "scat": 13899,
+ "scattered": 22090,
+ "scavenger": 36778,
+ "scc": 19458,
+ "scd": 48422,
+ "scen": 2204,
+ "scenario": 20456,
+ "scenarios": 31346,
+ "scence": 33418,
+ "scene": 3562,
+ "scenery": 16025,
+ "scenes": 5415,
+ "scenic": 15394,
+ "scent": 36277,
+ "scent": 7683,
+ "scented": 27190,
+ "scenter": 23059,
+ "scentre": 39371,
+ "scents": 26336,
+ "scep": 24439,
+ "scfc": 38578,
+ "sch": 844,
+ "sch": 7542,
+ "scha": 42809,
+ "schaf": 45588,
+ "schaft": 41010,
+ "schal": 35568,
+ "schalke": 41029,
+ "schallenge": 43665,
+ "schan": 31328,
+ "schar": 15085,
+ "schat": 31842,
+ "schau": 35830,
+ "sche": 3038,
+ "sche": 7289,
+ "schedu": 4207,
+ "schedule": 5521,
+ "scheduled": 10986,
+ "schedules": 28986,
+ "scheduling": 32216,
+ "scheer": 26776,
+ "schel": 39881,
+ "schel": 38569,
+ "schem": 17720,
+ "scheme": 9024,
+ "schemes": 22958,
+ "schen": 22738,
+ "scher": 21925,
+ "scher": 21299,
+ "schi": 13731,
+ "schi": 24984,
+ "schicago": 46230,
+ "schiff": 39431,
+ "schild": 32148,
+ "schiz": 33230,
+ "schizoph": 40004,
+ "schizophre": 41163,
+ "schle": 32022,
+ "schmid": 17375,
+ "schmidt": 18463,
+ "schnau": 45745,
+ "schnei": 19941,
+ "schneider": 22972,
+ "schnit": 40903,
+ "scho": 2493,
+ "schoice": 23860,
+ "schol": 4498,
+ "scholar": 7192,
+ "scholar": 12830,
+ "scholarly": 41065,
+ "scholars": 13818,
+ "scholarship": 9070,
+ "scholarships": 17866,
+ "scholastic": 35743,
+ "schoo": 20721,
+ "school": 6063,
+ "school": 1228,
+ "schooled": 44722,
+ "schoolers": 31455,
+ "schooling": 28608,
+ "schools": 3513,
+ "schre": 47685,
+ "schri": 25453,
+ "schro": 32381,
+ "schu": 11318,
+ "schubert": 46939,
+ "schul": 14945,
+ "schultz": 30308,
+ "schulz": 39572,
+ "schumacher": 39208,
+ "schumer": 25313,
+ "schur": 42475,
+ "schwab": 47602,
+ "schwar": 13985,
+ "schwartz": 30617,
+ "schwarz": 27074,
+ "schwarzenegger": 33860,
+ "schwe": 25324,
+ "sci": 2267,
+ "sci": 8309,
+ "sciart": 31704,
+ "scicom": 28606,
+ "scicomm": 29573,
+ "scien": 39261,
+ "science": 10201,
+ "science": 2497,
+ "sciencefiction": 39170,
+ "sciences": 11481,
+ "scienti": 4338,
+ "scientific": 9750,
+ "scientist": 11083,
+ "scientists": 8045,
+ "sciento": 36193,
+ "scientology": 44694,
+ "scifi": 41862,
+ "scifi": 12230,
+ "scion": 47208,
+ "sciss": 25667,
+ "scissors": 30867,
+ "sciutto": 44392,
+ "sclerosis": 39446,
+ "sclub": 20017,
+ "sco": 1065,
+ "sco": 4763,
+ "scoe": 31164,
+ "scol": 13599,
+ "scoll": 44895,
+ "scollege": 39536,
+ "scom": 26407,
+ "scon": 17163,
+ "scon": 29272,
+ "scones": 36443,
+ "sconf": 39704,
+ "scoo": 14199,
+ "scooby": 34469,
+ "scoop": 13829,
+ "scoops": 41360,
+ "scope": 7979,
+ "scopes": 30328,
+ "scopic": 23869,
+ "scopy": 20018,
+ "scor": 8442,
+ "score": 12067,
+ "score": 4431,
+ "scoreboard": 30104,
+ "scorecard": 38128,
+ "scored": 6143,
+ "scoreless": 33469,
+ "scorer": 16572,
+ "scorers": 26699,
+ "scores": 7039,
+ "scoring": 9198,
+ "scorpi": 15445,
+ "scorpio": 34331,
+ "scorpion": 28461,
+ "scorpions": 45401,
+ "scorsese": 45975,
+ "scot": 2496,
+ "scot": 9271,
+ "scotch": 16687,
+ "scoti": 46446,
+ "scotia": 27859,
+ "scotland": 29174,
+ "scotland": 4203,
+ "scots": 17260,
+ "scotsman": 39612,
+ "scott": 7775,
+ "scott": 3664,
+ "scotti": 6227,
+ "scottish": 18039,
+ "scottish": 7442,
+ "scottsdale": 27817,
+ "scotty": 39697,
+ "scotty": 26836,
+ "scotus": 21720,
+ "scou": 44909,
+ "scoun": 16110,
+ "scouncil": 48787,
+ "scountry": 40432,
+ "scour": 46172,
+ "scout": 32213,
+ "scout": 10786,
+ "scouting": 19072,
+ "scouts": 14837,
+ "scow": 27929,
+ "scowboys": 31386,
+ "scp": 45030,
+ "scr": 36131,
+ "scra": 11187,
+ "scrabble": 39488,
+ "scram": 17289,
+ "scramble": 32688,
+ "scrambled": 39026,
+ "scran": 41774,
+ "scranton": 45274,
+ "scrap": 27950,
+ "scrap": 21695,
+ "scrapbook": 48733,
+ "scrapped": 43325,
+ "scraps": 40809,
+ "scrat": 9572,
+ "scratch": 13258,
+ "scratched": 48831,
+ "scratches": 46556,
+ "scratching": 44617,
+ "scre": 1795,
+ "scream": 31645,
+ "scream": 13239,
+ "screamed": 35427,
+ "screaming": 12891,
+ "screams": 23989,
+ "screen": 5351,
+ "screen": 3750,
+ "screened": 31450,
+ "screening": 6688,
+ "screenings": 27655,
+ "screenplay": 30058,
+ "screens": 12689,
+ "screenshot": 20637,
+ "screenshot": 12646,
+ "screenshots": 26783,
+ "screenshotsaturday": 21406,
+ "screenwriter": 37293,
+ "screenwriting": 35465,
+ "screw": 25529,
+ "screw": 14225,
+ "screwdriver": 48748,
+ "screwed": 30592,
+ "screws": 38292,
+ "scri": 2139,
+ "scrib": 34259,
+ "scribe": 36228,
+ "scribed": 38334,
+ "scricket": 45947,
+ "scrim": 21978,
+ "scrimmage": 25216,
+ "scrip": 11955,
+ "script": 8374,
+ "scripted": 40513,
+ "scription": 26604,
+ "scriptions": 39512,
+ "scripts": 20109,
+ "scripture": 27186,
+ "scro": 30768,
+ "scroll": 24160,
+ "scrolling": 28889,
+ "scrolls": 38113,
+ "scroo": 42263,
+ "scru": 7589,
+ "scrub": 23432,
+ "scrubs": 37919,
+ "scrum": 29047,
+ "scrump": 39791,
+ "scrumptious": 40987,
+ "scrutiny": 34305,
+ "scs": 26853,
+ "sct": 39284,
+ "scu": 8181,
+ "scu": 32135,
+ "scuba": 39053,
+ "scuba": 20559,
+ "scubadiving": 49046,
+ "scue": 25955,
+ "scul": 4948,
+ "scully": 36598,
+ "sculp": 6093,
+ "sculpt": 45044,
+ "sculpted": 41296,
+ "sculpting": 44389,
+ "sculptor": 29409,
+ "sculpture": 8757,
+ "sculptures": 20378,
+ "scum": 29655,
+ "scumb": 44525,
+ "scup": 21506,
+ "scur": 32742,
+ "scwx": 41966,
+ "scy": 27471,
+ "sd": 3080,
+ "sd": 4159,
+ "sda": 25548,
+ "sdale": 12327,
+ "sday": 5902,
+ "sday": 1376,
+ "sdays": 14491,
+ "sdc": 40992,
+ "sdcc": 13246,
+ "sden": 17241,
+ "sdf": 34681,
+ "sdg": 20177,
+ "sdgs": 16261,
+ "sdk": 40015,
+ "sdlive": 34561,
+ "sdn": 41925,
+ "sdsu": 41284,
+ "se": 567,
+ "se": 611,
+ "sea": 5970,
+ "sea": 2102,
+ "seab": 15728,
+ "seabir": 42558,
+ "seac": 35626,
+ "seaf": 9336,
+ "seafood": 12472,
+ "seag": 15730,
+ "seagu": 38076,
+ "seagull": 38858,
+ "seagulls": 42215,
+ "seahawks": 15341,
+ "seal": 21381,
+ "seal": 10159,
+ "sealed": 13358,
+ "sealing": 42992,
+ "seals": 18179,
+ "seam": 13710,
+ "seam": 44201,
+ "seaman": 47513,
+ "seamless": 29373,
+ "seamus": 40175,
+ "sean": 11406,
+ "sean": 6077,
+ "seanhannity": 43316,
+ "seap": 29983,
+ "seaport": 46418,
+ "sear": 1612,
+ "search": 23129,
+ "search": 1920,
+ "searched": 28961,
+ "searches": 26378,
+ "searching": 10626,
+ "seared": 29727,
+ "sears": 26693,
+ "seas": 7329,
+ "seas": 9556,
+ "seascape": 42593,
+ "seaside": 18867,
+ "season": 19288,
+ "season": 1367,
+ "seasonal": 14215,
+ "seasoned": 28399,
+ "seasoning": 43439,
+ "seasons": 8635,
+ "seat": 19670,
+ "seat": 4922,
+ "seated": 23953,
+ "seater": 37543,
+ "seating": 16240,
+ "seats": 6944,
+ "seattle": 24388,
+ "seattle": 6274,
+ "seau": 32263,
+ "seaw": 32658,
+ "seaweed": 30204,
+ "seaworld": 27422,
+ "seb": 35766,
+ "seb": 25171,
+ "sebasti": 10324,
+ "sebastian": 43792,
+ "sebastian": 13181,
+ "sebring": 41086,
+ "sec": 2875,
+ "sec": 5338,
+ "seca": 37847,
+ "secco": 27394,
+ "sece": 46297,
+ "seclu": 42392,
+ "secon": 1846,
+ "second": 9329,
+ "second": 2241,
+ "secondary": 13107,
+ "seconds": 6541,
+ "secre": 2460,
+ "secret": 20710,
+ "secret": 4145,
+ "secretari": 29515,
+ "secretariat": 31767,
+ "secretary": 6552,
+ "secretly": 21400,
+ "secrets": 9735,
+ "secs": 28665,
+ "sect": 15772,
+ "section": 34986,
+ "section": 4853,
+ "sectional": 21876,
+ "sections": 20061,
+ "sector": 6579,
+ "sectors": 22173,
+ "secu": 4894,
+ "secular": 47483,
+ "secular": 27560,
+ "secur": 2557,
+ "secure": 44763,
+ "secure": 7515,
+ "secured": 16848,
+ "secures": 31567,
+ "securing": 24759,
+ "securities": 25080,
+ "security": 31245,
+ "security": 2741,
+ "sed": 14034,
+ "sed": 1252,
+ "sedan": 24237,
+ "sedg": 46926,
+ "sedge": 45288,
+ "sedi": 29269,
+ "sedly": 31771,
+ "sedona": 46862,
+ "seduc": 19933,
+ "seductive": 43721,
+ "see": 1751,
+ "see": 862,
+ "seed": 14064,
+ "seed": 6488,
+ "seeded": 33688,
+ "seeding": 40050,
+ "seedlings": 47933,
+ "seeds": 9128,
+ "seeing": 3214,
+ "seek": 8839,
+ "seeker": 28011,
+ "seekers": 20732,
+ "seeking": 8592,
+ "seeks": 12594,
+ "seem": 20043,
+ "seem": 7523,
+ "seemed": 17240,
+ "seemingly": 25917,
+ "seems": 4453,
+ "seen": 36273,
+ "seen": 2041,
+ "seer": 32486,
+ "sees": 7594,
+ "seeyou": 41279,
+ "sef": 27453,
+ "seg": 10551,
+ "sega": 16122,
+ "segment": 15615,
+ "segments": 43053,
+ "segreg": 49117,
+ "segregation": 39086,
+ "segu": 33156,
+ "segun": 43087,
+ "seh": 27536,
+ "seh": 41430,
+ "sehun": 17705,
+ "sei": 13130,
+ "sei": 15907,
+ "sein": 24669,
+ "seine": 41378,
+ "seinfeld": 33706,
+ "seis": 25559,
+ "seismic": 38459,
+ "seiz": 22171,
+ "seize": 26624,
+ "seized": 15826,
+ "seizure": 36804,
+ "seizures": 47199,
+ "sek": 45515,
+ "sek": 25880,
+ "sel": 1000,
+ "sel": 4098,
+ "sela": 47006,
+ "selamat": 37692,
+ "selangor": 44402,
+ "selby": 43546,
+ "selca": 38606,
+ "selcaday": 35924,
+ "seldom": 48322,
+ "sele": 29137,
+ "selec": 3014,
+ "select": 8690,
+ "selected": 6881,
+ "selecting": 32696,
+ "selection": 6724,
+ "selections": 24099,
+ "selective": 28686,
+ "selects": 32902,
+ "selen": 19970,
+ "selena": 14677,
+ "selenagomez": 27653,
+ "seley": 30556,
+ "self": 10139,
+ "self": 1322,
+ "selfcare": 39560,
+ "selfi": 3007,
+ "selfie": 26735,
+ "selfie": 3666,
+ "selfies": 46058,
+ "selfies": 10050,
+ "selfish": 26907,
+ "selfless": 34236,
+ "sell": 10279,
+ "sell": 5119,
+ "seller": 11779,
+ "sellers": 16562,
+ "selling": 4396,
+ "sells": 14306,
+ "selma": 36652,
+ "sels": 42070,
+ "selves": 4505,
+ "sely": 8402,
+ "sem": 8645,
+ "sem": 17106,
+ "sema": 31816,
+ "seman": 29119,
+ "seman": 28378,
+ "semana": 41780,
+ "semb": 36054,
+ "seme": 10855,
+ "sement": 10714,
+ "sements": 31449,
+ "semester": 11905,
+ "semi": 11023,
+ "semi": 6684,
+ "semic": 26967,
+ "semicon": 34315,
+ "semiconduc": 35646,
+ "semiconductor": 43551,
+ "semifinal": 22935,
+ "semifinals": 21863,
+ "semin": 5595,
+ "seminar": 7269,
+ "seminars": 34870,
+ "seminary": 31655,
+ "seminole": 42956,
+ "semis": 24013,
+ "semit": 22628,
+ "semite": 23721,
+ "semitic": 34894,
+ "semitism": 25911,
+ "semper": 47391,
+ "sen": 1057,
+ "sen": 2249,
+ "sena": 21584,
+ "senate": 30703,
+ "senate": 6843,
+ "senator": 20871,
+ "senator": 8495,
+ "senators": 16889,
+ "send": 27684,
+ "send": 3625,
+ "sending": 6985,
+ "sends": 10817,
+ "sene": 25269,
+ "seneca": 33419,
+ "senegal": 28255,
+ "senew": 49313,
+ "seng": 43022,
+ "seng": 29971,
+ "senior": 19865,
+ "senior": 3415,
+ "seniors": 8138,
+ "senna": 36195,
+ "senpai": 46562,
+ "sens": 5218,
+ "sens": 22837,
+ "sensation": 19383,
+ "sensational": 23051,
+ "sense": 29162,
+ "sense": 4747,
+ "sensei": 36158,
+ "senses": 21809,
+ "sensi": 38802,
+ "sensible": 30635,
+ "sensing": 29236,
+ "sensiti": 20531,
+ "sensitive": 13734,
+ "sensitivity": 27788,
+ "sensor": 15330,
+ "sensors": 20356,
+ "sensory": 21831,
+ "sensu": 28157,
+ "sensual": 40860,
+ "sent": 6200,
+ "sent": 3676,
+ "sentence": 12737,
+ "sentenced": 17773,
+ "sentences": 25858,
+ "sentencing": 34394,
+ "senti": 19042,
+ "sentim": 25102,
+ "sentiment": 25949,
+ "sentimental": 40070,
+ "sentiments": 47450,
+ "sentin": 20042,
+ "sentinel": 23123,
+ "senting": 3924,
+ "seo": 24743,
+ "seo": 8622,
+ "seok": 34697,
+ "seok": 22482,
+ "seokjin": 45584,
+ "seoul": 13253,
+ "sep": 3212,
+ "sep": 10434,
+ "separ": 6859,
+ "separate": 13886,
+ "separated": 22163,
+ "separately": 41904,
+ "separates": 45365,
+ "separati": 39377,
+ "separating": 43480,
+ "separation": 22007,
+ "sephora": 38414,
+ "sepsis": 40205,
+ "sept": 5380,
+ "septe": 3672,
+ "september": 3707,
+ "septic": 34690,
+ "sepul": 47360,
+ "seq": 44379,
+ "sequ": 5491,
+ "seque": 44662,
+ "sequel": 15701,
+ "sequence": 18833,
+ "sequences": 47306,
+ "sequencing": 33484,
+ "sequo": 32781,
+ "sequoia": 42404,
+ "ser": 803,
+ "ser": 2771,
+ "sera": 28250,
+ "serbia": 19038,
+ "serbian": 33687,
+ "sere": 35770,
+ "seren": 7880,
+ "serena": 19519,
+ "serenawilliams": 48316,
+ "serendip": 45805,
+ "serendipity": 49386,
+ "serene": 28269,
+ "serenity": 24187,
+ "serge": 13477,
+ "serge": 35700,
+ "sergeant": 22049,
+ "sergei": 39870,
+ "sergey": 35390,
+ "sergi": 47675,
+ "sergio": 18359,
+ "seri": 2763,
+ "seri": 37509,
+ "serial": 14216,
+ "serie": 19752,
+ "seriea": 32660,
+ "series": 1857,
+ "serious": 47421,
+ "serious": 4770,
+ "seriously": 4885,
+ "sermon": 24884,
+ "sero": 48883,
+ "serpent": 37084,
+ "serpent": 35364,
+ "serra": 39851,
+ "serrano": 44236,
+ "sers": 13509,
+ "serum": 25385,
+ "serv": 1297,
+ "serv": 24571,
+ "servant": 20810,
+ "servants": 29652,
+ "serve": 39202,
+ "serve": 2838,
+ "served": 4740,
+ "server": 36458,
+ "server": 8398,
+ "serverless": 49243,
+ "servers": 22262,
+ "serves": 9915,
+ "servic": 27115,
+ "service": 21496,
+ "service": 2086,
+ "serviced": 44687,
+ "services": 3100,
+ "servicing": 41300,
+ "serving": 5722,
+ "sery": 14279,
+ "ses": 23708,
+ "ses": 1386,
+ "sesame": 21706,
+ "sese": 37128,
+ "sesh": 24274,
+ "session": 2550,
+ "sessions": 6327,
+ "set": 7965,
+ "set": 1167,
+ "setback": 43605,
+ "seth": 20005,
+ "seth": 11870,
+ "sethu": 38933,
+ "setlist": 33141,
+ "seton": 43799,
+ "sets": 4650,
+ "sett": 4984,
+ "sett": 17567,
+ "sette": 14613,
+ "setter": 23153,
+ "settes": 44145,
+ "setti": 45170,
+ "setting": 5264,
+ "settings": 18628,
+ "settle": 15075,
+ "settled": 18310,
+ "settlement": 16494,
+ "settlements": 36605,
+ "settlers": 35671,
+ "settles": 41498,
+ "settling": 22036,
+ "setup": 11092,
+ "seu": 31539,
+ "seul": 48975,
+ "seum": 18838,
+ "seun": 24209,
+ "seung": 32393,
+ "seung": 33711,
+ "seungri": 41627,
+ "seuss": 34441,
+ "sev": 26585,
+ "sev": 37600,
+ "seva": 42604,
+ "seve": 21458,
+ "seve": 22468,
+ "sevel": 17439,
+ "seven": 7874,
+ "seven": 5757,
+ "sevens": 29911,
+ "sevent": 43048,
+ "seventeen": 19337,
+ "seventh": 17568,
+ "seventy": 47170,
+ "sever": 3250,
+ "sever": 45557,
+ "several": 5560,
+ "severance": 26194,
+ "severe": 6215,
+ "severely": 24417,
+ "severn": 34626,
+ "severy": 34207,
+ "sevilla": 24947,
+ "seville": 34988,
+ "sew": 28640,
+ "sewage": 32777,
+ "sewer": 28294,
+ "sewing": 15974,
+ "sewn": 42118,
+ "sex": 3548,
+ "sex": 5937,
+ "sexi": 20562,
+ "sexiest": 25426,
+ "sexism": 32059,
+ "sexist": 33047,
+ "sexu": 14741,
+ "sexual": 6749,
+ "sexuality": 21244,
+ "sexually": 23032,
+ "sexy": 21019,
+ "sexy": 38127,
+ "sey": 6317,
+ "sey": 2258,
+ "seychel": 36809,
+ "seychelles": 38519,
+ "seye": 35604,
+ "seym": 22657,
+ "seymour": 25850,
+ "seys": 15081,
+ "sez": 42377,
+ "señ": 43368,
+ "sf": 4435,
+ "sf": 4915,
+ "sfa": 32675,
+ "sfam": 37649,
+ "sfb": 27930,
+ "sfc": 14129,
+ "sfest": 49024,
+ "sff": 42056,
+ "sfgiants": 20923,
+ "sfield": 11801,
+ "sfo": 39182,
+ "sfootball": 45259,
+ "sfor": 9115,
+ "sford": 28917,
+ "sforsale": 28888,
+ "sfw": 18073,
+ "sfx": 37995,
+ "sg": 9599,
+ "sg": 7611,
+ "sga": 33049,
+ "sgate": 27558,
+ "sgh": 47590,
+ "sgo": 5393,
+ "sgo": 21044,
+ "sgt": 13748,
+ "sh": 552,
+ "sh": 849,
+ "sha": 1514,
+ "sha": 3337,
+ "shaa": 44221,
+ "shab": 8323,
+ "shabbat": 38042,
+ "shabby": 28838,
+ "shack": 23866,
+ "shack": 18785,
+ "shad": 3182,
+ "shad": 23874,
+ "shade": 34554,
+ "shade": 10097,
+ "shaded": 43506,
+ "shades": 46608,
+ "shades": 9270,
+ "shadesof": 45180,
+ "shading": 37348,
+ "shado": 9325,
+ "shadow": 15243,
+ "shadow": 7068,
+ "shadowhun": 19931,
+ "shadowhunters": 24834,
+ "shadowing": 46092,
+ "shadows": 12971,
+ "shady": 22158,
+ "shaf": 12032,
+ "shaft": 21545,
+ "shag": 22439,
+ "shaggy": 42662,
+ "shah": 13203,
+ "shah": 8439,
+ "shahe": 23643,
+ "shaheed": 30060,
+ "shaheer": 43969,
+ "shahi": 46972,
+ "shahid": 25696,
+ "shahid": 27138,
+ "shahidkapoor": 29892,
+ "shahzad": 45915,
+ "shai": 47941,
+ "shaikh": 45712,
+ "shail": 37603,
+ "shair": 43135,
+ "shak": 8385,
+ "shake": 8206,
+ "shake": 8251,
+ "shaken": 38237,
+ "shaker": 26210,
+ "shakers": 38411,
+ "shakes": 19668,
+ "shakespe": 9890,
+ "shakespeare": 22499,
+ "shakespeare": 12488,
+ "shakespearesunday": 32320,
+ "shaking": 19101,
+ "shakira": 40795,
+ "shakti": 48593,
+ "shakti": 32458,
+ "shakur": 48915,
+ "shal": 15056,
+ "shal": 28175,
+ "shale": 32864,
+ "shall": 4742,
+ "shallow": 23730,
+ "shalom": 31339,
+ "sham": 6453,
+ "sham": 9005,
+ "shaman": 48727,
+ "shambles": 40799,
+ "shame": 14776,
+ "shame": 7593,
+ "shameful": 28283,
+ "shameless": 25380,
+ "shaming": 40553,
+ "shampoo": 23944,
+ "shamrock": 34199,
+ "shan": 5171,
+ "shan": 8834,
+ "shana": 44835,
+ "shand": 29101,
+ "shane": 26863,
+ "shane": 11572,
+ "shang": 11141,
+ "shanghai": 12742,
+ "shani": 46665,
+ "shank": 24685,
+ "shankar": 24108,
+ "shann": 9932,
+ "shannon": 22842,
+ "shannon": 13581,
+ "shant": 36610,
+ "shap": 5581,
+ "shape": 26925,
+ "shape": 6448,
+ "shaped": 10127,
+ "shapes": 15377,
+ "shaping": 18632,
+ "shapiro": 32110,
+ "shaq": 46402,
+ "shaq": 26843,
+ "shar": 1669,
+ "shar": 36542,
+ "shara": 48849,
+ "sharapo": 36489,
+ "sharapova": 36671,
+ "shard": 42207,
+ "share": 7585,
+ "share": 1978,
+ "shared": 5368,
+ "shareholder": 38241,
+ "shareholders": 34778,
+ "sharepoint": 39213,
+ "shares": 4974,
+ "sharethe": 49277,
+ "shareyour": 45890,
+ "shari": 27738,
+ "shari": 47390,
+ "sharia": 37244,
+ "sharif": 15501,
+ "sharing": 3567,
+ "sharjah": 33420,
+ "shark": 15836,
+ "shark": 7980,
+ "sharks": 10047,
+ "sharkweek": 39571,
+ "sharma": 10105,
+ "sharon": 28722,
+ "sharon": 14138,
+ "sharp": 17126,
+ "sharp": 8157,
+ "sharpe": 34374,
+ "sharpen": 41465,
+ "sharpie": 46858,
+ "sharply": 37185,
+ "shasta": 46727,
+ "shat": 12169,
+ "shat": 44388,
+ "shatter": 45008,
+ "shattered": 26820,
+ "shau": 13750,
+ "shaun": 23446,
+ "shaun": 16669,
+ "shav": 11410,
+ "shave": 17735,
+ "shaved": 25571,
+ "shaving": 24261,
+ "shaw": 6122,
+ "shaw": 6805,
+ "shawa": 46413,
+ "shawl": 35132,
+ "shawn": 16677,
+ "shawn": 10970,
+ "shawnee": 48060,
+ "shawnmendes": 27277,
+ "shawty": 38026,
+ "shay": 10778,
+ "shay": 18361,
+ "shaykh": 47223,
+ "shaz": 18618,
+ "shazam": 29063,
+ "shc": 43419,
+ "shd": 37729,
+ "she": 1729,
+ "she": 1043,
+ "shea": 20407,
+ "shead": 44287,
+ "shead": 20434,
+ "shealth": 41743,
+ "shealth": 22197,
+ "shear": 27974,
+ "shear": 32108,
+ "shearer": 40505,
+ "sheath": 45637,
+ "shed": 16586,
+ "shed": 1492,
+ "shedding": 33608,
+ "sheds": 25921,
+ "shee": 23450,
+ "shee": 34321,
+ "sheed": 26105,
+ "sheehan": 41809,
+ "sheen": 25025,
+ "sheep": 23604,
+ "sheep": 9629,
+ "sheer": 17577,
+ "sheeran": 18561,
+ "sheet": 7298,
+ "sheets": 12744,
+ "shef": 8237,
+ "sheff": 38844,
+ "sheff": 43821,
+ "sheffiel": 26940,
+ "sheffield": 41763,
+ "sheffield": 10420,
+ "sheffieldissuper": 33628,
+ "sheh": 31667,
+ "sheikh": 15031,
+ "sheil": 42765,
+ "sheila": 25734,
+ "shek": 33285,
+ "shel": 3159,
+ "shelby": 36906,
+ "shelby": 16885,
+ "sheldon": 25079,
+ "shelf": 10955,
+ "shell": 23374,
+ "shell": 6648,
+ "shelley": 22497,
+ "shelling": 43166,
+ "shells": 19265,
+ "shelly": 37461,
+ "shelter": 8599,
+ "sheltered": 48070,
+ "shelters": 24312,
+ "shelton": 24471,
+ "shelves": 16225,
+ "shem": 40299,
+ "shen": 10154,
+ "shen": 31098,
+ "shenan": 20965,
+ "shenando": 44666,
+ "shenanigans": 26590,
+ "shenko": 39751,
+ "shenmue": 48279,
+ "shenzhen": 38970,
+ "shep": 33757,
+ "shep": 44857,
+ "shepard": 26810,
+ "shepher": 11008,
+ "shepherd": 13242,
+ "shepherds": 42792,
+ "sheppard": 37304,
+ "sher": 3570,
+ "sher": 4510,
+ "sheraton": 39400,
+ "shere": 21507,
+ "sheri": 9235,
+ "sheridan": 27085,
+ "sheriff": 10309,
+ "sherlock": 17294,
+ "sherman": 17822,
+ "sherry": 44348,
+ "sherry": 24689,
+ "shers": 14141,
+ "sherwood": 24527,
+ "sheryl": 39773,
+ "shes": 45514,
+ "shes": 2502,
+ "shet": 15850,
+ "shetland": 29595,
+ "shetty": 25533,
+ "shev": 45182,
+ "sheva": 45132,
+ "shh": 35025,
+ "shhh": 36932,
+ "shi": 823,
+ "shi": 3533,
+ "shia": 23791,
+ "shibu": 36177,
+ "shibuya": 41623,
+ "shie": 26638,
+ "shiel": 33413,
+ "shield": 8670,
+ "shields": 19085,
+ "shies": 35312,
+ "shif": 35317,
+ "shift": 43767,
+ "shift": 6905,
+ "shifted": 34429,
+ "shifter": 48944,
+ "shifting": 21992,
+ "shifts": 23957,
+ "shik": 36980,
+ "shil": 14370,
+ "shill": 32121,
+ "shill": 30090,
+ "shilpa": 47062,
+ "shilpa": 40690,
+ "shim": 11986,
+ "shim": 32780,
+ "shima": 14382,
+ "shimano": 48904,
+ "shimi": 40517,
+ "shimmer": 38792,
+ "shin": 5664,
+ "shin": 11784,
+ "shinde": 41516,
+ "shine": 17582,
+ "shine": 3780,
+ "shinee": 19660,
+ "shines": 16015,
+ "shing": 38641,
+ "shing": 1743,
+ "shining": 10485,
+ "shino": 43074,
+ "shiny": 12190,
+ "ship": 7645,
+ "ship": 1158,
+ "shipment": 28553,
+ "shipp": 34709,
+ "shipped": 15279,
+ "shippers": 44789,
+ "shipping": 5721,
+ "ships": 3262,
+ "shipwreck": 48878,
+ "shipy": 26828,
+ "shipyard": 31273,
+ "shir": 1956,
+ "shiraz": 35618,
+ "shire": 11975,
+ "shire": 2968,
+ "shirehour": 32456,
+ "shirley": 18189,
+ "shiro": 26048,
+ "shirt": 27576,
+ "shirt": 2523,
+ "shirtless": 28959,
+ "shirts": 5803,
+ "shistory": 34979,
+ "shiv": 18042,
+ "shiv": 37121,
+ "shiva": 33881,
+ "shiva": 21174,
+ "shka": 38944,
+ "shld": 49359,
+ "shma": 48074,
+ "shment": 8802,
+ "shments": 18822,
+ "sho": 719,
+ "sho": 13756,
+ "shock": 19617,
+ "shock": 8736,
+ "shocked": 15787,
+ "shocker": 37971,
+ "shockey": 22258,
+ "shocking": 13394,
+ "shocks": 31886,
+ "shoe": 16308,
+ "shoe": 7342,
+ "shoes": 49391,
+ "shoes": 4079,
+ "shol": 21472,
+ "sholm": 44139,
+ "shome": 42701,
+ "shon": 19526,
+ "shon": 37621,
+ "shone": 47173,
+ "shoo": 1975,
+ "shook": 20730,
+ "shoops": 29956,
+ "shoot": 12531,
+ "shoot": 3704,
+ "shooter": 13645,
+ "shooters": 31902,
+ "shooting": 3992,
+ "shootings": 26753,
+ "shootout": 20666,
+ "shoots": 14144,
+ "shop": 5738,
+ "shop": 1557,
+ "shopify": 47949,
+ "shoplocal": 21775,
+ "shopp": 38486,
+ "shoppe": 38236,
+ "shopped": 28088,
+ "shopper": 24346,
+ "shoppers": 22316,
+ "shopping": 42101,
+ "shopping": 4266,
+ "shops": 6467,
+ "shopsmall": 35942,
+ "shor": 3209,
+ "shore": 14717,
+ "shore": 5928,
+ "shored": 33140,
+ "shoreditch": 35042,
+ "shoreline": 34807,
+ "shores": 18102,
+ "short": 6803,
+ "short": 3005,
+ "shortage": 19910,
+ "shortages": 38730,
+ "shortcuts": 45793,
+ "shorten": 41711,
+ "shorter": 20350,
+ "shortest": 33717,
+ "shortfilm": 37204,
+ "shorth": 37397,
+ "shortlist": 28163,
+ "shortlisted": 20631,
+ "shortly": 11967,
+ "shorts": 9680,
+ "shorty": 33502,
+ "shot": 9805,
+ "shot": 2000,
+ "shotel": 42365,
+ "shotgun": 21643,
+ "shots": 5342,
+ "shou": 3890,
+ "shoul": 29847,
+ "should": 14947,
+ "should": 1535,
+ "shoulder": 8476,
+ "shoulders": 18738,
+ "shouldn": 9416,
+ "shour": 20025,
+ "shouse": 28671,
+ "shout": 7335,
+ "shout": 5214,
+ "shouted": 44397,
+ "shouting": 26464,
+ "shoutout": 8274,
+ "shouts": 26709,
+ "shovel": 31778,
+ "show": 2133,
+ "show": 1080,
+ "showbiz": 34156,
+ "showcas": 14290,
+ "showcase": 7265,
+ "showcased": 35786,
+ "showcases": 26266,
+ "showcasing": 17036,
+ "showdown": 15576,
+ "showed": 7150,
+ "shower": 7777,
+ "showers": 9893,
+ "showing": 3649,
+ "shown": 8506,
+ "showroom": 16821,
+ "shows": 2665,
+ "showtime": 40576,
+ "showtime": 15442,
+ "showyour": 46733,
+ "shp": 38341,
+ "shq": 21145,
+ "shr": 10118,
+ "shra": 21360,
+ "shradd": 28172,
+ "shraddha": 35208,
+ "shraddhakapoor": 40385,
+ "shre": 12101,
+ "shred": 19756,
+ "shred": 33017,
+ "shredded": 31772,
+ "shredding": 45534,
+ "shree": 37410,
+ "shrek": 35009,
+ "shrews": 26411,
+ "shrewsbury": 30921,
+ "shri": 8838,
+ "shri": 11424,
+ "shrimp": 12727,
+ "shrin": 24865,
+ "shrine": 16156,
+ "shrink": 34957,
+ "shrinking": 41243,
+ "shrm": 44163,
+ "shro": 15259,
+ "shroff": 32081,
+ "shrop": 22630,
+ "shropshire": 26344,
+ "shru": 14911,
+ "shrub": 41464,
+ "shrubs": 47975,
+ "shrun": 46767,
+ "shs": 16184,
+ "sht": 44210,
+ "shti": 38927,
+ "shu": 2872,
+ "shu": 17651,
+ "shua": 33771,
+ "shub": 40552,
+ "shud": 45782,
+ "shuff": 42641,
+ "shuffle": 21681,
+ "shui": 45473,
+ "shuk": 29927,
+ "shukla": 46829,
+ "shul": 30721,
+ "shum": 37383,
+ "shun": 24479,
+ "shun": 39594,
+ "shur": 41032,
+ "shut": 8702,
+ "shut": 8282,
+ "shutdown": 16051,
+ "shutout": 24385,
+ "shuts": 28313,
+ "shutt": 31866,
+ "shutter": 36235,
+ "shutter": 33902,
+ "shutters": 46894,
+ "shutting": 31383,
+ "shuttle": 15842,
+ "shwar": 41640,
+ "shy": 22678,
+ "shy": 9682,
+ "si": 564,
+ "si": 2990,
+ "sia": 2357,
+ "siam": 29686,
+ "siam": 48248,
+ "siamese": 43161,
+ "sian": 28510,
+ "sian": 6221,
+ "sians": 26583,
+ "sias": 28645,
+ "siber": 22206,
+ "siberia": 39969,
+ "siberian": 34058,
+ "sibl": 14338,
+ "sible": 14507,
+ "sibling": 43060,
+ "sibling": 23779,
+ "siblings": 17156,
+ "sic": 8278,
+ "sic": 1118,
+ "sica": 34125,
+ "sical": 33875,
+ "sichuan": 48950,
+ "sicilian": 45292,
+ "sicily": 23179,
+ "sick": 11143,
+ "sick": 5359,
+ "sickest": 47972,
+ "sickle": 41459,
+ "sickness": 28898,
+ "sics": 26297,
+ "sid": 10117,
+ "sid": 15119,
+ "sidd": 19842,
+ "siddi": 35227,
+ "side": 5869,
+ "side": 1145,
+ "sided": 21061,
+ "sidekick": 44683,
+ "sidel": 43557,
+ "sideline": 32056,
+ "sidelines": 31046,
+ "sider": 30581,
+ "siders": 41249,
+ "sides": 7578,
+ "sideshow": 46789,
+ "sidewalk": 23278,
+ "sidewalks": 43583,
+ "sideways": 35593,
+ "siding": 38758,
+ "sidney": 22598,
+ "sie": 8533,
+ "sie": 5685,
+ "sieg": 49203,
+ "siege": 18460,
+ "siegel": 48559,
+ "siem": 18434,
+ "siemens": 30147,
+ "siempre": 44030,
+ "siena": 33336,
+ "sienna": 40373,
+ "sier": 10028,
+ "sier": 7444,
+ "sierra": 13552,
+ "siers": 35923,
+ "sies": 16367,
+ "siest": 18323,
+ "sif": 29300,
+ "sig": 872,
+ "sig": 19145,
+ "sigh": 36303,
+ "sigh": 15505,
+ "sighs": 44579,
+ "sight": 16897,
+ "sight": 6329,
+ "sighted": 33034,
+ "sighting": 17507,
+ "sightings": 30004,
+ "sights": 17364,
+ "sightseeing": 34210,
+ "sigma": 45075,
+ "sigma": 15697,
+ "sign": 5538,
+ "sign": 2292,
+ "signage": 21156,
+ "signal": 10781,
+ "signaling": 38492,
+ "signalling": 48426,
+ "signals": 17150,
+ "signation": 24347,
+ "signature": 9189,
+ "signatures": 21865,
+ "signed": 3163,
+ "signee": 39778,
+ "signi": 34023,
+ "signific": 6374,
+ "significance": 23769,
+ "significant": 8735,
+ "significantly": 16187,
+ "signing": 4401,
+ "signingday": 40282,
+ "signings": 27731,
+ "signs": 4659,
+ "signup": 40791,
+ "sigue": 49401,
+ "sii": 36672,
+ "sik": 19974,
+ "sik": 22413,
+ "sika": 31144,
+ "sikh": 21829,
+ "sikhs": 45426,
+ "sil": 1556,
+ "sil": 8315,
+ "sila": 41754,
+ "sile": 37620,
+ "silen": 39048,
+ "silence": 8462,
+ "silenced": 45415,
+ "silent": 30352,
+ "silent": 8487,
+ "silently": 42640,
+ "silhou": 20589,
+ "silhouette": 26149,
+ "silic": 23830,
+ "silicon": 32412,
+ "silicon": 17888,
+ "silicone": 28221,
+ "silk": 25891,
+ "silk": 9743,
+ "silky": 29554,
+ "sill": 42468,
+ "sill": 48024,
+ "silly": 11883,
+ "silon": 31841,
+ "sils": 39708,
+ "silva": 16489,
+ "silve": 37697,
+ "silver": 7525,
+ "silver": 3467,
+ "silverado": 46160,
+ "silverstone": 29666,
+ "silvia": 37289,
+ "sim": 5026,
+ "sim": 10740,
+ "sima": 35871,
+ "simba": 39492,
+ "simcoe": 47148,
+ "sime": 28329,
+ "simi": 38073,
+ "simil": 7202,
+ "similar": 8547,
+ "similarities": 34716,
+ "simm": 13001,
+ "simmons": 14699,
+ "simo": 37171,
+ "simon": 8796,
+ "simon": 6668,
+ "simona": 46277,
+ "simone": 19062,
+ "simons": 33097,
+ "simp": 2542,
+ "simple": 19018,
+ "simple": 4129,
+ "simpler": 35489,
+ "simplest": 39588,
+ "simpli": 16868,
+ "simplicity": 21262,
+ "simplified": 36647,
+ "simplify": 35479,
+ "simply": 25637,
+ "simply": 6151,
+ "simpson": 41805,
+ "simpson": 11750,
+ "simpsons": 21092,
+ "sims": 14021,
+ "simul": 9845,
+ "simulated": 46395,
+ "simulation": 18610,
+ "simulator": 20821,
+ "simultaneous": 48816,
+ "simultaneously": 28575,
+ "sin": 1303,
+ "sin": 3421,
+ "sina": 19541,
+ "sinai": 33226,
+ "sinatra": 27262,
+ "sinc": 30464,
+ "since": 1855,
+ "sincere": 24513,
+ "sincere": 24886,
+ "sincerely": 25673,
+ "sinclair": 23100,
+ "sind": 39598,
+ "sind": 30877,
+ "sindh": 20754,
+ "sindia": 48038,
+ "sine": 22741,
+ "sine": 33793,
+ "sinfo": 47178,
+ "sing": 1387,
+ "sing": 1197,
+ "singapo": 27861,
+ "singapore": 28879,
+ "singapore": 6754,
+ "singer": 33880,
+ "singer": 5108,
+ "singers": 15613,
+ "singersongwriter": 44585,
+ "singh": 19445,
+ "singh": 5715,
+ "singing": 5864,
+ "single": 19524,
+ "single": 2688,
+ "singles": 12025,
+ "singleton": 46247,
+ "singly": 16619,
+ "sings": 13635,
+ "singul": 34003,
+ "singular": 44009,
+ "singularity": 48410,
+ "sinha": 29416,
+ "sini": 41781,
+ "sini": 26319,
+ "sinister": 31313,
+ "sink": 37232,
+ "sink": 14551,
+ "sinking": 27949,
+ "sinks": 32710,
+ "sinn": 36315,
+ "sinner": 45380,
+ "sinners": 43436,
+ "sino": 29759,
+ "sins": 9345,
+ "sinthe": 30737,
+ "sinu": 37351,
+ "sinus": 47535,
+ "sio": 10807,
+ "siob": 40954,
+ "siology": 46315,
+ "sion": 5676,
+ "sion": 1015,
+ "sional": 14533,
+ "sionally": 30754,
+ "sions": 4060,
+ "sioux": 44695,
+ "sioux": 24954,
+ "sip": 16096,
+ "sipping": 28527,
+ "sir": 10708,
+ "sir": 3846,
+ "sire": 28450,
+ "siren": 33026,
+ "sirens": 35907,
+ "siri": 13986,
+ "siri": 18394,
+ "sirius": 23574,
+ "sirius": 34999,
+ "siriusxm": 29833,
+ "sirloin": 46828,
+ "sis": 18132,
+ "sis": 2580,
+ "sisd": 27132,
+ "sisi": 37892,
+ "siss": 42929,
+ "sissy": 27564,
+ "sist": 20520,
+ "sista": 37448,
+ "sister": 17417,
+ "sister": 3677,
+ "sisterhood": 37313,
+ "sisters": 6404,
+ "sit": 7387,
+ "sit": 4037,
+ "sitcom": 30426,
+ "site": 26792,
+ "site": 1988,
+ "sites": 7236,
+ "sith": 41499,
+ "sito": 42613,
+ "sits": 12726,
+ "sitt": 42988,
+ "sitter": 40777,
+ "sittin": 40887,
+ "sitting": 4919,
+ "situ": 5562,
+ "situ": 42536,
+ "situated": 22030,
+ "situation": 7144,
+ "situations": 19096,
+ "sity": 38177,
+ "sity": 5477,
+ "siu": 40174,
+ "sium": 8090,
+ "sius": 27595,
+ "siva": 20991,
+ "sivan": 36931,
+ "sive": 23572,
+ "sive": 1875,
+ "sively": 10343,
+ "siveness": 39667,
+ "sives": 23896,
+ "sivity": 42738,
+ "siwon": 29055,
+ "six": 5968,
+ "six": 4093,
+ "sixers": 25941,
+ "sixteen": 28677,
+ "sixth": 12909,
+ "sixties": 44948,
+ "sixty": 32588,
+ "siya": 44440,
+ "size": 38377,
+ "size": 3235,
+ "sized": 9832,
+ "sizes": 10253,
+ "sizing": 28330,
+ "sizz": 23778,
+ "sizzle": 47890,
+ "sizzling": 35799,
+ "sj": 7536,
+ "sj": 16010,
+ "sjo": 42012,
+ "sk": 909,
+ "sk": 2058,
+ "ska": 7495,
+ "skag": 31948,
+ "skan": 46772,
+ "skar": 27587,
+ "skar": 26835,
+ "skate": 13740,
+ "skate": 12745,
+ "skateboard": 31777,
+ "skateboarding": 31352,
+ "skater": 30337,
+ "skaters": 39824,
+ "skates": 31479,
+ "skc": 44551,
+ "ske": 6261,
+ "ske": 25516,
+ "skel": 36564,
+ "skelet": 27075,
+ "skeletal": 37369,
+ "skeleton": 20062,
+ "skeletons": 48874,
+ "skell": 40801,
+ "skep": 27772,
+ "skeptical": 44934,
+ "sker": 37640,
+ "sker": 33600,
+ "sket": 3744,
+ "sketch": 11767,
+ "sketch": 5269,
+ "sketchbook": 18899,
+ "sketched": 38581,
+ "sketches": 17622,
+ "sketching": 23228,
+ "sketchy": 41582,
+ "skey": 37453,
+ "ski": 3327,
+ "ski": 3428,
+ "skid": 36574,
+ "skid": 32099,
+ "skier": 42585,
+ "skies": 7244,
+ "skiing": 14400,
+ "skil": 24543,
+ "skill": 15598,
+ "skill": 10604,
+ "skilled": 17535,
+ "skillet": 40568,
+ "skills": 4113,
+ "skim": 33191,
+ "skin": 5821,
+ "skin": 3575,
+ "skincare": 12648,
+ "skine": 37300,
+ "sking": 46215,
+ "skinned": 42199,
+ "skinner": 30261,
+ "skinny": 42729,
+ "skinny": 15457,
+ "skins": 11594,
+ "skip": 39793,
+ "skip": 14296,
+ "skipped": 40639,
+ "skipper": 22226,
+ "skipping": 34867,
+ "skir": 8919,
+ "skirt": 12386,
+ "skirts": 24840,
+ "skis": 32843,
+ "skit": 43573,
+ "skitchen": 42820,
+ "skittles": 43213,
+ "sko": 15141,
+ "sko": 23493,
+ "skoda": 38668,
+ "skool": 26743,
+ "skril": 43149,
+ "skrillex": 43651,
+ "sks": 48136,
+ "sku": 10836,
+ "skul": 17561,
+ "skull": 34068,
+ "skull": 12092,
+ "skulls": 31804,
+ "skunk": 42194,
+ "sky": 3075,
+ "sky": 2390,
+ "skybet": 45540,
+ "skye": 21475,
+ "skyl": 43554,
+ "skylar": 45411,
+ "skyline": 14606,
+ "skymap": 41734,
+ "skynews": 40977,
+ "skype": 17069,
+ "skyrim": 33693,
+ "skysports": 39845,
+ "skysports": 46725,
+ "skywalker": 32936,
+ "sl": 2621,
+ "sl": 7489,
+ "sla": 2725,
+ "sla": 26707,
+ "slab": 24241,
+ "slabs": 42818,
+ "slack": 37108,
+ "slack": 30142,
+ "slade": 33546,
+ "slain": 35972,
+ "slalom": 43540,
+ "slam": 14891,
+ "slam": 10131,
+ "slammed": 29772,
+ "slams": 18907,
+ "slan": 44663,
+ "slan": 47193,
+ "sland": 11294,
+ "slang": 33655,
+ "slap": 48830,
+ "slap": 21751,
+ "slapped": 38861,
+ "slaps": 46796,
+ "slash": 19749,
+ "slat": 38966,
+ "slate": 17919,
+ "slated": 36094,
+ "slater": 25968,
+ "slaugh": 26782,
+ "slaughter": 19815,
+ "slaughtered": 46615,
+ "slav": 47292,
+ "slava": 41797,
+ "slave": 14029,
+ "slavery": 15754,
+ "slaves": 23833,
+ "slaw": 28178,
+ "slay": 48319,
+ "slay": 19380,
+ "slayed": 44870,
+ "slayer": 21605,
+ "slaying": 27812,
+ "slays": 45648,
+ "slc": 21972,
+ "sle": 1709,
+ "sleague": 23336,
+ "sled": 28438,
+ "sledge": 48750,
+ "slee": 17642,
+ "slee": 38977,
+ "sleek": 23187,
+ "sleep": 4656,
+ "sleep": 3840,
+ "sleeper": 28709,
+ "sleeping": 6982,
+ "sleepless": 39779,
+ "sleepover": 39415,
+ "sleeps": 16610,
+ "sleepy": 32572,
+ "sleepy": 14497,
+ "sleet": 36948,
+ "sleeve": 35270,
+ "sleeve": 10536,
+ "sleeveless": 38049,
+ "sleeves": 19691,
+ "sleg": 47650,
+ "sleigh": 30865,
+ "slender": 40331,
+ "slept": 20388,
+ "sler": 14066,
+ "sley": 17198,
+ "sley": 6496,
+ "sli": 1811,
+ "sli": 44824,
+ "slic": 19692,
+ "slice": 13431,
+ "sliced": 28121,
+ "slices": 28424,
+ "slick": 18341,
+ "slide": 27828,
+ "slide": 8837,
+ "slider": 37861,
+ "sliders": 40700,
+ "slides": 15939,
+ "slideshow": 42817,
+ "sliding": 21468,
+ "slife": 15448,
+ "sliga": 21080,
+ "slight": 14297,
+ "slightly": 8456,
+ "sligo": 30424,
+ "slike": 38744,
+ "slim": 35226,
+ "slim": 12364,
+ "slime": 29107,
+ "sling": 28021,
+ "sling": 32607,
+ "slinger": 47269,
+ "slions": 43363,
+ "slip": 39785,
+ "slip": 12105,
+ "slipknot": 41816,
+ "slipped": 30344,
+ "slipper": 39644,
+ "slippers": 26509,
+ "slippery": 30814,
+ "slipping": 36301,
+ "slips": 30632,
+ "slist": 33749,
+ "slit": 47011,
+ "slive": 31652,
+ "slo": 4303,
+ "slo": 36083,
+ "sloan": 29110,
+ "sloane": 41553,
+ "slogan": 23398,
+ "slogans": 42795,
+ "slope": 22769,
+ "slopes": 24066,
+ "sloppy": 36154,
+ "slot": 14500,
+ "sloth": 30007,
+ "slots": 19238,
+ "slou": 48493,
+ "slovak": 23315,
+ "slovakia": 25994,
+ "sloven": 17018,
+ "slovenia": 21037,
+ "slow": 6674,
+ "slow": 5444,
+ "slowdown": 38421,
+ "slowed": 43793,
+ "slower": 29181,
+ "slowing": 29839,
+ "slowly": 9568,
+ "slows": 46855,
+ "slp": 45599,
+ "slr": 21325,
+ "sls": 33651,
+ "slt": 39283,
+ "sltd": 36388,
+ "slu": 7224,
+ "slu": 47456,
+ "slug": 34190,
+ "slugger": 48671,
+ "slum": 46754,
+ "slumber": 44295,
+ "slump": 35588,
+ "slur": 30476,
+ "slush": 39815,
+ "slv": 45526,
+ "sly": 28145,
+ "sly": 21062,
+ "sm": 978,
+ "sm": 2764,
+ "sma": 4357,
+ "sma": 11854,
+ "smack": 21280,
+ "smack": 30026,
+ "smackdown": 26138,
+ "smafia": 47686,
+ "smag": 32212,
+ "smal": 48379,
+ "small": 5244,
+ "small": 2442,
+ "smallbiz": 41724,
+ "smallbiz": 18987,
+ "smallbusiness": 21316,
+ "smalle": 18490,
+ "smaller": 12431,
+ "smallest": 18686,
+ "smalls": 41696,
+ "sman": 9612,
+ "smar": 3201,
+ "smart": 5383,
+ "smart": 4115,
+ "smartcities": 34822,
+ "smartcity": 33973,
+ "smarter": 18990,
+ "smartest": 37092,
+ "smarthome": 47726,
+ "smartphone": 11290,
+ "smartphones": 22212,
+ "smartwatch": 35798,
+ "smash": 17258,
+ "smash": 10332,
+ "smashbros": 44897,
+ "smashed": 18410,
+ "smashes": 45657,
+ "smashing": 19632,
+ "smatter": 16537,
+ "smb": 30446,
+ "smc": 31375,
+ "smc": 28312,
+ "smd": 34582,
+ "sme": 11758,
+ "sme": 15650,
+ "smear": 37546,
+ "smel": 28476,
+ "smell": 9688,
+ "smelling": 32493,
+ "smells": 14668,
+ "smelly": 46145,
+ "smen": 15961,
+ "smer": 48526,
+ "smere": 39629,
+ "smes": 26141,
+ "smg": 46876,
+ "smh": 9623,
+ "smi": 5655,
+ "smi": 40049,
+ "smil": 33937,
+ "smile": 27641,
+ "smile": 3490,
+ "smiled": 34362,
+ "smiles": 8726,
+ "smiley": 22925,
+ "smiling": 9200,
+ "smir": 24667,
+ "smith": 10527,
+ "smith": 2915,
+ "smiths": 27872,
+ "smithson": 25372,
+ "smithsonian": 31209,
+ "smm": 19510,
+ "smma": 42370,
+ "smo": 2513,
+ "smo": 13437,
+ "smobile": 38923,
+ "smog": 44425,
+ "smoke": 20381,
+ "smoke": 6664,
+ "smoked": 11161,
+ "smoker": 32348,
+ "smokers": 29571,
+ "smokes": 40336,
+ "smokey": 23670,
+ "smokin": 32825,
+ "smoking": 9038,
+ "smoky": 25549,
+ "smol": 29939,
+ "smol": 40403,
+ "smoo": 5430,
+ "smooth": 10958,
+ "smooth": 8990,
+ "smoother": 44271,
+ "smoothie": 16668,
+ "smoothies": 34458,
+ "smoothly": 32380,
+ "smore": 48323,
+ "smp": 32260,
+ "smriti": 49227,
+ "sms": 10409,
+ "smt": 26672,
+ "smtown": 26072,
+ "smu": 10878,
+ "smu": 30458,
+ "smug": 41021,
+ "smugg": 28130,
+ "smuggling": 34146,
+ "smur": 24708,
+ "smusic": 19191,
+ "smw": 44929,
+ "smx": 46699,
+ "smy": 14381,
+ "smyth": 44822,
+ "sn": 1672,
+ "sn": 5844,
+ "sna": 4032,
+ "snack": 47548,
+ "snack": 10039,
+ "snacking": 46474,
+ "snacks": 12349,
+ "snag": 34789,
+ "snag": 28043,
+ "snagged": 48534,
+ "snail": 23132,
+ "snails": 34928,
+ "snake": 30133,
+ "snake": 8798,
+ "snakes": 19605,
+ "snap": 4578,
+ "snap": 7404,
+ "snapback": 31234,
+ "snapchat": 7799,
+ "snapmatic": 45907,
+ "snapp": 10185,
+ "snapped": 15543,
+ "snapper": 31677,
+ "snapping": 31581,
+ "snaps": 16890,
+ "snapshot": 18243,
+ "snar": 30810,
+ "snare": 40651,
+ "snat": 18457,
+ "snatch": 35302,
+ "snatched": 44821,
+ "snation": 14362,
+ "snazzy": 48963,
+ "snc": 39918,
+ "sne": 3791,
+ "sne": 46503,
+ "sneak": 27871,
+ "sneak": 6917,
+ "sneaker": 31698,
+ "sneaker": 24781,
+ "sneakers": 17397,
+ "sneaking": 34633,
+ "sneakpeek": 47831,
+ "sneaks": 40926,
+ "sneaky": 21293,
+ "snee": 42095,
+ "snell": 46410,
+ "sner": 31424,
+ "snes": 26667,
+ "snews": 18623,
+ "snf": 47651,
+ "sng": 41549,
+ "snhl": 43093,
+ "sni": 7186,
+ "sni": 35570,
+ "snickers": 49127,
+ "sniff": 37841,
+ "snip": 42954,
+ "sniper": 22157,
+ "snippet": 37531,
+ "snippets": 44001,
+ "snl": 16011,
+ "sno": 8567,
+ "sno": 17802,
+ "snoo": 11352,
+ "snooker": 25657,
+ "snoop": 44503,
+ "snoop": 27754,
+ "snoopdogg": 48388,
+ "snoopy": 41967,
+ "snooze": 40718,
+ "snor": 16590,
+ "snoring": 44560,
+ "snorkel": 44285,
+ "snorkeling": 48103,
+ "snow": 3880,
+ "snow": 2583,
+ "snowball": 39254,
+ "snowboard": 33403,
+ "snowboarding": 32397,
+ "snowday": 37982,
+ "snowden": 32154,
+ "snowdon": 47107,
+ "snowdonia": 36088,
+ "snowed": 45073,
+ "snowfall": 21714,
+ "snowflake": 33447,
+ "snowflakes": 38618,
+ "snowing": 21443,
+ "snowman": 22668,
+ "snowstorm": 38777,
+ "snowy": 14191,
+ "snp": 15301,
+ "sns": 36343,
+ "snsd": 27961,
+ "snt": 34834,
+ "snu": 9694,
+ "snuck": 36522,
+ "snug": 45169,
+ "snuggle": 31327,
+ "snuggles": 48165,
+ "sny": 17526,
+ "snyder": 22106,
+ "snz": 37678,
+ "so": 759,
+ "so": 706,
+ "soa": 39584,
+ "soak": 24839,
+ "soaked": 26592,
+ "soaking": 26750,
+ "soap": 26086,
+ "soap": 11088,
+ "soaps": 40958,
+ "soar": 48997,
+ "soar": 22241,
+ "soaring": 27968,
+ "soars": 41348,
+ "sob": 24900,
+ "sob": 35507,
+ "sobbing": 36691,
+ "sober": 30969,
+ "sober": 24487,
+ "sobre": 42768,
+ "sobri": 49308,
+ "sobs": 43636,
+ "soc": 3253,
+ "soc": 7741,
+ "soca": 49239,
+ "socal": 46470,
+ "socal": 20450,
+ "soccer": 16268,
+ "soccer": 4233,
+ "socceroos": 41997,
+ "socent": 30831,
+ "sochi": 21014,
+ "soci": 1720,
+ "social": 4803,
+ "social": 2346,
+ "socialism": 23372,
+ "socialist": 18450,
+ "socialists": 43839,
+ "socially": 24555,
+ "socialmedi": 23813,
+ "socialmedia": 9600,
+ "socialmediamarketing": 31790,
+ "societal": 40058,
+ "societies": 25855,
+ "society": 3757,
+ "socio": 44319,
+ "socio": 42790,
+ "sociology": 32373,
+ "sock": 29801,
+ "sock": 18277,
+ "socket": 28657,
+ "socks": 8774,
+ "socorro": 46409,
+ "socute": 45086,
+ "sod": 31435,
+ "soda": 13533,
+ "sodium": 29070,
+ "soe": 44136,
+ "soe": 25498,
+ "soever": 34024,
+ "sof": 1571,
+ "sof": 41187,
+ "sofa": 15723,
+ "soff": 35290,
+ "soff": 30684,
+ "sofficial": 20563,
+ "sofi": 41537,
+ "sofia": 18914,
+ "sofinstagram": 17301,
+ "soft": 12778,
+ "soft": 3773,
+ "softball": 8369,
+ "softer": 44462,
+ "softhe": 23127,
+ "softly": 34958,
+ "software": 35941,
+ "software": 5847,
+ "softwitter": 11311,
+ "sog": 44775,
+ "soggy": 41168,
+ "sohn": 49267,
+ "soho": 47749,
+ "soho": 17592,
+ "soi": 40495,
+ "soil": 33417,
+ "soil": 9216,
+ "soils": 34891,
+ "soir": 43427,
+ "sok": 43456,
+ "sol": 1175,
+ "sol": 9941,
+ "sola": 40086,
+ "solace": 42567,
+ "solar": 16990,
+ "solar": 5199,
+ "solareclipse": 44727,
+ "sold": 33116,
+ "sold": 3939,
+ "soldi": 5098,
+ "soldier": 9355,
+ "soldiers": 7547,
+ "sole": 10519,
+ "sole": 8576,
+ "soleil": 33148,
+ "solely": 27913,
+ "solent": 47783,
+ "soles": 22682,
+ "soli": 3911,
+ "solic": 19369,
+ "solicitor": 45647,
+ "solicitors": 46000,
+ "solid": 30626,
+ "solid": 6148,
+ "solidar": 10415,
+ "solidarity": 10983,
+ "solidi": 46136,
+ "solids": 49070,
+ "solihull": 45293,
+ "solit": 37039,
+ "solitaire": 47257,
+ "solitary": 33094,
+ "solitude": 33199,
+ "solo": 17626,
+ "solo": 5797,
+ "soloist": 46391,
+ "solom": 15768,
+ "solomon": 19785,
+ "solos": 44868,
+ "solst": 20298,
+ "solstice": 21359,
+ "solu": 2487,
+ "solution": 4575,
+ "solutions": 5140,
+ "solve": 8917,
+ "solved": 13451,
+ "solves": 42740,
+ "solving": 15581,
+ "som": 734,
+ "som": 10672,
+ "soma": 36170,
+ "somal": 40281,
+ "somali": 26231,
+ "somalia": 17051,
+ "somaliland": 43315,
+ "some": 1132,
+ "some": 836,
+ "somebody": 8305,
+ "someday": 17127,
+ "somehow": 11735,
+ "someone": 2100,
+ "somer": 9656,
+ "somerhalder": 33990,
+ "somerset": 14926,
+ "somerville": 41409,
+ "somes": 38124,
+ "somethin": 33541,
+ "something": 28316,
+ "something": 2006,
+ "sometime": 21464,
+ "sometimes": 4237,
+ "somewhat": 17864,
+ "somewhere": 8119,
+ "somm": 42726,
+ "somme": 30625,
+ "sommer": 44954,
+ "somos": 24951,
+ "son": 1176,
+ "son": 825,
+ "sona": 21249,
+ "sonam": 40096,
+ "sonar": 48235,
+ "sonata": 37009,
+ "sone": 29599,
+ "song": 6868,
+ "song": 2295,
+ "songs": 4641,
+ "songwriter": 13034,
+ "songwriters": 39583,
+ "songwriting": 33567,
+ "songz": 49302,
+ "soni": 34899,
+ "soni": 35911,
+ "sonia": 20409,
+ "sonic": 23785,
+ "sonic": 9132,
+ "sonics": 48511,
+ "sonja": 46102,
+ "sonline": 23412,
+ "sonny": 43000,
+ "sonny": 20880,
+ "sono": 44109,
+ "sonom": 48596,
+ "sonoma": 26269,
+ "sons": 5502,
+ "sonsof": 46676,
+ "sont": 31063,
+ "sonthe": 40923,
+ "sony": 16042,
+ "sony": 8748,
+ "sonya": 39172,
+ "soo": 5517,
+ "soo": 8602,
+ "soom": 39771,
+ "soon": 27559,
+ "soon": 1745,
+ "sooner": 18968,
+ "sooners": 30449,
+ "sooo": 11526,
+ "soooo": 13658,
+ "sooooo": 21199,
+ "soooooo": 34859,
+ "soor": 46698,
+ "soothe": 44424,
+ "soothing": 27730,
+ "sop": 3974,
+ "sop": 19194,
+ "soph": 34963,
+ "sophi": 6192,
+ "sophia": 16790,
+ "sophie": 38648,
+ "sophie": 12357,
+ "sophistic": 17646,
+ "sophisticated": 20833,
+ "sophom": 13696,
+ "sophomore": 15242,
+ "sophomores": 47645,
+ "soprano": 28880,
+ "soproud": 44479,
+ "sor": 1852,
+ "sor": 16872,
+ "sora": 38719,
+ "sorbet": 39994,
+ "sore": 43330,
+ "sore": 15454,
+ "sored": 6731,
+ "soren": 38907,
+ "sorg": 28152,
+ "sori": 38588,
+ "sorority": 30059,
+ "soros": 33248,
+ "sorren": 44012,
+ "sorrow": 28020,
+ "sorrows": 47924,
+ "sorry": 25745,
+ "sorry": 3675,
+ "sorrynotsorry": 37105,
+ "sort": 8450,
+ "sorta": 34700,
+ "sorted": 13221,
+ "sorting": 19198,
+ "sorts": 12577,
+ "sory": 16257,
+ "sos": 25145,
+ "sos": 5792,
+ "sosa": 45433,
+ "sosfam": 47709,
+ "sot": 41542,
+ "sot": 34116,
+ "sothe": 32145,
+ "sotho": 45496,
+ "soto": 27947,
+ "sotto": 26047,
+ "sotu": 32286,
+ "sou": 1101,
+ "sou": 24293,
+ "sought": 18874,
+ "soul": 8701,
+ "soul": 3755,
+ "soulful": 30196,
+ "soulmate": 38130,
+ "souls": 10951,
+ "soun": 19474,
+ "sound": 5236,
+ "sound": 3608,
+ "soundcheck": 31394,
+ "soundcloud": 15190,
+ "sounded": 28287,
+ "sounders": 44933,
+ "sounding": 21351,
+ "sounds": 5694,
+ "soundtrack": 11389,
+ "soup": 7077,
+ "soups": 45052,
+ "sour": 2235,
+ "sour": 12049,
+ "source": 23698,
+ "source": 3634,
+ "sourced": 23340,
+ "sources": 5124,
+ "sourcing": 19574,
+ "sourdough": 29921,
+ "souri": 11674,
+ "sous": 32093,
+ "sousa": 46296,
+ "sout": 38156,
+ "sout": 32732,
+ "south": 2938,
+ "south": 2045,
+ "southafrica": 15184,
+ "southampton": 15767,
+ "southbank": 44173,
+ "southbound": 22932,
+ "southeast": 13942,
+ "southeastern": 26813,
+ "southend": 25583,
+ "souther": 33330,
+ "southern": 17704,
+ "southern": 5036,
+ "southgate": 47262,
+ "southkorea": 43552,
+ "southport": 37446,
+ "southside": 36436,
+ "southsudan": 30419,
+ "southwark": 39098,
+ "southwe": 46443,
+ "southwest": 13320,
+ "southwestern": 30157,
+ "souven": 20210,
+ "souvenir": 24811,
+ "souvenirs": 48460,
+ "souza": 29424,
+ "sov": 29737,
+ "sover": 31876,
+ "sovere": 17736,
+ "sovereign": 29418,
+ "sovereign": 26337,
+ "sovereignty": 31701,
+ "soviet": 14274,
+ "sow": 33089,
+ "sowe": 36130,
+ "soweto": 47070,
+ "sown": 49369,
+ "sox": 39556,
+ "sox": 8657,
+ "soy": 16524,
+ "soy": 15010,
+ "soybean": 34606,
+ "soybeans": 40840,
+ "soyu": 39578,
+ "soyuz": 43842,
+ "sp": 588,
+ "sp": 4393,
+ "spa": 7852,
+ "spa": 6692,
+ "spac": 10336,
+ "space": 7857,
+ "space": 2138,
+ "spacecraft": 25940,
+ "spaces": 9006,
+ "spaceship": 34317,
+ "spacex": 22511,
+ "spacey": 48770,
+ "spacious": 24769,
+ "spad": 45362,
+ "spade": 32562,
+ "spades": 48368,
+ "spaghetti": 18440,
+ "spain": 5083,
+ "spal": 26018,
+ "spam": 29712,
+ "spam": 14624,
+ "span": 4270,
+ "span": 14537,
+ "spandex": 41686,
+ "spani": 16721,
+ "spaniel": 35435,
+ "spanish": 29966,
+ "spanish": 6013,
+ "spann": 25323,
+ "spanning": 38638,
+ "spans": 45407,
+ "spaper": 34548,
+ "spar": 3378,
+ "spar": 34576,
+ "spare": 12615,
+ "spares": 39505,
+ "spark": 9555,
+ "spark": 11047,
+ "sparked": 32647,
+ "sparkle": 18287,
+ "sparkles": 36410,
+ "sparkling": 17893,
+ "sparkly": 30542,
+ "sparks": 15046,
+ "sparky": 47198,
+ "sparring": 42161,
+ "sparrow": 22888,
+ "spart": 10143,
+ "sparta": 38401,
+ "spartan": 26582,
+ "spartan": 24225,
+ "spartans": 20457,
+ "sparty": 36477,
+ "spas": 31714,
+ "spati": 19200,
+ "spatial": 22022,
+ "spaw": 31605,
+ "spawn": 29166,
+ "spay": 40634,
+ "spc": 20492,
+ "spca": 37018,
+ "spd": 37717,
+ "spd": 28307,
+ "spdwy": 45981,
+ "spe": 876,
+ "spe": 36676,
+ "speak": 20599,
+ "speak": 4208,
+ "speake": 46077,
+ "speaker": 25764,
+ "speaker": 4914,
+ "speakers": 7675,
+ "speaking": 3714,
+ "speaks": 5661,
+ "spear": 23277,
+ "spear": 30420,
+ "speare": 43859,
+ "spears": 20242,
+ "spec": 1711,
+ "spec": 18596,
+ "speci": 1969,
+ "special": 11422,
+ "special": 1689,
+ "specialist": 10630,
+ "specialists": 21719,
+ "speciality": 46904,
+ "specialized": 23265,
+ "specializes": 48533,
+ "specially": 4513,
+ "specials": 11983,
+ "specialty": 18262,
+ "species": 6330,
+ "specific": 10528,
+ "specifically": 17174,
+ "specification": 46394,
+ "specifications": 39705,
+ "specified": 48114,
+ "specimen": 30263,
+ "specimens": 42715,
+ "specs": 24093,
+ "spect": 3416,
+ "spectac": 7242,
+ "spectacle": 34342,
+ "spectacular": 8404,
+ "spectator": 32372,
+ "spectators": 39306,
+ "spective": 6633,
+ "spector": 48676,
+ "spectral": 45441,
+ "spectre": 35998,
+ "spectro": 27646,
+ "spectrum": 13532,
+ "specul": 19209,
+ "speculation": 30898,
+ "sped": 38813,
+ "spee": 4050,
+ "speech": 19556,
+ "speech": 4902,
+ "speeches": 25208,
+ "speechless": 23152,
+ "speed": 6860,
+ "speed": 4163,
+ "speeding": 27264,
+ "speeds": 22017,
+ "speedway": 11480,
+ "speedy": 21603,
+ "spel": 41887,
+ "spell": 22784,
+ "spell": 11230,
+ "spelled": 24339,
+ "spelling": 15614,
+ "spells": 25335,
+ "spelt": 38316,
+ "spen": 5087,
+ "spence": 33324,
+ "spencer": 27509,
+ "spencer": 10678,
+ "spend": 4664,
+ "spending": 5961,
+ "spends": 22508,
+ "spent": 4429,
+ "speople": 33035,
+ "sper": 8213,
+ "sper": 15313,
+ "sperm": 35781,
+ "sperson": 22687,
+ "spf": 34973,
+ "spg": 34623,
+ "sph": 28909,
+ "sph": 24684,
+ "sphe": 33691,
+ "spher": 18349,
+ "sphere": 6987,
+ "spheres": 37478,
+ "spheric": 21744,
+ "sphin": 39237,
+ "sphinx": 46487,
+ "spho": 20442,
+ "sphoto": 38594,
+ "sphy": 43808,
+ "spi": 3174,
+ "spi": 37080,
+ "spic": 17264,
+ "spice": 29761,
+ "spice": 10141,
+ "spiced": 24267,
+ "spicer": 37627,
+ "spices": 21194,
+ "spicy": 10915,
+ "spide": 36801,
+ "spider": 11963,
+ "spider": 7622,
+ "spiderman": 39808,
+ "spiderman": 18427,
+ "spiders": 23141,
+ "spidey": 41706,
+ "spie": 28573,
+ "spie": 28746,
+ "spied": 43998,
+ "spiegel": 45351,
+ "spiel": 28435,
+ "spiel": 37690,
+ "spielberg": 37569,
+ "spies": 25374,
+ "spieth": 43254,
+ "spike": 35306,
+ "spike": 15310,
+ "spiked": 47014,
+ "spikes": 29582,
+ "spil": 47765,
+ "spill": 43933,
+ "spill": 18006,
+ "spilled": 33206,
+ "spilling": 49006,
+ "spills": 35796,
+ "spin": 6288,
+ "spin": 9226,
+ "spinach": 14747,
+ "spinal": 23925,
+ "spine": 48221,
+ "spine": 19646,
+ "sping": 47113,
+ "spinner": 29924,
+ "spinning": 13987,
+ "spino": 40848,
+ "spinoff": 42513,
+ "spinrilla": 46064,
+ "spins": 27243,
+ "spion": 39604,
+ "spionage": 41838,
+ "spir": 3745,
+ "spiral": 19873,
+ "spiration": 38126,
+ "spire": 27439,
+ "spired": 40650,
+ "spires": 46938,
+ "spiri": 4024,
+ "spirit": 18224,
+ "spirit": 4071,
+ "spirited": 34701,
+ "spirits": 13192,
+ "spiritu": 7237,
+ "spiritual": 46076,
+ "spiritual": 9473,
+ "spirituality": 22165,
+ "spiro": 40085,
+ "spit": 18115,
+ "spit": 23177,
+ "spite": 26060,
+ "spitfire": 31126,
+ "spitting": 40721,
+ "spl": 2470,
+ "spl": 33052,
+ "spla": 4809,
+ "splac": 16059,
+ "splace": 38743,
+ "splash": 43641,
+ "splash": 11879,
+ "splat": 15733,
+ "splatoon": 22565,
+ "splay": 3169,
+ "splen": 18552,
+ "splend": 29861,
+ "splendid": 21016,
+ "splendor": 46262,
+ "splin": 38090,
+ "split": 25443,
+ "split": 9109,
+ "splits": 34897,
+ "splitting": 37210,
+ "splus": 40866,
+ "spn": 35467,
+ "spn": 19414,
+ "spnfamily": 38566,
+ "spo": 1261,
+ "spo": 21085,
+ "spock": 43918,
+ "spoil": 25600,
+ "spoiled": 21399,
+ "spoiler": 16512,
+ "spoilers": 18326,
+ "spoils": 42436,
+ "spoilt": 35358,
+ "spokane": 24528,
+ "spoke": 13890,
+ "spoke": 6518,
+ "spoken": 12979,
+ "spokesman": 31632,
+ "spokesperson": 26234,
+ "spol": 22476,
+ "spol": 8132,
+ "spoli": 34301,
+ "spolice": 37406,
+ "spon": 1715,
+ "spon": 48216,
+ "sponge": 22861,
+ "sponge": 24345,
+ "spongebob": 25089,
+ "spons": 5597,
+ "sponsor": 10424,
+ "sponsor": 7574,
+ "sponsored": 7197,
+ "sponsoring": 16181,
+ "sponsors": 11005,
+ "sponsorship": 17632,
+ "spontaneous": 32465,
+ "spoo": 11248,
+ "spooky": 15369,
+ "spool": 49152,
+ "spoon": 27001,
+ "spoon": 14024,
+ "spoons": 29661,
+ "spor": 1475,
+ "spor": 33746,
+ "sport": 4379,
+ "sport": 2364,
+ "sporting": 32620,
+ "sporting": 8944,
+ "sports": 6436,
+ "sports": 2054,
+ "sportsc": 40114,
+ "sportscar": 46931,
+ "sportscenter": 39157,
+ "sportsman": 39020,
+ "sportsmanship": 34858,
+ "sportsnet": 34144,
+ "sportswear": 39747,
+ "sporty": 33346,
+ "spot": 3223,
+ "spot": 3049,
+ "spotify": 7193,
+ "spotlight": 7901,
+ "spots": 7670,
+ "spotted": 4533,
+ "spotter": 30742,
+ "spotting": 15885,
+ "spouse": 24724,
+ "spout": 48993,
+ "spp": 47567,
+ "spr": 1536,
+ "spr": 19417,
+ "spra": 12966,
+ "spraw": 46590,
+ "spray": 37885,
+ "spray": 10449,
+ "sprayed": 40022,
+ "spraying": 39224,
+ "spre": 18740,
+ "spread": 20620,
+ "spread": 5284,
+ "spreading": 11821,
+ "spreads": 27579,
+ "spree": 21851,
+ "spri": 35498,
+ "spride": 26685,
+ "spring": 5166,
+ "spring": 2420,
+ "springbreak": 37753,
+ "springer": 30117,
+ "springfield": 16599,
+ "springs": 7308,
+ "springst": 32132,
+ "springsteen": 28367,
+ "springtime": 28285,
+ "springtraining": 49364,
+ "springwatch": 29239,
+ "sprink": 15817,
+ "sprinkle": 42897,
+ "sprinkler": 48754,
+ "sprinkles": 37326,
+ "sprint": 29248,
+ "sprint": 10751,
+ "sprinter": 36947,
+ "sprints": 36404,
+ "sprite": 32544,
+ "spro": 13902,
+ "spro": 37403,
+ "sproject": 37802,
+ "sproud": 37686,
+ "sprout": 35863,
+ "sprouts": 25756,
+ "spru": 17041,
+ "spruce": 23812,
+ "sprung": 32968,
+ "sps": 13869,
+ "spu": 23566,
+ "spun": 47922,
+ "spun": 32852,
+ "spur": 15206,
+ "spur": 20361,
+ "spurs": 10916,
+ "spursofficial": 45290,
+ "sput": 47521,
+ "spx": 20584,
+ "spy": 13861,
+ "spy": 6656,
+ "spyder": 39952,
+ "spying": 36227,
+ "sq": 9370,
+ "sq": 11590,
+ "sqft": 41912,
+ "sql": 42759,
+ "sql": 18938,
+ "sqm": 47978,
+ "sqn": 41209,
+ "squ": 1653,
+ "squad": 13892,
+ "squad": 4234,
+ "squadron": 18579,
+ "squads": 36590,
+ "square": 19314,
+ "square": 3999,
+ "squared": 32967,
+ "squares": 26972,
+ "squash": 13312,
+ "squat": 44628,
+ "squat": 30680,
+ "squats": 40213,
+ "sque": 9721,
+ "sque": 8097,
+ "squee": 14420,
+ "squeeze": 21684,
+ "squeezed": 40413,
+ "squid": 42057,
+ "squid": 22553,
+ "squir": 9683,
+ "squire": 48090,
+ "squirrel": 14004,
+ "squirrels": 26623,
+ "squish": 42607,
+ "squishy": 47001,
+ "sr": 3437,
+ "sr": 5428,
+ "srbachchan": 32353,
+ "src": 23445,
+ "sre": 17748,
+ "sri": 11051,
+ "sri": 9276,
+ "sridevi": 46301,
+ "srilan": 15559,
+ "srilanka": 16922,
+ "srin": 26818,
+ "srinagar": 33671,
+ "srini": 41899,
+ "sriracha": 42743,
+ "sris": 27851,
+ "srisri": 32966,
+ "srk": 44982,
+ "srk": 11216,
+ "srl": 33808,
+ "srp": 43004,
+ "srs": 41764,
+ "srsly": 44179,
+ "srt": 28139,
+ "sru": 44152,
+ "srugby": 40526,
+ "ss": 690,
+ "ss": 632,
+ "ssa": 6088,
+ "ssal": 31330,
+ "ssal": 35936,
+ "ssb": 37511,
+ "ssc": 21692,
+ "ssc": 20364,
+ "ssd": 23107,
+ "sse": 9030,
+ "sse": 8938,
+ "ssed": 38755,
+ "ssed": 1804,
+ "ssel": 17402,
+ "ssel": 19373,
+ "sseldorf": 47792,
+ "ssell": 42388,
+ "ssels": 8355,
+ "ssen": 39408,
+ "ssen": 22645,
+ "sser": 20445,
+ "sses": 1802,
+ "ssett": 44103,
+ "ssf": 33239,
+ "ssg": 40707,
+ "ssh": 48866,
+ "ssi": 834,
+ "ssi": 14953,
+ "ssia": 22238,
+ "ssian": 31218,
+ "ssible": 47099,
+ "ssic": 27774,
+ "ssic": 17077,
+ "ssie": 7572,
+ "ssier": 26422,
+ "ssil": 15026,
+ "ssin": 42660,
+ "ssing": 2112,
+ "ssion": 16050,
+ "ssion": 1627,
+ "ssional": 13727,
+ "ssionism": 24787,
+ "ssionist": 27682,
+ "ssions": 4137,
+ "ssive": 2734,
+ "ssively": 28060,
+ "ssl": 32195,
+ "ssler": 30287,
+ "ssly": 24904,
+ "ssn": 39116,
+ "ssnhq": 47998,
+ "sso": 25900,
+ "sso": 7914,
+ "ssoccer": 32546,
+ "sson": 36124,
+ "sson": 7271,
+ "ssor": 35152,
+ "ssp": 31101,
+ "ssr": 39880,
+ "sss": 11176,
+ "ssss": 30676,
+ "ssss": 15880,
+ "sssss": 24298,
+ "sst": 40396,
+ "ssu": 35351,
+ "ssummit": 49301,
+ "ssus": 31286,
+ "ssw": 36937,
+ "ssy": 22519,
+ "ssy": 8661,
+ "st": 522,
+ "st": 545,
+ "sta": 1363,
+ "sta": 2745,
+ "stab": 7726,
+ "stab": 29974,
+ "stabbed": 24534,
+ "stabbing": 25474,
+ "stabil": 42576,
+ "stabili": 23903,
+ "stability": 16716,
+ "stable": 44427,
+ "stable": 10492,
+ "stables": 34218,
+ "stac": 10175,
+ "stacey": 41653,
+ "stacey": 24262,
+ "stache": 23616,
+ "stack": 24723,
+ "stack": 11257,
+ "stacked": 24990,
+ "stacking": 39836,
+ "stacks": 24734,
+ "stacy": 26628,
+ "stad": 15832,
+ "stad": 16485,
+ "stade": 38198,
+ "stadi": 26587,
+ "stadion": 48815,
+ "stadium": 3390,
+ "stadiums": 38852,
+ "stadt": 22713,
+ "staf": 2367,
+ "staff": 31188,
+ "staff": 2813,
+ "staffer": 38494,
+ "staffers": 44994,
+ "staffing": 32932,
+ "stafford": 25006,
+ "staffordshire": 29198,
+ "staffs": 36098,
+ "stag": 12088,
+ "stag": 20277,
+ "stage": 23182,
+ "stage": 2170,
+ "staged": 19906,
+ "stages": 12297,
+ "staggering": 37315,
+ "staging": 27026,
+ "stagram": 19503,
+ "stags": 45936,
+ "stain": 3933,
+ "stain": 14603,
+ "stained": 13751,
+ "staining": 32523,
+ "stainless": 12320,
+ "stains": 32008,
+ "stair": 7240,
+ "stair": 17662,
+ "staircase": 22777,
+ "stairs": 9577,
+ "stairway": 45559,
+ "stak": 39144,
+ "stake": 15955,
+ "stake": 7937,
+ "stakeholder": 39122,
+ "stakeholders": 22968,
+ "stakes": 7519,
+ "staking": 47082,
+ "stal": 3861,
+ "stal": 5535,
+ "stale": 42471,
+ "stalert": 25450,
+ "stalin": 28346,
+ "stalk": 40826,
+ "stalk": 14878,
+ "stalker": 26777,
+ "stalking": 24721,
+ "stalks": 45886,
+ "stall": 24636,
+ "stall": 12058,
+ "stalled": 40362,
+ "stallion": 28273,
+ "stallions": 44787,
+ "stallone": 40969,
+ "stalls": 25427,
+ "stam": 4663,
+ "stamatic": 30904,
+ "stamford": 27843,
+ "stamina": 48753,
+ "stamp": 28694,
+ "stamp": 12771,
+ "stampcollecting": 42852,
+ "stamped": 38356,
+ "stampede": 25384,
+ "stamps": 13827,
+ "stan": 2203,
+ "stan": 2434,
+ "stana": 33311,
+ "stanbul": 11231,
+ "stance": 48900,
+ "stance": 3542,
+ "stances": 15054,
+ "stand": 1819,
+ "stand": 2087,
+ "standalone": 44887,
+ "standard": 35780,
+ "standard": 5807,
+ "standardi": 30247,
+ "standards": 9022,
+ "standby": 36184,
+ "standing": 39934,
+ "standing": 2862,
+ "standings": 19835,
+ "standoff": 31821,
+ "standout": 23131,
+ "standre": 48309,
+ "stands": 6446,
+ "standup": 35108,
+ "standup": 24964,
+ "standwith": 19540,
+ "stanford": 36219,
+ "stanford": 15087,
+ "stang": 12536,
+ "stani": 38228,
+ "stanis": 37711,
+ "stanley": 19048,
+ "stanley": 10079,
+ "stanleycup": 28662,
+ "stans": 26564,
+ "stant": 41576,
+ "stant": 4906,
+ "stanton": 25400,
+ "stap": 10438,
+ "staple": 22695,
+ "staples": 23646,
+ "stapleton": 45228,
+ "star": 993,
+ "star": 1565,
+ "starbuck": 48519,
+ "starbucks": 9499,
+ "starch": 47837,
+ "starcraft": 48871,
+ "stardom": 44616,
+ "stardust": 34337,
+ "stare": 18094,
+ "stared": 47772,
+ "stares": 37916,
+ "starfish": 44283,
+ "stargate": 41099,
+ "stargazing": 49328,
+ "staring": 13800,
+ "stark": 40446,
+ "stark": 15353,
+ "starlight": 32197,
+ "starling": 46205,
+ "starmagic": 48023,
+ "starplus": 37815,
+ "starr": 19186,
+ "starred": 24180,
+ "starrer": 41311,
+ "starring": 6660,
+ "starry": 30963,
+ "stars": 2895,
+ "starship": 37166,
+ "start": 17466,
+ "start": 1572,
+ "started": 2760,
+ "starter": 7800,
+ "starters": 22222,
+ "starting": 2530,
+ "startrek": 30642,
+ "startrek": 15349,
+ "starts": 3105,
+ "startu": 6996,
+ "startup": 18049,
+ "startup": 5882,
+ "startups": 9056,
+ "starve": 46957,
+ "starving": 30473,
+ "starwar": 17287,
+ "starwars": 26239,
+ "starwars": 7887,
+ "starz": 25928,
+ "stas": 19866,
+ "stash": 27711,
+ "stasy": 45942,
+ "stat": 3004,
+ "stat": 15216,
+ "state": 3492,
+ "state": 1295,
+ "statec": 33931,
+ "stated": 19629,
+ "statedept": 41458,
+ "statefair": 40305,
+ "statement": 5401,
+ "statements": 19513,
+ "staten": 38263,
+ "stateof": 35195,
+ "states": 22125,
+ "states": 4218,
+ "statesman": 35301,
+ "stateu": 44248,
+ "statewide": 29561,
+ "stati": 9622,
+ "static": 16363,
+ "stating": 35147,
+ "station": 13498,
+ "station": 2631,
+ "stationary": 29493,
+ "stationed": 47618,
+ "stationery": 33851,
+ "stations": 10051,
+ "statistical": 29349,
+ "statistics": 14165,
+ "stats": 7294,
+ "statu": 32481,
+ "statue": 8222,
+ "statues": 24363,
+ "status": 6414,
+ "stau": 28550,
+ "staur": 3709,
+ "stav": 20285,
+ "stax": 32235,
+ "stay": 4714,
+ "stay": 2277,
+ "stayed": 13805,
+ "staying": 8993,
+ "stays": 13311,
+ "staytuned": 39285,
+ "stc": 29859,
+ "std": 30477,
+ "ste": 795,
+ "ste": 2686,
+ "stea": 46614,
+ "stead": 16101,
+ "stead": 11031,
+ "steadily": 35049,
+ "steady": 12937,
+ "steak": 26955,
+ "steak": 8913,
+ "steakhouse": 35031,
+ "steaks": 30655,
+ "steal": 37070,
+ "steal": 10181,
+ "stealing": 14242,
+ "steals": 20224,
+ "stealth": 25327,
+ "steam": 10962,
+ "steam": 6972,
+ "steamboat": 41121,
+ "steamed": 29007,
+ "steamer": 49075,
+ "steaming": 43746,
+ "steampunk": 24130,
+ "steamy": 43104,
+ "stec": 46713,
+ "stech": 48949,
+ "stech": 32455,
+ "sted": 20426,
+ "sted": 1356,
+ "stee": 31793,
+ "steed": 48293,
+ "steel": 6938,
+ "steel": 4726,
+ "steele": 19460,
+ "steelers": 14430,
+ "steen": 42851,
+ "steen": 18625,
+ "steep": 28648,
+ "steep": 20714,
+ "steer": 27612,
+ "steering": 19833,
+ "stef": 29158,
+ "stefan": 15004,
+ "stefan": 18829,
+ "stefani": 38319,
+ "stefano": 30719,
+ "steff": 30075,
+ "stein": 13653,
+ "stein": 5818,
+ "steiner": 36314,
+ "stel": 9102,
+ "stel": 10798,
+ "stell": 22355,
+ "stella": 46178,
+ "stella": 17869,
+ "stellar": 13810,
+ "stellen": 42754,
+ "stem": 24342,
+ "stem": 6761,
+ "stemc": 40486,
+ "stems": 31503,
+ "sten": 7652,
+ "sten": 7877,
+ "stencil": 47854,
+ "stennis": 45636,
+ "step": 15572,
+ "step": 3348,
+ "steph": 3522,
+ "steph": 16251,
+ "stephan": 37312,
+ "stephani": 48121,
+ "stephanie": 14361,
+ "stephen": 10421,
+ "stephen": 6078,
+ "stephenking": 46361,
+ "stephens": 22256,
+ "stephenson": 37280,
+ "stepped": 18384,
+ "stepping": 15906,
+ "steps": 5408,
+ "ster": 1022,
+ "ster": 881,
+ "stere": 9229,
+ "stered": 6935,
+ "stereo": 15992,
+ "stereo": 17400,
+ "stereotypes": 27890,
+ "steria": 38804,
+ "stering": 14175,
+ "sterling": 45790,
+ "sterling": 9378,
+ "stern": 36254,
+ "stern": 2945,
+ "steroids": 37670,
+ "sterone": 39418,
+ "sters": 2132,
+ "stery": 24232,
+ "stest": 8556,
+ "stev": 11640,
+ "steve": 7412,
+ "steve": 3803,
+ "steven": 10973,
+ "steven": 8016,
+ "stevens": 13877,
+ "stevenson": 25091,
+ "stevie": 42104,
+ "stevie": 18969,
+ "stew": 17906,
+ "stewar": 28453,
+ "steward": 34980,
+ "steward": 43355,
+ "stewards": 49294,
+ "stewardship": 36720,
+ "stewart": 8120,
+ "stfu": 47000,
+ "stg": 48387,
+ "stgeorge": 43698,
+ "sth": 13456,
+ "sth": 34004,
+ "sthe": 16491,
+ "sthel": 42863,
+ "sti": 860,
+ "sti": 12439,
+ "stia": 26492,
+ "stible": 25835,
+ "stic": 5868,
+ "stic": 1561,
+ "stical": 16660,
+ "stically": 19041,
+ "stick": 5483,
+ "stick": 4987,
+ "sticker": 11270,
+ "stickers": 11613,
+ "sticking": 21021,
+ "sticks": 10016,
+ "sticky": 18887,
+ "stics": 5449,
+ "stie": 38164,
+ "stie": 11000,
+ "stier": 42069,
+ "sties": 16428,
+ "stiff": 43471,
+ "stiff": 21441,
+ "stig": 4088,
+ "stig": 42551,
+ "stigate": 15390,
+ "stigma": 20619,
+ "stik": 42247,
+ "stil": 21790,
+ "stil": 37519,
+ "stiles": 33028,
+ "still": 13209,
+ "still": 1170,
+ "stills": 20259,
+ "stim": 18269,
+ "stime": 24711,
+ "stimul": 16434,
+ "stimulate": 42380,
+ "stimulating": 41237,
+ "stimulation": 39530,
+ "stimulus": 47283,
+ "stin": 2588,
+ "stin": 4025,
+ "stina": 22359,
+ "stine": 7098,
+ "sting": 19868,
+ "sting": 1271,
+ "stingly": 49332,
+ "stingray": 43229,
+ "stink": 38213,
+ "stinky": 44957,
+ "stino": 40658,
+ "stint": 33531,
+ "stion": 10812,
+ "stip": 39869,
+ "stips": 44756,
+ "stique": 43305,
+ "stir": 12416,
+ "stir": 19564,
+ "stirling": 23128,
+ "stirring": 39205,
+ "stis": 45224,
+ "stit": 14110,
+ "stitch": 30003,
+ "stitch": 14771,
+ "stitched": 36540,
+ "stitcher": 48204,
+ "stitches": 32360,
+ "stitching": 45208,
+ "stitu": 14585,
+ "stitutes": 40479,
+ "stive": 22426,
+ "stix": 48829,
+ "stjohn": 36153,
+ "stl": 14179,
+ "stl": 12527,
+ "stlblues": 44138,
+ "stlcards": 28644,
+ "stle": 7698,
+ "stles": 48638,
+ "stlouis": 40358,
+ "stlouis": 39516,
+ "stm": 28333,
+ "stn": 27175,
+ "sto": 928,
+ "sto": 5723,
+ "stock": 5899,
+ "stock": 3206,
+ "stocked": 23552,
+ "stockholm": 16024,
+ "stocki": 42944,
+ "stocking": 17335,
+ "stockings": 28040,
+ "stockmarket": 40359,
+ "stockport": 35569,
+ "stocks": 9321,
+ "stockton": 26130,
+ "stoday": 22392,
+ "stok": 43782,
+ "stoke": 31338,
+ "stoke": 13550,
+ "stoked": 13160,
+ "stokes": 27512,
+ "stol": 11401,
+ "stol": 6700,
+ "stole": 10995,
+ "stolen": 8704,
+ "stolic": 45020,
+ "stom": 2343,
+ "stom": 38068,
+ "stoma": 43545,
+ "stomach": 14722,
+ "stomp": 40165,
+ "stomping": 46144,
+ "ston": 4101,
+ "ston": 1839,
+ "stone": 7694,
+ "stone": 2441,
+ "stoned": 36248,
+ "stonehenge": 42417,
+ "stoner": 35131,
+ "stoner": 29115,
+ "stones": 42659,
+ "stones": 6885,
+ "stonewall": 39688,
+ "stoney": 44198,
+ "stony": 41717,
+ "stony": 35691,
+ "stoo": 24505,
+ "stood": 9151,
+ "stool": 34413,
+ "stool": 22314,
+ "stop": 6005,
+ "stop": 1691,
+ "stopbrexit": 48680,
+ "stopp": 15738,
+ "stopped": 6015,
+ "stopper": 32147,
+ "stoppers": 34457,
+ "stopping": 10735,
+ "stops": 9822,
+ "stopthe": 26463,
+ "stor": 809,
+ "stor": 17740,
+ "storage": 6824,
+ "store": 17769,
+ "store": 2183,
+ "stored": 28257,
+ "stores": 6370,
+ "storey": 24025,
+ "storians": 34628,
+ "stories": 3784,
+ "storing": 40087,
+ "stork": 46452,
+ "storm": 7434,
+ "storm": 2819,
+ "stormed": 45939,
+ "stormhour": 12161,
+ "storming": 24842,
+ "storms": 6464,
+ "stormtrooper": 49218,
+ "stormy": 20075,
+ "stors": 7178,
+ "story": 6512,
+ "story": 1134,
+ "storyline": 37079,
+ "storymonth": 23717,
+ "storyteller": 35882,
+ "storytelling": 14457,
+ "storytime": 44197,
+ "stos": 19281,
+ "stou": 37168,
+ "stour": 37361,
+ "stour": 21928,
+ "stout": 16550,
+ "stove": 21423,
+ "stow": 44284,
+ "stow": 17046,
+ "stowe": 34196,
+ "stown": 28071,
+ "stown": 7939,
+ "stp": 30576,
+ "stpatrick": 21343,
+ "stpatricksday": 22747,
+ "str": 807,
+ "str": 15913,
+ "stra": 1894,
+ "stra": 6253,
+ "strack": 46861,
+ "strada": 31134,
+ "strade": 48968,
+ "straigh": 31016,
+ "straight": 22114,
+ "straight": 4241,
+ "strain": 16887,
+ "strains": 38067,
+ "strait": 22946,
+ "straits": 41984,
+ "stral": 23289,
+ "stralia": 42510,
+ "stran": 18411,
+ "strand": 18214,
+ "strand": 17826,
+ "stranded": 22975,
+ "strang": 11138,
+ "strange": 33380,
+ "strange": 7288,
+ "strangely": 37566,
+ "stranger": 35541,
+ "stranger": 14149,
+ "strangers": 20684,
+ "strangerthings": 43271,
+ "strangest": 46740,
+ "strap": 13946,
+ "strapped": 40922,
+ "straps": 31213,
+ "stras": 36814,
+ "stras": 42125,
+ "strasbourg": 39576,
+ "strat": 11345,
+ "strat": 32925,
+ "strata": 47278,
+ "strate": 3532,
+ "strate": 28758,
+ "strategi": 49102,
+ "strategic": 10246,
+ "strategically": 45706,
+ "strategies": 9942,
+ "strategist": 37180,
+ "strategy": 5637,
+ "strates": 45724,
+ "stratford": 23955,
+ "strath": 21997,
+ "stration": 3156,
+ "strato": 28878,
+ "strauss": 32033,
+ "strava": 34625,
+ "stravel": 43494,
+ "straw": 7430,
+ "straw": 16438,
+ "strawberries": 17796,
+ "strawberry": 10233,
+ "straws": 33048,
+ "stray": 30784,
+ "stray": 15712,
+ "stre": 1079,
+ "stre": 19652,
+ "stread": 27797,
+ "streak": 11749,
+ "streaks": 42092,
+ "stream": 8659,
+ "stream": 3322,
+ "streamed": 26280,
+ "streamer": 25178,
+ "streamers": 19937,
+ "streaming": 6278,
+ "streamline": 44917,
+ "streams": 13545,
+ "stree": 35082,
+ "stree": 32438,
+ "streep": 38701,
+ "street": 4839,
+ "street": 2012,
+ "streetart": 12948,
+ "streetcar": 34268,
+ "streetfood": 44486,
+ "streetphotography": 20786,
+ "streets": 6058,
+ "streetstyle": 39118,
+ "streetwear": 37298,
+ "strel": 39685,
+ "stren": 4349,
+ "streng": 4472,
+ "strength": 15475,
+ "strength": 5959,
+ "strengthen": 16318,
+ "strengthened": 47131,
+ "strengthening": 23475,
+ "strengthens": 40280,
+ "strengths": 29268,
+ "stress": 17297,
+ "stress": 5843,
+ "stressed": 16497,
+ "stresses": 32112,
+ "stressful": 24268,
+ "stressing": 35917,
+ "stret": 12265,
+ "stretch": 10064,
+ "stretched": 29393,
+ "stretches": 32231,
+ "stretching": 24423,
+ "stri": 1493,
+ "stri": 27795,
+ "stria": 39620,
+ "strial": 30217,
+ "strian": 12924,
+ "stric": 2607,
+ "strick": 25181,
+ "strickland": 48939,
+ "strict": 21585,
+ "strictly": 16475,
+ "stride": 36024,
+ "strides": 37355,
+ "stries": 18171,
+ "strife": 46473,
+ "strike": 20774,
+ "strike": 5767,
+ "striker": 12448,
+ "strikers": 33465,
+ "strikes": 9280,
+ "striking": 13392,
+ "string": 25512,
+ "string": 9696,
+ "strings": 15699,
+ "strip": 9317,
+ "stripe": 19368,
+ "striped": 22192,
+ "stripes": 14239,
+ "stripped": 26602,
+ "stripper": 45759,
+ "stripping": 48588,
+ "strips": 19000,
+ "strive": 22140,
+ "striving": 37671,
+ "stro": 3121,
+ "stro": 6186,
+ "stroke": 44621,
+ "stroke": 10403,
+ "strokes": 26595,
+ "strol": 30123,
+ "stroll": 15924,
+ "stroller": 47076,
+ "strolling": 40911,
+ "strom": 14707,
+ "stron": 4165,
+ "strong": 10436,
+ "strong": 2389,
+ "stronger": 27760,
+ "stronger": 9245,
+ "strongertogether": 38532,
+ "strongest": 16171,
+ "strongh": 38678,
+ "strongly": 15507,
+ "strophy": 47912,
+ "strou": 48425,
+ "stroud": 39895,
+ "strous": 23752,
+ "stru": 1666,
+ "struc": 3311,
+ "struck": 10861,
+ "struction": 12497,
+ "structural": 16899,
+ "structure": 5285,
+ "structured": 27147,
+ "structures": 14171,
+ "structuring": 37496,
+ "strugg": 5176,
+ "struggle": 8443,
+ "struggled": 32921,
+ "struggles": 17446,
+ "struggling": 12135,
+ "struly": 34118,
+ "strum": 37632,
+ "strung": 46033,
+ "strust": 23920,
+ "strut": 48375,
+ "stry": 17325,
+ "stry": 2245,
+ "sts": 1088,
+ "stu": 858,
+ "stu": 23531,
+ "stuart": 32054,
+ "stuart": 11723,
+ "stub": 27066,
+ "stubborn": 38955,
+ "stuck": 6596,
+ "stud": 22368,
+ "stud": 13319,
+ "studded": 29153,
+ "studen": 44156,
+ "student": 14681,
+ "student": 2556,
+ "students": 1712,
+ "studi": 5691,
+ "studied": 21369,
+ "studies": 6426,
+ "studio": 17798,
+ "studio": 3155,
+ "studios": 6231,
+ "studs": 27571,
+ "study": 21051,
+ "study": 3123,
+ "studyabroad": 45425,
+ "studying": 8826,
+ "stuff": 46072,
+ "stuff": 3487,
+ "stuffed": 11781,
+ "stuffing": 31612,
+ "stuffs": 43455,
+ "stuk": 32424,
+ "stumb": 16784,
+ "stumble": 39045,
+ "stumbled": 21776,
+ "stump": 32064,
+ "stun": 3088,
+ "stun": 37959,
+ "stunned": 34034,
+ "stunner": 29965,
+ "stunning": 3769,
+ "stunningly": 47515,
+ "stuns": 43796,
+ "stunt": 19905,
+ "stunts": 40118,
+ "stupi": 18975,
+ "stupid": 42600,
+ "stupid": 8085,
+ "stupidity": 33766,
+ "stur": 10676,
+ "sturdy": 43780,
+ "stures": 27223,
+ "sturgeon": 31580,
+ "sturi": 21747,
+ "sturridge": 45331,
+ "stutt": 30444,
+ "stuttgart": 32219,
+ "stv": 27060,
+ "stv": 9708,
+ "stweet": 46832,
+ "stweets": 39174,
+ "stx": 42548,
+ "sty": 1421,
+ "sty": 2920,
+ "style": 12356,
+ "style": 1844,
+ "styled": 17974,
+ "styles": 6948,
+ "styli": 38577,
+ "styling": 14597,
+ "stylish": 10378,
+ "stylist": 15928,
+ "styn": 41394,
+ "su": 605,
+ "su": 2937,
+ "sua": 42448,
+ "suarez": 21437,
+ "suave": 47305,
+ "sub": 1783,
+ "sub": 7765,
+ "subaru": 21319,
+ "subjec": 16090,
+ "subject": 10300,
+ "subjects": 22099,
+ "subli": 16350,
+ "sublime": 22367,
+ "submarine": 19968,
+ "submer": 27156,
+ "submerged": 43171,
+ "submission": 16571,
+ "submissions": 21566,
+ "submit": 10423,
+ "submitted": 15189,
+ "submitting": 38788,
+ "subram": 49207,
+ "subs": 16398,
+ "subscri": 5838,
+ "subscribe": 9839,
+ "subscribed": 44867,
+ "subscriber": 36292,
+ "subscribers": 17337,
+ "subscription": 17979,
+ "subscriptions": 47162,
+ "subsequ": 33598,
+ "subsequent": 44323,
+ "subsi": 14856,
+ "subsidi": 45029,
+ "subsidiary": 45506,
+ "subsidies": 37685,
+ "subsidy": 47462,
+ "substan": 17487,
+ "substance": 19309,
+ "substances": 36834,
+ "substantial": 27171,
+ "substantially": 47577,
+ "substitu": 18529,
+ "substitute": 25340,
+ "subtitles": 39479,
+ "subtle": 16536,
+ "subur": 12517,
+ "suburb": 37664,
+ "suburban": 23570,
+ "suburbs": 25317,
+ "subway": 12196,
+ "suc": 1869,
+ "succe": 7981,
+ "succeed": 13556,
+ "succeeded": 41077,
+ "succes": 39019,
+ "success": 3695,
+ "success": 3034,
+ "successes": 29436,
+ "successful": 4670,
+ "successfully": 9934,
+ "succession": 38491,
+ "successive": 41319,
+ "successor": 34774,
+ "succu": 45253,
+ "succul": 25671,
+ "succulent": 35236,
+ "such": 2046,
+ "suction": 42786,
+ "sud": 8067,
+ "sud": 33714,
+ "sudan": 31149,
+ "sudan": 13474,
+ "sudanese": 42837,
+ "sudbury": 32488,
+ "sudden": 10833,
+ "sudden": 15433,
+ "suddenly": 11076,
+ "sue": 14045,
+ "sue": 6641,
+ "sued": 22225,
+ "suede": 21036,
+ "sues": 17105,
+ "suf": 21204,
+ "suf": 22579,
+ "sufc": 37091,
+ "suff": 4866,
+ "suffe": 13510,
+ "suffer": 13557,
+ "suffered": 14766,
+ "suffering": 10140,
+ "suffers": 22389,
+ "sufficient": 28410,
+ "suffol": 13775,
+ "suffolk": 46408,
+ "suffolk": 15685,
+ "suffra": 34596,
+ "suffrage": 39567,
+ "sufi": 39756,
+ "sug": 3189,
+ "suga": 28757,
+ "sugar": 12418,
+ "sugar": 5574,
+ "sugge": 6345,
+ "suggest": 13356,
+ "suggested": 18790,
+ "suggesti": 15033,
+ "suggesting": 29792,
+ "suggestion": 23741,
+ "suggestions": 16052,
+ "suggests": 13333,
+ "suho": 32744,
+ "sui": 24972,
+ "suici": 16372,
+ "suicidal": 37165,
+ "suicide": 31310,
+ "suicide": 8247,
+ "suing": 18309,
+ "suisse": 35964,
+ "suit": 11887,
+ "suit": 3940,
+ "suitable": 17476,
+ "suitcase": 27792,
+ "suite": 9346,
+ "suited": 25919,
+ "suites": 21523,
+ "suits": 9949,
+ "suk": 24820,
+ "suk": 6886,
+ "suka": 44017,
+ "suke": 25590,
+ "sukh": 46961,
+ "suki": 32704,
+ "sul": 1767,
+ "sul": 19879,
+ "sula": 34713,
+ "sula": 26143,
+ "sullivan": 14477,
+ "sully": 37752,
+ "sulph": 37234,
+ "sulphur": 47659,
+ "sultan": 35650,
+ "sultan": 17049,
+ "sum": 7054,
+ "sum": 8257,
+ "suma": 47938,
+ "sumat": 32640,
+ "sumatra": 47346,
+ "sume": 45457,
+ "sumi": 41248,
+ "summ": 1309,
+ "summar": 34657,
+ "summari": 31993,
+ "summary": 13435,
+ "summed": 34912,
+ "summer": 5500,
+ "summer": 1673,
+ "summers": 18254,
+ "summerslam": 40264,
+ "summertime": 19025,
+ "summit": 30011,
+ "summit": 3768,
+ "summon": 27622,
+ "summon": 39782,
+ "sumner": 46813,
+ "sumo": 33734,
+ "sump": 34252,
+ "sumptuous": 47354,
+ "sums": 13325,
+ "sun": 968,
+ "sun": 2176,
+ "sunbathing": 46994,
+ "sunburn": 45767,
+ "sund": 40735,
+ "sundae": 38078,
+ "sundance": 24128,
+ "sundar": 44936,
+ "sunday": 6649,
+ "sunday": 1706,
+ "sundayfunday": 21565,
+ "sundaymorning": 24809,
+ "sundaymotivation": 46227,
+ "sundays": 15827,
+ "sundaywith": 26469,
+ "sundaywithmarsha": 26662,
+ "sunder": 15097,
+ "sunderland": 45727,
+ "sunderland": 18851,
+ "sundown": 44438,
+ "sune": 41096,
+ "sunflower": 21559,
+ "sunflowers": 39809,
+ "sung": 16903,
+ "sung": 6047,
+ "sunglasses": 12906,
+ "suni": 17663,
+ "suni": 47010,
+ "sunil": 32861,
+ "sunite": 21382,
+ "sunited": 35276,
+ "sunk": 37534,
+ "sunken": 43473,
+ "sunlight": 17996,
+ "sunni": 44315,
+ "sunny": 15632,
+ "sunny": 5438,
+ "sunrise": 5610,
+ "suns": 18322,
+ "sunscreen": 29355,
+ "sunset": 37880,
+ "sunset": 3424,
+ "sunsets": 17721,
+ "sunshine": 32761,
+ "sunshine": 5385,
+ "suny": 41308,
+ "sup": 19078,
+ "sup": 8249,
+ "supdates": 24177,
+ "super": 1642,
+ "super": 1994,
+ "superb": 8930,
+ "superbike": 45709,
+ "superbowl": 47461,
+ "superbowl": 16467,
+ "supercar": 27021,
+ "supercars": 32185,
+ "supercell": 43227,
+ "supercharged": 47479,
+ "supere": 46831,
+ "superfood": 41715,
+ "supergirl": 25771,
+ "superhero": 14049,
+ "superheroes": 23334,
+ "superint": 17615,
+ "superintendent": 19020,
+ "superior": 13205,
+ "superjunior": 40475,
+ "superleague": 45539,
+ "superman": 11237,
+ "supermarket": 19897,
+ "supermarkets": 45106,
+ "supermodel": 41963,
+ "supermoon": 36571,
+ "supernatural": 15484,
+ "supernova": 39843,
+ "superrugby": 48717,
+ "supersonic": 42019,
+ "supersport": 46319,
+ "superst": 38202,
+ "superstar": 32551,
+ "superstar": 10472,
+ "superstars": 25797,
+ "supervis": 12709,
+ "supervised": 41316,
+ "supervision": 36234,
+ "supervisor": 20366,
+ "supervisors": 37958,
+ "superyacht": 42714,
+ "supp": 1023,
+ "supper": 15727,
+ "supple": 31431,
+ "supplement": 19924,
+ "supplements": 21265,
+ "supplied": 24106,
+ "supplier": 18043,
+ "suppliers": 24196,
+ "supplies": 9384,
+ "supply": 25074,
+ "supply": 6389,
+ "supplychain": 31224,
+ "supplying": 32739,
+ "suppo": 6941,
+ "suppor": 2104,
+ "support": 12062,
+ "support": 1425,
+ "supported": 8038,
+ "supporter": 12992,
+ "supporters": 7403,
+ "supportindiefilm": 43976,
+ "supporting": 3976,
+ "supportive": 18313,
+ "supportlocal": 43852,
+ "supports": 8336,
+ "supportsmall": 30941,
+ "supportsmallstreamers": 36097,
+ "suppose": 18924,
+ "supposed": 9119,
+ "supposedly": 32302,
+ "suppre": 20542,
+ "suppression": 36508,
+ "supra": 48485,
+ "supre": 5875,
+ "supremac": 28643,
+ "supremacist": 39005,
+ "supremacy": 28913,
+ "supreme": 35222,
+ "supreme": 7468,
+ "supt": 23625,
+ "sur": 1090,
+ "sur": 7123,
+ "sura": 33412,
+ "sura": 49125,
+ "surabaya": 45227,
+ "surance": 22184,
+ "surat": 30201,
+ "sure": 14320,
+ "sure": 1650,
+ "sured": 36869,
+ "surely": 11409,
+ "sures": 12725,
+ "suresh": 32118,
+ "suresh": 31464,
+ "sureshpp": 41924,
+ "sureshpprabhu": 42050,
+ "surf": 10176,
+ "surf": 10322,
+ "surface": 7744,
+ "surfaces": 20746,
+ "surfer": 24925,
+ "surfers": 34842,
+ "surfing": 15762,
+ "surg": 13045,
+ "surge": 17457,
+ "surgeon": 16039,
+ "surgeons": 26000,
+ "surger": 5122,
+ "surgeries": 34940,
+ "surgery": 5344,
+ "surgical": 16386,
+ "suri": 14130,
+ "suri": 33952,
+ "suring": 16817,
+ "suriya": 17832,
+ "surpass": 45494,
+ "surpassed": 25648,
+ "surplus": 29413,
+ "surpri": 3244,
+ "surprise": 5099,
+ "surprised": 8949,
+ "surprises": 16920,
+ "surprising": 14964,
+ "surprisingly": 17367,
+ "surreal": 18408,
+ "surrealism": 41773,
+ "surrender": 20964,
+ "surrendered": 44601,
+ "surrey": 26489,
+ "surrey": 14315,
+ "surro": 47499,
+ "surroun": 8250,
+ "surround": 26543,
+ "surround": 22999,
+ "surrounded": 13589,
+ "surrounding": 12544,
+ "surroundings": 26915,
+ "surrounds": 39012,
+ "suru": 49240,
+ "surve": 8952,
+ "surveill": 15408,
+ "surveillance": 15578,
+ "survey": 45914,
+ "survey": 6809,
+ "surveying": 33085,
+ "surveys": 25096,
+ "survi": 3440,
+ "surviv": 12922,
+ "survival": 10172,
+ "survive": 10431,
+ "survived": 13483,
+ "survives": 30927,
+ "surviving": 18609,
+ "survivor": 31934,
+ "survivor": 10944,
+ "survivors": 13711,
+ "surya": 37767,
+ "sus": 8091,
+ "sus": 3036,
+ "susa": 20546,
+ "susan": 19922,
+ "susan": 10168,
+ "suscep": 44270,
+ "sush": 22298,
+ "sushi": 11729,
+ "sushmaswar": 48200,
+ "susie": 32284,
+ "susp": 7971,
+ "suspec": 10298,
+ "suspect": 9065,
+ "suspected": 15579,
+ "suspects": 18265,
+ "suspen": 10578,
+ "suspend": 41007,
+ "suspended": 13126,
+ "suspends": 39535,
+ "suspense": 21556,
+ "suspension": 15417,
+ "suspici": 25714,
+ "suspicion": 34910,
+ "suspicious": 19862,
+ "sussex": 31244,
+ "sussex": 13266,
+ "sustain": 4644,
+ "sustain": 28156,
+ "sustainability": 9635,
+ "sustainable": 23645,
+ "sustainable": 7078,
+ "sustained": 22699,
+ "sustaining": 44418,
+ "sut": 23984,
+ "sut": 28956,
+ "sutherland": 27592,
+ "sutton": 39359,
+ "sutton": 18564,
+ "suv": 15985,
+ "suz": 9957,
+ "suzanne": 24617,
+ "suzu": 36289,
+ "suzuki": 16892,
+ "suzy": 26552,
+ "sv": 6508,
+ "sv": 17083,
+ "svc": 45065,
+ "sve": 47637,
+ "sven": 37786,
+ "sven": 45183,
+ "sver": 45923,
+ "sville": 44580,
+ "sville": 6741,
+ "svp": 28465,
+ "svt": 42014,
+ "svu": 32123,
+ "sw": 1220,
+ "sw": 4457,
+ "swa": 4707,
+ "swa": 31916,
+ "swach": 20862,
+ "swachhb": 31898,
+ "swachhbharat": 36927,
+ "swag": 8852,
+ "swag": 8177,
+ "swagg": 47702,
+ "swagger": 35797,
+ "swain": 43226,
+ "swal": 13433,
+ "swallow": 28979,
+ "swallowed": 46956,
+ "swallows": 45124,
+ "swam": 42539,
+ "swami": 25021,
+ "swamp": 41953,
+ "swamp": 16595,
+ "swamy": 28445,
+ "swan": 8215,
+ "swan": 12530,
+ "swana": 24699,
+ "swans": 19516,
+ "swansea": 16567,
+ "swanson": 34797,
+ "swap": 15234,
+ "swapped": 39077,
+ "swapping": 44702,
+ "swaps": 49242,
+ "swar": 11680,
+ "swarm": 31577,
+ "swarovski": 28515,
+ "swat": 32547,
+ "swat": 26482,
+ "swatch": 48053,
+ "sway": 26443,
+ "sway": 26617,
+ "swc": 42231,
+ "swe": 2350,
+ "swe": 38070,
+ "swear": 7406,
+ "swearing": 32627,
+ "sweat": 10282,
+ "sweat": 12663,
+ "sweater": 11455,
+ "sweaters": 31303,
+ "sweating": 33215,
+ "sweats": 39321,
+ "sweatshirt": 22442,
+ "sweaty": 28419,
+ "sweden": 8760,
+ "swedish": 11585,
+ "swee": 1812,
+ "sweek": 30017,
+ "sweeney": 27286,
+ "sweep": 23220,
+ "sweep": 13669,
+ "sweeping": 25719,
+ "sweeps": 26887,
+ "sweepstakes": 25992,
+ "sweet": 10957,
+ "sweet": 2418,
+ "sweetened": 45577,
+ "sweeter": 32873,
+ "sweetest": 15180,
+ "sweethe": 16316,
+ "sweetheart": 18079,
+ "sweetie": 24450,
+ "sweetness": 29713,
+ "sweets": 18045,
+ "swel": 48470,
+ "swell": 35538,
+ "swell": 21490,
+ "swelling": 46578,
+ "swept": 23311,
+ "swer": 30514,
+ "swfc": 30227,
+ "swfl": 46607,
+ "swi": 3881,
+ "swi": 45223,
+ "swick": 17159,
+ "swif": 28548,
+ "swift": 34843,
+ "swift": 8229,
+ "swild": 33909,
+ "swild": 38696,
+ "swildlife": 46818,
+ "swim": 4928,
+ "swim": 7681,
+ "swimmer": 25475,
+ "swimmers": 27776,
+ "swimming": 7411,
+ "swims": 46798,
+ "swimsuit": 25504,
+ "swimwear": 31889,
+ "swin": 14554,
+ "swin": 40798,
+ "swindon": 29540,
+ "swine": 31166,
+ "swing": 25292,
+ "swing": 7429,
+ "swinging": 26760,
+ "swings": 29141,
+ "swipe": 31828,
+ "swire": 42753,
+ "swirl": 35795,
+ "swis": 23611,
+ "swish": 38571,
+ "swiss": 37917,
+ "swiss": 9287,
+ "swit": 3726,
+ "switch": 22480,
+ "switch": 5893,
+ "switched": 22869,
+ "switches": 33569,
+ "switching": 21155,
+ "swith": 17299,
+ "switzer": 9835,
+ "switzerland": 9912,
+ "swivel": 48256,
+ "swo": 38673,
+ "swol": 29575,
+ "swollen": 36129,
+ "swoo": 29744,
+ "swood": 24158,
+ "swoon": 37028,
+ "swoop": 45661,
+ "sword": 33294,
+ "sword": 11356,
+ "swords": 27181,
+ "swork": 42722,
+ "sworld": 33305,
+ "sworn": 21130,
+ "sworth": 13322,
+ "swt": 38878,
+ "swx": 20597,
+ "sx": 9402,
+ "sx": 17806,
+ "sxsw": 13369,
+ "sy": 974,
+ "sy": 2126,
+ "sya": 35017,
+ "sycam": 34911,
+ "sycamore": 43086,
+ "syd": 4525,
+ "syd": 22504,
+ "sydney": 15878,
+ "sydney": 5278,
+ "syed": 27624,
+ "syfy": 32047,
+ "sykes": 27287,
+ "syl": 6452,
+ "sylla": 41708,
+ "sylvania": 12011,
+ "sylve": 28369,
+ "sylvester": 37214,
+ "sylvia": 25670,
+ "sym": 3645,
+ "sym": 40327,
+ "symb": 22987,
+ "symbol": 13085,
+ "symboli": 22019,
+ "symbolic": 33177,
+ "symbolism": 44679,
+ "symbols": 25476,
+ "symmetry": 31427,
+ "symp": 11468,
+ "sympathi": 47493,
+ "sympathy": 32477,
+ "symph": 9544,
+ "symphonic": 42639,
+ "symphony": 11180,
+ "sympo": 9730,
+ "symposium": 9971,
+ "symptom": 47799,
+ "symptoms": 12956,
+ "syn": 3758,
+ "syn": 36090,
+ "synago": 30945,
+ "synagogue": 33518,
+ "sync": 20081,
+ "synchron": 23943,
+ "syndic": 21098,
+ "syndicate": 28779,
+ "syndrome": 10927,
+ "syner": 22283,
+ "synergy": 32012,
+ "syno": 31533,
+ "synod": 47712,
+ "synopsis": 47018,
+ "synth": 33841,
+ "synth": 24462,
+ "synthe": 22604,
+ "synthesi": 33565,
+ "synthesis": 21602,
+ "synthesizer": 44077,
+ "synthetic": 19917,
+ "syou": 26742,
+ "syour": 21718,
+ "syrac": 17279,
+ "syracuse": 19640,
+ "syrah": 45364,
+ "syri": 18917,
+ "syria": 5563,
+ "syrian": 47562,
+ "syrian": 10041,
+ "syrians": 41392,
+ "syrup": 16611,
+ "sys": 26726,
+ "syste": 1933,
+ "system": 47813,
+ "system": 2422,
+ "systematic": 28586,
+ "systemic": 33807,
+ "systems": 4828,
+ "sz": 13438,
+ "sz": 15879,
+ "sze": 44507,
+ "szn": 48092,
+ "são": 45911,
+ "sé": 37879,
+ "t": 83,
+ "t": 339,
+ "ta": 648,
+ "ta": 1397,
+ "taa": 43874,
+ "tab": 2648,
+ "tab": 14724,
+ "tabby": 36145,
+ "tabern": 48991,
+ "tability": 15770,
+ "table": 12108,
+ "table": 2175,
+ "tableau": 39723,
+ "tables": 7822,
+ "tablet": 12494,
+ "tabletop": 46843,
+ "tabletop": 25773,
+ "tablets": 20436,
+ "tably": 24440,
+ "taboo": 38400,
+ "tabs": 29163,
+ "tac": 3145,
+ "tac": 22653,
+ "tache": 39239,
+ "tack": 6339,
+ "tack": 34446,
+ "tackle": 10294,
+ "tackled": 47218,
+ "tackles": 18021,
+ "tackling": 19628,
+ "taco": 31924,
+ "taco": 12436,
+ "tacoma": 25397,
+ "tacos": 14090,
+ "tactic": 40377,
+ "tactical": 17137,
+ "tactics": 16410,
+ "tacular": 48985,
+ "tad": 15890,
+ "tad": 19860,
+ "tado": 40846,
+ "tae": 15257,
+ "tae": 15580,
+ "taehyung": 24642,
+ "taek": 30753,
+ "taekwondo": 39963,
+ "taemin": 30600,
+ "taeyang": 45802,
+ "taeyeon": 27389,
+ "taf": 29660,
+ "taft": 42141,
+ "tag": 3456,
+ "tag": 3640,
+ "tage": 2669,
+ "tages": 39902,
+ "tagged": 12969,
+ "tagging": 25138,
+ "tagne": 47467,
+ "tags": 11606,
+ "tah": 14822,
+ "tah": 7090,
+ "tahit": 45385,
+ "tahoe": 26140,
+ "tai": 6511,
+ "tai": 13040,
+ "taiji": 30185,
+ "tail": 7156,
+ "tail": 4132,
+ "tailed": 20626,
+ "tailgate": 23168,
+ "tailgating": 42625,
+ "tailo": 27230,
+ "tailor": 29870,
+ "tailored": 28275,
+ "tailoring": 46357,
+ "tails": 16066,
+ "tain": 2841,
+ "tain": 1908,
+ "taine": 21214,
+ "taine": 32299,
+ "tained": 10212,
+ "taining": 7565,
+ "tainment": 30063,
+ "tains": 3952,
+ "tainted": 47211,
+ "taipei": 24356,
+ "tair": 29143,
+ "tairp": 43707,
+ "tait": 45325,
+ "taiwan": 36319,
+ "taiwan": 12626,
+ "taiwanese": 41416,
+ "taj": 28937,
+ "taj": 24805,
+ "taji": 46358,
+ "tak": 15070,
+ "tak": 14458,
+ "taka": 24070,
+ "taka": 40968,
+ "take": 5052,
+ "take": 1172,
+ "takeaway": 25737,
+ "takeaways": 32080,
+ "takeme": 41748,
+ "taken": 2807,
+ "takeoff": 32789,
+ "takeover": 11863,
+ "taker": 17939,
+ "takers": 30775,
+ "takes": 2633,
+ "takin": 30890,
+ "taking": 2019,
+ "taku": 48168,
+ "tal": 976,
+ "tal": 2066,
+ "tala": 29845,
+ "talaga": 35349,
+ "talbot": 30585,
+ "tale": 33971,
+ "tale": 7798,
+ "talent": 30435,
+ "talent": 5114,
+ "talented": 5331,
+ "talents": 16136,
+ "tales": 9469,
+ "tali": 12122,
+ "tali": 45406,
+ "taliban": 20788,
+ "talis": 36480,
+ "tality": 15631,
+ "talk": 12462,
+ "talk": 1841,
+ "talked": 10153,
+ "talkin": 26040,
+ "talking": 31463,
+ "talking": 2578,
+ "talks": 3237,
+ "tall": 11664,
+ "tall": 7771,
+ "talla": 21528,
+ "tallade": 44220,
+ "tallahassee": 37832,
+ "taller": 23470,
+ "tallest": 19774,
+ "tallinn": 45079,
+ "tally": 16323,
+ "talon": 47897,
+ "tam": 2661,
+ "tam": 12246,
+ "tama": 45424,
+ "tamanna": 48055,
+ "tamar": 22901,
+ "tamara": 35697,
+ "tame": 38557,
+ "tame": 32778,
+ "tamed": 40575,
+ "tami": 39429,
+ "tamil": 23046,
+ "tamil": 14033,
+ "tamilnadu": 32371,
+ "tamine": 42566,
+ "tammy": 28396,
+ "tampa": 10906,
+ "tampab": 37852,
+ "tamu": 34105,
+ "tan": 2123,
+ "tan": 5039,
+ "tana": 21396,
+ "tand": 20244,
+ "tandem": 33756,
+ "tane": 13344,
+ "tane": 24923,
+ "taneous": 22275,
+ "taneously": 24422,
+ "tang": 10425,
+ "tang": 20794,
+ "tanger": 31844,
+ "tangerine": 42045,
+ "tangible": 44823,
+ "tangle": 36568,
+ "tangled": 33587,
+ "tango": 24089,
+ "tani": 31374,
+ "tani": 32985,
+ "tania": 45369,
+ "tank": 29858,
+ "tank": 6172,
+ "tanker": 25020,
+ "tanks": 14223,
+ "tann": 19174,
+ "tanner": 22001,
+ "tanning": 27985,
+ "tans": 27332,
+ "tant": 41383,
+ "tant": 41695,
+ "tante": 48262,
+ "tanto": 45685,
+ "tany": 34410,
+ "tanya": 26800,
+ "tanz": 47399,
+ "tanzania": 15711,
+ "tao": 29084,
+ "tao": 18923,
+ "tap": 17923,
+ "tap": 7888,
+ "tapas": 27361,
+ "tape": 18332,
+ "tape": 5749,
+ "taped": 33219,
+ "tapes": 17903,
+ "tapestry": 33525,
+ "taping": 24355,
+ "tapp": 27644,
+ "tapp": 27764,
+ "tapped": 26649,
+ "tapping": 27882,
+ "tapro": 34415,
+ "taproom": 40266,
+ "taps": 23267,
+ "tar": 2002,
+ "tar": 6977,
+ "tara": 15264,
+ "tarak": 37813,
+ "taran": 32370,
+ "tarantino": 41180,
+ "tarde": 48670,
+ "tardis": 35410,
+ "tares": 34587,
+ "targe": 9620,
+ "target": 38556,
+ "target": 5400,
+ "targeted": 14968,
+ "targeting": 15818,
+ "targets": 12468,
+ "tari": 4238,
+ "tari": 38012,
+ "tarian": 11762,
+ "tarians": 42789,
+ "taries": 47291,
+ "tariff": 40220,
+ "tariffs": 28335,
+ "tariq": 42526,
+ "tarmac": 44294,
+ "taro": 26264,
+ "tarot": 23702,
+ "tart": 16707,
+ "tart": 14120,
+ "tartan": 35064,
+ "tarts": 29799,
+ "tary": 31729,
+ "tary": 5065,
+ "tarzan": 45463,
+ "tas": 6538,
+ "tas": 10163,
+ "tash": 35272,
+ "tasha": 44967,
+ "task": 39189,
+ "task": 10549,
+ "tasks": 19453,
+ "tasmania": 22429,
+ "tasmanian": 45102,
+ "tassel": 49276,
+ "tast": 10839,
+ "taste": 14314,
+ "taste": 5219,
+ "tasted": 22827,
+ "tasteof": 38097,
+ "taster": 29743,
+ "tastes": 13736,
+ "tastic": 21337,
+ "tasting": 7656,
+ "tastings": 49273,
+ "tasty": 43390,
+ "tasty": 8568,
+ "tat": 2652,
+ "tat": 21592,
+ "tata": 19300,
+ "tate": 44476,
+ "tate": 13295,
+ "tath": 27566,
+ "tati": 31433,
+ "tatiana": 48837,
+ "tation": 5280,
+ "tations": 32324,
+ "tator": 18791,
+ "tators": 37206,
+ "tats": 44557,
+ "tatt": 9232,
+ "tatted": 41605,
+ "tattoo": 15980,
+ "tattoo": 6325,
+ "tattooed": 28541,
+ "tattoos": 14900,
+ "tatum": 26103,
+ "tau": 6620,
+ "tau": 20510,
+ "taught": 9306,
+ "taun": 23910,
+ "taunton": 40681,
+ "taurus": 32881,
+ "taver": 37776,
+ "tavern": 18644,
+ "taw": 33868,
+ "taw": 40289,
+ "tawa": 29035,
+ "tawards": 14351,
+ "tax": 4581,
+ "tax": 3879,
+ "taxation": 36847,
+ "taxes": 11462,
+ "taxi": 25160,
+ "taxi": 11380,
+ "taxider": 47420,
+ "taxis": 34009,
+ "taxpay": 17986,
+ "taxpayer": 30978,
+ "taxpayers": 25503,
+ "tay": 6542,
+ "tay": 15073,
+ "taya": 38484,
+ "tayl": 3913,
+ "taylor": 9044,
+ "taylor": 3961,
+ "taylorswift": 18936,
+ "tayo": 33941,
+ "taz": 41475,
+ "taz": 31870,
+ "tb": 1990,
+ "tb": 7490,
+ "tba": 34363,
+ "tball": 8390,
+ "tball": 1467,
+ "tbc": 31807,
+ "tbd": 45548,
+ "tbh": 13238,
+ "tbi": 45868,
+ "tbl": 42962,
+ "tbli": 43664,
+ "tblightning": 44178,
+ "tbo": 34255,
+ "tbr": 46643,
+ "tbs": 37368,
+ "tbt": 2950,
+ "tc": 6820,
+ "tc": 5454,
+ "tca": 35116,
+ "tch": 10744,
+ "tch": 4048,
+ "tches": 42001,
+ "tcm": 21501,
+ "tcm": 26588,
+ "tcmparty": 24338,
+ "tcot": 8995,
+ "tcs": 39107,
+ "tcu": 26791,
+ "td": 20578,
+ "td": 3192,
+ "tdf": 21844,
+ "tdi": 45621,
+ "tdp": 47009,
+ "tds": 20238,
+ "tdsb": 29836,
+ "te": 600,
+ "te": 756,
+ "tea": 41053,
+ "tea": 3274,
+ "teach": 2043,
+ "teach": 6865,
+ "teacher": 18051,
+ "teacher": 4008,
+ "teachers": 5069,
+ "teaches": 17110,
+ "teaching": 5141,
+ "teachings": 32119,
+ "teal": 22821,
+ "team": 2085,
+ "team": 1027,
+ "teamcanada": 46636,
+ "teamed": 20590,
+ "teamgb": 40971,
+ "teaming": 24392,
+ "teammate": 17900,
+ "teammates": 13921,
+ "teams": 3891,
+ "teamsisd": 34703,
+ "teamusa": 28625,
+ "teamwork": 14657,
+ "teaparty": 33065,
+ "teapo": 35745,
+ "teapot": 40749,
+ "tear": 15802,
+ "tear": 11862,
+ "tearful": 46873,
+ "tearing": 24785,
+ "tears": 7688,
+ "teas": 23003,
+ "teas": 29314,
+ "tease": 25163,
+ "teased": 49122,
+ "teaser": 8982,
+ "teasers": 48990,
+ "teases": 28509,
+ "teasing": 36507,
+ "teat": 26376,
+ "teatime": 48948,
+ "teatro": 35756,
+ "teau": 24931,
+ "tebow": 37797,
+ "tec": 17381,
+ "tec": 11612,
+ "tech": 1782,
+ "tech": 2061,
+ "techcrunch": 42110,
+ "techn": 6252,
+ "technews": 31787,
+ "technic": 16639,
+ "technic": 37666,
+ "technical": 49231,
+ "technical": 7582,
+ "technically": 23180,
+ "technician": 22540,
+ "technicians": 35513,
+ "techno": 2599,
+ "techno": 17564,
+ "technological": 23068,
+ "technologies": 10040,
+ "technology": 3089,
+ "techs": 41353,
+ "ted": 4841,
+ "ted": 775,
+ "tedcruz": 27517,
+ "teddy": 25758,
+ "teddy": 11798,
+ "tedly": 8539,
+ "tedu": 42517,
+ "tedx": 17950,
+ "tedx": 41504,
+ "tee": 12676,
+ "tee": 3385,
+ "teed": 13692,
+ "teen": 5398,
+ "teen": 4697,
+ "teenage": 14069,
+ "teenager": 19338,
+ "teenagers": 25989,
+ "teenchoice": 28203,
+ "teens": 12375,
+ "teenth": 20249,
+ "teenwolf": 40067,
+ "teeny": 41622,
+ "teer": 48648,
+ "tees": 9641,
+ "teessi": 43295,
+ "teeth": 8225,
+ "tega": 29508,
+ "tegr": 39801,
+ "teh": 18720,
+ "teh": 29601,
+ "tehran": 26399,
+ "tein": 33223,
+ "tej": 46724,
+ "tek": 17489,
+ "tek": 18294,
+ "tekken": 29843,
+ "tel": 4978,
+ "tel": 2226,
+ "telang": 23469,
+ "telangana": 26386,
+ "tele": 3103,
+ "tele": 32851,
+ "telecom": 21057,
+ "telecommunications": 39900,
+ "telegram": 26780,
+ "telegraph": 14713,
+ "telephone": 17243,
+ "telescope": 19037,
+ "telethon": 49266,
+ "televised": 39470,
+ "television": 8608,
+ "telford": 38323,
+ "tell": 16069,
+ "tell": 2330,
+ "teller": 20415,
+ "tellers": 42707,
+ "telling": 5507,
+ "tells": 5217,
+ "tellu": 42511,
+ "telly": 31475,
+ "tels": 43607,
+ "telugu": 22927,
+ "tely": 5630,
+ "tem": 2404,
+ "tem": 17536,
+ "tema": 45881,
+ "teme": 43378,
+ "temp": 2684,
+ "temp": 11097,
+ "tempe": 36723,
+ "temper": 5981,
+ "temper": 35521,
+ "temperature": 9543,
+ "temperatures": 11575,
+ "tempered": 40521,
+ "tempest": 36053,
+ "templ": 16679,
+ "template": 18591,
+ "templates": 30498,
+ "temple": 21841,
+ "temple": 5620,
+ "temples": 24024,
+ "tempo": 19625,
+ "tempor": 4858,
+ "temporal": 43656,
+ "temporarily": 23189,
+ "temporary": 6513,
+ "temps": 11668,
+ "tempt": 28460,
+ "temptation": 30118,
+ "tempted": 26226,
+ "tempting": 34876,
+ "ten": 1149,
+ "ten": 2581,
+ "tenant": 16954,
+ "tenants": 26023,
+ "tenay": 45384,
+ "tenberg": 31329,
+ "tend": 17630,
+ "tend": 21252,
+ "tendency": 47277,
+ "tender": 23020,
+ "tender": 9838,
+ "tenderloin": 42750,
+ "tenders": 44741,
+ "tending": 35084,
+ "tendon": 48459,
+ "tends": 39962,
+ "tene": 24868,
+ "tened": 13682,
+ "tener": 29054,
+ "teneri": 28000,
+ "tenerife": 29401,
+ "teners": 41307,
+ "teness": 18018,
+ "teng": 34016,
+ "teng": 28474,
+ "tennant": 29310,
+ "tennes": 9514,
+ "tennessee": 10053,
+ "tennis": 31504,
+ "tennis": 5298,
+ "tenor": 30521,
+ "tens": 14062,
+ "tense": 23518,
+ "tension": 15221,
+ "tensions": 24224,
+ "tenstein": 49139,
+ "tent": 18505,
+ "tent": 10782,
+ "tentative": 48238,
+ "tenth": 27483,
+ "tention": 12191,
+ "tents": 30730,
+ "tenure": 30739,
+ "teo": 18665,
+ "tep": 31806,
+ "tequ": 17502,
+ "tequila": 18510,
+ "ter": 704,
+ "ter": 652,
+ "tera": 15155,
+ "teras": 44830,
+ "tere": 11329,
+ "tered": 49272,
+ "tered": 4389,
+ "terence": 33806,
+ "teresa": 19081,
+ "teri": 30917,
+ "teria": 22685,
+ "terie": 42276,
+ "tering": 7929,
+ "term": 40991,
+ "term": 4780,
+ "termin": 4766,
+ "terminal": 11816,
+ "terminals": 44091,
+ "terminator": 29609,
+ "terminology": 48896,
+ "terms": 8663,
+ "tern": 41572,
+ "tern": 12959,
+ "terns": 25251,
+ "tero": 20727,
+ "tero": 24697,
+ "terps": 41471,
+ "terr": 3921,
+ "terra": 22366,
+ "terra": 18816,
+ "terrac": 28549,
+ "terrace": 13820,
+ "terraces": 47508,
+ "terracotta": 45123,
+ "terrain": 20184,
+ "terran": 43726,
+ "terre": 33888,
+ "terre": 27537,
+ "terrell": 39494,
+ "terrence": 38746,
+ "terrestrial": 46299,
+ "terri": 4504,
+ "terri": 36722,
+ "terrible": 9741,
+ "terribly": 34558,
+ "terrier": 14455,
+ "terriers": 47047,
+ "terrific": 13837,
+ "terrified": 28204,
+ "terrifying": 18526,
+ "territ": 10720,
+ "territorial": 39163,
+ "territories": 32846,
+ "territory": 13936,
+ "terror": 9596,
+ "terror": 9327,
+ "terrori": 6836,
+ "terrorism": 10583,
+ "terrorist": 10575,
+ "terrorists": 12835,
+ "terry": 19378,
+ "terry": 8561,
+ "ters": 24102,
+ "ters": 1737,
+ "terti": 48386,
+ "tery": 4184,
+ "tes": 8019,
+ "tes": 3609,
+ "tesco": 15434,
+ "tese": 33320,
+ "tesla": 12254,
+ "tess": 21807,
+ "tess": 20840,
+ "tessa": 32063,
+ "test": 7738,
+ "test": 1628,
+ "testam": 23477,
+ "testament": 24609,
+ "tested": 10576,
+ "tester": 32707,
+ "testi": 18373,
+ "testic": 42364,
+ "testify": 33088,
+ "testifying": 46347,
+ "testim": 12553,
+ "testimonial": 28834,
+ "testimony": 18672,
+ "testing": 4967,
+ "testo": 42428,
+ "testosterone": 45168,
+ "tests": 8715,
+ "tet": 40468,
+ "tet": 13275,
+ "tetra": 40902,
+ "tetris": 45934,
+ "teu": 47152,
+ "teuk": 39979,
+ "teur": 27120,
+ "tex": 2056,
+ "tex": 11728,
+ "texan": 35287,
+ "texan": 38386,
+ "texans": 17580,
+ "texanscheer": 43717,
+ "texas": 15713,
+ "texas": 3403,
+ "texaste": 46469,
+ "text": 18169,
+ "text": 4160,
+ "textbook": 25952,
+ "textbooks": 44041,
+ "texted": 29004,
+ "textile": 19789,
+ "textiles": 24326,
+ "texting": 18600,
+ "texts": 12767,
+ "texture": 16505,
+ "textured": 32168,
+ "textures": 28063,
+ "tey": 32395,
+ "tez": 22664,
+ "tf": 18828,
+ "tf": 5001,
+ "tfc": 30186,
+ "tfl": 29918,
+ "tford": 22493,
+ "tful": 17108,
+ "tfw": 16741,
+ "tg": 7665,
+ "tg": 11981,
+ "tgif": 14483,
+ "th": 513,
+ "th": 640,
+ "tha": 18470,
+ "tha": 4715,
+ "thab": 38219,
+ "thad": 48339,
+ "thai": 28054,
+ "thai": 8825,
+ "thail": 7258,
+ "thailand": 7469,
+ "thak": 22801,
+ "thakur": 38427,
+ "thal": 7967,
+ "thal": 12323,
+ "thala": 17784,
+ "thalai": 25206,
+ "thalaivar": 44918,
+ "thalap": 39789,
+ "thalapathy": 45405,
+ "thalapathy": 23324,
+ "thall": 36007,
+ "tham": 11761,
+ "tham": 8896,
+ "thames": 43472,
+ "thames": 15321,
+ "than": 792,
+ "than": 1126,
+ "thand": 44465,
+ "thane": 21463,
+ "thang": 24870,
+ "thani": 31322,
+ "thank": 2790,
+ "thank": 1144,
+ "thanked": 32079,
+ "thankful": 38839,
+ "thankful": 6217,
+ "thankfully": 22089,
+ "thanking": 21989,
+ "thanks": 5672,
+ "thanks": 1085,
+ "thanksgiving": 45732,
+ "thanksgiving": 6167,
+ "thanku": 45710,
+ "thankyou": 18050,
+ "thankyou": 9911,
+ "thanniversary": 35564,
+ "thanos": 36709,
+ "thanx": 25095,
+ "thar": 14396,
+ "thar": 38843,
+ "thard": 43474,
+ "that": 6303,
+ "that": 682,
+ "thatcher": 32496,
+ "thats": 44636,
+ "thats": 9254,
+ "thaw": 26081,
+ "thaw": 47229,
+ "thbewithyou": 41067,
+ "thc": 20091,
+ "thcentury": 49111,
+ "thd": 28219,
+ "thday": 37801,
+ "the": 599,
+ "the": 518,
+ "thea": 15935,
+ "thea": 25429,
+ "thead": 25259,
+ "theal": 45728,
+ "thealth": 31398,
+ "thear": 43283,
+ "theart": 44678,
+ "theast": 8378,
+ "theastern": 17877,
+ "theat": 2263,
+ "theater": 39438,
+ "theater": 6128,
+ "theaters": 14689,
+ "theatre": 19857,
+ "theatre": 3292,
+ "theatres": 21680,
+ "theatrical": 26833,
+ "theband": 27695,
+ "thebeatles": 35645,
+ "thebest": 40883,
+ "thebest": 25856,
+ "thebig": 24732,
+ "theblack": 47718,
+ "thec": 48659,
+ "thed": 31405,
+ "thedaily": 33550,
+ "theday": 4408,
+ "thedream": 39417,
+ "thee": 44475,
+ "thee": 15108,
+ "theeconomist": 44518,
+ "theellenshow": 35342,
+ "thefilm": 31665,
+ "theflash": 25434,
+ "theforce": 40002,
+ "theforceawakens": 48033,
+ "theft": 13286,
+ "thefuture": 34287,
+ "thegame": 24428,
+ "thegood": 28594,
+ "thegreat": 28721,
+ "thei": 44522,
+ "their": 911,
+ "theirs": 29297,
+ "thel": 5403,
+ "thelast": 23495,
+ "thelastjedi": 47992,
+ "theless": 27712,
+ "theli": 15277,
+ "thelittle": 46872,
+ "thelo": 47036,
+ "thelove": 40668,
+ "thelove": 43200,
+ "them": 5435,
+ "them": 1180,
+ "themasters": 48378,
+ "theme": 38524,
+ "theme": 5849,
+ "themed": 10126,
+ "themes": 17849,
+ "themet": 48183,
+ "themovie": 27062,
+ "themselves": 6503,
+ "then": 5929,
+ "then": 1594,
+ "thenburg": 45209,
+ "thene": 17012,
+ "thenew": 24212,
+ "thenext": 47881,
+ "thenight": 43336,
+ "theno": 37172,
+ "thenorth": 34338,
+ "theo": 17043,
+ "theo": 18084,
+ "theod": 26653,
+ "theodore": 30743,
+ "theological": 41162,
+ "theology": 24095,
+ "theon": 34653,
+ "theone": 46231,
+ "theopen": 41438,
+ "theore": 22690,
+ "theoretical": 35585,
+ "theori": 34804,
+ "theories": 23937,
+ "theory": 7143,
+ "thepeople": 33597,
+ "thepersonal": 29981,
+ "thepersonalnetwork": 30016,
+ "thephoto": 18303,
+ "thephotohour": 18607,
+ "ther": 1160,
+ "ther": 743,
+ "therap": 4499,
+ "therapeu": 19332,
+ "therapeutic": 23240,
+ "therapeutics": 49101,
+ "therapies": 30179,
+ "therapist": 20608,
+ "therapists": 34763,
+ "therapper": 49340,
+ "therapy": 5257,
+ "there": 5283,
+ "there": 997,
+ "thereal": 8074,
+ "thereal": 41140,
+ "thereby": 43308,
+ "thered": 10208,
+ "therefore": 16865,
+ "theres": 18494,
+ "theresa": 14126,
+ "therese": 47996,
+ "theresistance": 22845,
+ "theri": 28967,
+ "theri": 45297,
+ "therine": 26807,
+ "therine": 9239,
+ "thering": 7891,
+ "therland": 25351,
+ "thermal": 13689,
+ "thermo": 22303,
+ "thermom": 31138,
+ "thermometer": 38172,
+ "thermost": 42391,
+ "thern": 10919,
+ "thern": 3137,
+ "thero": 13165,
+ "theroad": 29807,
+ "therock": 30036,
+ "theroy": 38146,
+ "thers": 1959,
+ "thes": 40556,
+ "thes": 6460,
+ "thescript": 47061,
+ "these": 40366,
+ "these": 1071,
+ "theses": 39388,
+ "thesimpsons": 45513,
+ "thesims": 34192,
+ "thesis": 10673,
+ "thessal": 41491,
+ "thessaloni": 41753,
+ "thest": 35343,
+ "thesun": 45617,
+ "theta": 27694,
+ "thetic": 7954,
+ "thetimes": 36039,
+ "thevamp": 33701,
+ "thevoice": 47206,
+ "thevoice": 30258,
+ "thewalkingdead": 18087,
+ "thewanted": 43008,
+ "theworld": 44988,
+ "theworld": 17475,
+ "thex": 35990,
+ "they": 15174,
+ "they": 889,
+ "theyre": 28266,
+ "thfc": 17729,
+ "thi": 2362,
+ "thi": 9111,
+ "thia": 17943,
+ "thiago": 44537,
+ "thian": 23214,
+ "thians": 28187,
+ "thibau": 48351,
+ "thic": 26107,
+ "thic": 11794,
+ "thick": 18417,
+ "thick": 11006,
+ "thicker": 43302,
+ "thickness": 40754,
+ "thief": 18508,
+ "thier": 25595,
+ "thierry": 32929,
+ "thieves": 17899,
+ "thigh": 47124,
+ "thigh": 22877,
+ "thighs": 30847,
+ "thik": 20512,
+ "thika": 44619,
+ "thill": 31266,
+ "thim": 42331,
+ "thin": 2178,
+ "thin": 7847,
+ "thine": 47192,
+ "thing": 7499,
+ "thing": 946,
+ "things": 30670,
+ "things": 1739,
+ "thingsto": 43924,
+ "thingy": 36888,
+ "think": 9820,
+ "think": 1331,
+ "thinkbig": 26015,
+ "thinkbigsundaywithmarsha": 26666,
+ "thinker": 34577,
+ "thinkers": 32779,
+ "thinkin": 34443,
+ "thinking": 3291,
+ "thinks": 6109,
+ "thinner": 47247,
+ "thir": 6030,
+ "third": 32102,
+ "third": 3981,
+ "thirds": 42582,
+ "thirst": 23563,
+ "thirsty": 39731,
+ "thirsty": 17521,
+ "thirteen": 34209,
+ "thirty": 20813,
+ "thiru": 43292,
+ "this": 4340,
+ "this": 589,
+ "thisday": 6532,
+ "thisdayin": 33641,
+ "thisdayinhistory": 46913,
+ "thisi": 7299,
+ "thisis": 14887,
+ "thismorning": 36245,
+ "thistle": 29039,
+ "thistory": 28904,
+ "thium": 21804,
+ "thletics": 17765,
+ "thm": 10407,
+ "thman": 30079,
+ "thms": 19874,
+ "thn": 44155,
+ "thn": 45587,
+ "thnx": 25480,
+ "tho": 1325,
+ "tho": 5025,
+ "thof": 18943,
+ "thofjuly": 21613,
+ "thol": 29319,
+ "thole": 31029,
+ "tholes": 42465,
+ "thology": 9881,
+ "thom": 2585,
+ "thom": 24094,
+ "thomas": 12574,
+ "thomas": 3888,
+ "thome": 21289,
+ "thomp": 37274,
+ "thompson": 42181,
+ "thompson": 8535,
+ "thomson": 24151,
+ "thon": 38776,
+ "thon": 8924,
+ "thong": 37058,
+ "thood": 15623,
+ "thor": 4130,
+ "thor": 13691,
+ "thora": 46866,
+ "thorn": 12957,
+ "thorn": 18466,
+ "thorne": 18025,
+ "thorns": 33650,
+ "thornton": 23592,
+ "thorough": 15294,
+ "thorough": 34788,
+ "thoroughbred": 43248,
+ "thoroughly": 19750,
+ "thorpe": 18099,
+ "thos": 41965,
+ "those": 1753,
+ "thot": 33736,
+ "thou": 1513,
+ "thou": 17781,
+ "though": 2846,
+ "thought": 23948,
+ "thought": 2449,
+ "thoughtful": 19592,
+ "thoughts": 3618,
+ "thour": 27125,
+ "thousand": 9344,
+ "thousands": 7089,
+ "thouse": 40318,
+ "thouse": 7819,
+ "thoven": 23078,
+ "thr": 1111,
+ "thr": 19138,
+ "thra": 17761,
+ "thra": 32797,
+ "thrash": 38262,
+ "thre": 1607,
+ "thread": 31108,
+ "thread": 8815,
+ "threads": 24957,
+ "threat": 7527,
+ "threat": 7212,
+ "threaten": 26097,
+ "threatened": 16391,
+ "threatening": 16400,
+ "threatens": 20555,
+ "threats": 12766,
+ "three": 21615,
+ "three": 2097,
+ "thren": 41776,
+ "thresh": 29779,
+ "threshold": 33791,
+ "threw": 12746,
+ "thri": 8713,
+ "thrift": 27779,
+ "thrill": 21023,
+ "thrilled": 7879,
+ "thriller": 9653,
+ "thrilling": 20101,
+ "thrills": 39829,
+ "thrive": 17669,
+ "thriving": 22677,
+ "thro": 2101,
+ "thro": 28624,
+ "throat": 16371,
+ "thrombo": 47585,
+ "throne": 15999,
+ "thrones": 8072,
+ "throp": 34939,
+ "throttle": 37139,
+ "through": 6091,
+ "through": 1417,
+ "throughout": 6721,
+ "throughs": 48278,
+ "throw": 3315,
+ "throw": 6293,
+ "throwback": 6001,
+ "throwback": 5058,
+ "throwbackthursday": 6326,
+ "thrower": 40199,
+ "throwing": 9734,
+ "thrown": 15079,
+ "throws": 14723,
+ "thru": 23856,
+ "thru": 6162,
+ "thrush": 46133,
+ "thrust": 40202,
+ "ths": 2079,
+ "tht": 23554,
+ "thu": 3837,
+ "thu": 14153,
+ "thub": 25660,
+ "thug": 37212,
+ "thug": 18137,
+ "thugs": 27686,
+ "thul": 28368,
+ "thulhu": 37560,
+ "thum": 14679,
+ "thumb": 19514,
+ "thumb": 18674,
+ "thumbnail": 32365,
+ "thumbs": 17599,
+ "thun": 32267,
+ "thunder": 6161,
+ "thunder": 8951,
+ "thunderbird": 45131,
+ "thunderbirds": 44286,
+ "thunderbolt": 43596,
+ "thunderstorm": 12005,
+ "thunderstorms": 19525,
+ "thunt": 46763,
+ "thur": 1837,
+ "thur": 21704,
+ "thurman": 41291,
+ "thurs": 9908,
+ "thursday": 11218,
+ "thursday": 2221,
+ "thursdaymotivation": 39375,
+ "thursdays": 21444,
+ "thursdaythoughts": 14866,
+ "thurst": 33970,
+ "thus": 12457,
+ "thusi": 9488,
+ "thwaite": 48469,
+ "thweeksary": 30871,
+ "thx": 5913,
+ "thy": 7804,
+ "thy": 3362,
+ "thyme": 29805,
+ "thyro": 25174,
+ "thyroid": 32558,
+ "ti": 555,
+ "ti": 2605,
+ "tia": 6709,
+ "tial": 2826,
+ "tially": 14503,
+ "tian": 23011,
+ "tian": 8125,
+ "tians": 35182,
+ "tiara": 38322,
+ "tib": 47868,
+ "tibet": 19927,
+ "tibet": 22234,
+ "tibetan": 24057,
+ "tible": 11453,
+ "tic": 890,
+ "tic": 1550,
+ "tica": 9669,
+ "tical": 34191,
+ "tical": 4342,
+ "tically": 13375,
+ "ticals": 30861,
+ "tice": 3122,
+ "tich": 48769,
+ "tician": 43358,
+ "ticism": 26491,
+ "tick": 24640,
+ "tick": 15617,
+ "ticket": 25740,
+ "ticket": 4500,
+ "ticketing": 44432,
+ "tickets": 2015,
+ "ticking": 35842,
+ "tickle": 42999,
+ "ticks": 40269,
+ "tico": 17670,
+ "ticon": 45996,
+ "tics": 2419,
+ "ticul": 15538,
+ "ticus": 44277,
+ "tid": 26002,
+ "tid": 23727,
+ "tidal": 21949,
+ "tide": 15698,
+ "tide": 9105,
+ "tides": 25524,
+ "tidy": 23858,
+ "tie": 14072,
+ "tie": 3422,
+ "tied": 9889,
+ "tiem": 34762,
+ "tien": 47538,
+ "tiene": 43438,
+ "tier": 14390,
+ "tier": 6598,
+ "tierney": 45693,
+ "tiers": 24604,
+ "ties": 25556,
+ "ties": 2499,
+ "tiest": 18300,
+ "tiesto": 46367,
+ "tif": 23216,
+ "tiff": 11112,
+ "tiff": 20699,
+ "tiffany": 30467,
+ "tiffany": 14446,
+ "tification": 43923,
+ "tified": 40854,
+ "tiful": 29123,
+ "tify": 6677,
+ "tig": 31999,
+ "tiger": 11954,
+ "tiger": 6531,
+ "tigers": 6934,
+ "tigh": 31365,
+ "tight": 25763,
+ "tight": 9123,
+ "tighten": 46653,
+ "tighter": 48193,
+ "tightly": 37568,
+ "tights": 29581,
+ "tijuana": 45273,
+ "tik": 24986,
+ "tik": 32403,
+ "tiki": 30107,
+ "til": 6124,
+ "til": 1763,
+ "tile": 26217,
+ "tile": 8227,
+ "tiles": 10607,
+ "tility": 38180,
+ "till": 17462,
+ "till": 4267,
+ "tilla": 26063,
+ "tillerson": 47738,
+ "tilly": 41199,
+ "tilt": 23601,
+ "tim": 1292,
+ "tim": 3863,
+ "timate": 4754,
+ "timb": 26627,
+ "timber": 14441,
+ "timber": 16246,
+ "timberlake": 28274,
+ "timbers": 39911,
+ "timberwolves": 41190,
+ "time": 3764,
+ "time": 788,
+ "timed": 32727,
+ "timehop": 19944,
+ "timel": 23549,
+ "timelapse": 48154,
+ "timeless": 15558,
+ "timeline": 11492,
+ "timely": 19250,
+ "timeout": 41536,
+ "timer": 19725,
+ "timers": 44574,
+ "times": 26445,
+ "times": 1661,
+ "timesnow": 45487,
+ "timesof": 32522,
+ "timesofindia": 44182,
+ "timetable": 31971,
+ "timeto": 29187,
+ "timing": 13624,
+ "timm": 22444,
+ "timmy": 33252,
+ "timo": 13390,
+ "timo": 33777,
+ "timothy": 42087,
+ "timothy": 18560,
+ "timp": 42166,
+ "tin": 1310,
+ "tin": 5420,
+ "tina": 9257,
+ "tinder": 24287,
+ "tine": 22341,
+ "ting": 7451,
+ "ting": 694,
+ "tinged": 44829,
+ "tings": 35332,
+ "tini": 26839,
+ "tink": 39278,
+ "tinker": 45272,
+ "tinker": 40910,
+ "tino": 20538,
+ "tins": 37359,
+ "tint": 40497,
+ "tinted": 42618,
+ "tiny": 21716,
+ "tiny": 5591,
+ "tio": 27562,
+ "tion": 2274,
+ "tion": 740,
+ "tional": 22460,
+ "tional": 2986,
+ "tionality": 24514,
+ "tionally": 12409,
+ "tionary": 8381,
+ "tione": 44318,
+ "tioned": 9083,
+ "tioning": 15528,
+ "tionist": 25732,
+ "tions": 1371,
+ "tious": 14255,
+ "tip": 15383,
+ "tip": 4623,
+ "tipoff": 44521,
+ "tipp": 32294,
+ "tipped": 31878,
+ "tipper": 38095,
+ "tipperary": 45612,
+ "tipping": 27827,
+ "tips": 3173,
+ "tipton": 48809,
+ "tiptuesday": 42112,
+ "tique": 37772,
+ "tir": 25467,
+ "tir": 38462,
+ "tire": 29128,
+ "tire": 9362,
+ "tired": 6533,
+ "tireless": 39835,
+ "tirelessly": 41548,
+ "tires": 15533,
+ "tiring": 42630,
+ "tiru": 36033,
+ "tis": 7839,
+ "tis": 7394,
+ "tise": 13745,
+ "tisgarh": 40538,
+ "tish": 45148,
+ "tish": 28784,
+ "tism": 27113,
+ "tiss": 28155,
+ "tissue": 15368,
+ "tissues": 32172,
+ "tist": 7902,
+ "tista": 25580,
+ "tists": 25944,
+ "tit": 1991,
+ "tit": 13202,
+ "tita": 40936,
+ "titan": 13496,
+ "titan": 15516,
+ "titanic": 20729,
+ "titanium": 24409,
+ "titans": 13066,
+ "titi": 17434,
+ "titi": 48504,
+ "title": 28033,
+ "title": 3644,
+ "titled": 9939,
+ "titles": 9780,
+ "tito": 26838,
+ "titus": 36102,
+ "tium": 21975,
+ "tiv": 1835,
+ "tiva": 41886,
+ "tive": 14640,
+ "tive": 1420,
+ "tively": 9883,
+ "tiveness": 20955,
+ "tives": 7570,
+ "tivity": 9859,
+ "tivo": 32162,
+ "tix": 5835,
+ "tiz": 19376,
+ "tj": 18890,
+ "tj": 18988,
+ "tk": 22344,
+ "tk": 20676,
+ "tko": 37347,
+ "tks": 38739,
+ "tl": 14325,
+ "tl": 8190,
+ "tland": 30697,
+ "tlap": 41976,
+ "tlc": 22047,
+ "tle": 39141,
+ "tle": 5825,
+ "tles": 39363,
+ "tless": 17427,
+ "tlot": 41080,
+ "tls": 47367,
+ "tly": 37483,
+ "tly": 1646,
+ "tm": 9430,
+ "tm": 7789,
+ "tman": 20796,
+ "tmc": 35263,
+ "tment": 26485,
+ "tml": 39445,
+ "tmltalk": 42260,
+ "tmnt": 32444,
+ "tmobile": 34901,
+ "tmr": 35906,
+ "tmrw": 16496,
+ "tms": 44496,
+ "tmund": 23801,
+ "tmw": 45827,
+ "tmz": 37248,
+ "tn": 3827,
+ "tn": 7248,
+ "tna": 21150,
+ "tnam": 8079,
+ "tner": 34922,
+ "tness": 35212,
+ "tney": 9523,
+ "tng": 35898,
+ "tnt": 20659,
+ "tnx": 38220,
+ "to": 580,
+ "to": 531,
+ "toa": 17916,
+ "toad": 26096,
+ "toast": 24654,
+ "toast": 10920,
+ "toasted": 23533,
+ "toaster": 39061,
+ "toasty": 44726,
+ "tob": 24260,
+ "tobac": 12611,
+ "tobacco": 13905,
+ "tobago": 39482,
+ "tobe": 17534,
+ "tobe": 28740,
+ "tober": 18162,
+ "tober": 2925,
+ "toberfest": 26249,
+ "tobi": 40335,
+ "tobi": 48374,
+ "tobias": 32464,
+ "tobin": 42466,
+ "toby": 29659,
+ "toby": 18333,
+ "toc": 41907,
+ "toc": 30643,
+ "tock": 25274,
+ "tod": 38239,
+ "tod": 33568,
+ "toda": 47141,
+ "todas": 36150,
+ "today": 11800,
+ "today": 721,
+ "todayin": 32957,
+ "todays": 13513,
+ "todayshow": 29739,
+ "todd": 10398,
+ "todd": 9951,
+ "toddler": 17772,
+ "toddlers": 36719,
+ "toddy": 38926,
+ "todo": 48857,
+ "todo": 23087,
+ "todos": 33355,
+ "toe": 47756,
+ "toe": 11344,
+ "toes": 16511,
+ "tof": 6659,
+ "toff": 27319,
+ "toffee": 34880,
+ "tofficial": 47953,
+ "tofthe": 23678,
+ "toftheday": 20566,
+ "tofu": 24692,
+ "tog": 45715,
+ "toge": 1903,
+ "together": 17858,
+ "together": 1952,
+ "togo": 26729,
+ "tography": 33968,
+ "toh": 26851,
+ "toi": 7472,
+ "toi": 26941,
+ "toid": 49124,
+ "toile": 43148,
+ "toilet": 11071,
+ "toilets": 24027,
+ "toire": 39534,
+ "tok": 16690,
+ "tok": 27010,
+ "token": 32634,
+ "token": 17134,
+ "tokens": 23562,
+ "tokyo": 35038,
+ "tokyo": 6667,
+ "tol": 4678,
+ "tol": 32962,
+ "told": 3527,
+ "tole": 15677,
+ "toledo": 19812,
+ "toler": 12150,
+ "tolerance": 20377,
+ "tolerant": 38536,
+ "tolerate": 35556,
+ "tolkien": 32989,
+ "toll": 44090,
+ "toll": 14155,
+ "tollywood": 42016,
+ "tology": 34799,
+ "tom": 999,
+ "tom": 2435,
+ "toma": 42360,
+ "toma": 44710,
+ "tomas": 35944,
+ "tomas": 27178,
+ "tomat": 12041,
+ "tomato": 9867,
+ "tomatoes": 13004,
+ "tomb": 37187,
+ "tomb": 15582,
+ "tombs": 48613,
+ "tombstone": 45729,
+ "tome": 24137,
+ "tome": 24283,
+ "tomi": 46290,
+ "tomlin": 46649,
+ "tomlinson": 17484,
+ "tommorow": 42871,
+ "tommy": 16573,
+ "tommy": 8876,
+ "tomo": 31223,
+ "tomo": 34434,
+ "tomor": 1277,
+ "tomorrow": 19728,
+ "tomorrow": 1293,
+ "tomorrowland": 34951,
+ "tomorrows": 32258,
+ "tomorrowspaper": 35005,
+ "tomorrowspaperstoday": 35190,
+ "tomp": 43544,
+ "tompkins": 49068,
+ "toms": 10545,
+ "tomy": 18730,
+ "ton": 838,
+ "ton": 917,
+ "tona": 13459,
+ "tone": 32366,
+ "tone": 8408,
+ "toned": 29426,
+ "toner": 40614,
+ "tones": 14744,
+ "tong": 21510,
+ "tonga": 37882,
+ "tongue": 44820,
+ "tongue": 13626,
+ "tongues": 39837,
+ "toni": 17766,
+ "toni": 17171,
+ "tonic": 17808,
+ "tonics": 34647,
+ "tonight": 1009,
+ "tonights": 23312,
+ "tonite": 13449,
+ "tonka": 42781,
+ "tonline": 45867,
+ "tonne": 42450,
+ "tonnes": 24813,
+ "tons": 7555,
+ "tony": 9150,
+ "tony": 4767,
+ "tonyawards": 46068,
+ "too": 1843,
+ "too": 1256,
+ "took": 2280,
+ "tool": 13718,
+ "tool": 5999,
+ "toolbox": 46599,
+ "toolkit": 29849,
+ "tools": 5771,
+ "toom": 27550,
+ "toon": 24664,
+ "toon": 19701,
+ "toonami": 48336,
+ "toons": 35345,
+ "toor": 42590,
+ "tooth": 15316,
+ "tooth": 12030,
+ "toothbrush": 36841,
+ "toothpaste": 37322,
+ "tooting": 42969,
+ "top": 5534,
+ "top": 1253,
+ "topaz": 46125,
+ "tope": 32149,
+ "tope": 42239,
+ "topeka": 46884,
+ "topia": 29618,
+ "topic": 8720,
+ "topical": 37464,
+ "topics": 11916,
+ "topless": 37415,
+ "topo": 23008,
+ "topoli": 30152,
+ "topp": 19529,
+ "topped": 12588,
+ "topper": 31780,
+ "toppers": 41651,
+ "topping": 21071,
+ "toppings": 47554,
+ "topps": 20201,
+ "tops": 8154,
+ "topshop": 40953,
+ "topus": 21495,
+ "tor": 937,
+ "tor": 1208,
+ "tora": 45147,
+ "torah": 37945,
+ "toral": 45282,
+ "torch": 31921,
+ "torch": 15820,
+ "tore": 38066,
+ "tore": 19385,
+ "tored": 38046,
+ "torg": 33214,
+ "tori": 17689,
+ "tori": 17539,
+ "toria": 23732,
+ "torial": 28029,
+ "torian": 48399,
+ "tories": 14193,
+ "torino": 29178,
+ "torio": 34235,
+ "torn": 8572,
+ "torn": 18023,
+ "tornad": 24676,
+ "tornado": 9062,
+ "tornadoes": 28254,
+ "toro": 17892,
+ "toron": 37407,
+ "toronto": 16866,
+ "toronto": 4514,
+ "torpe": 34093,
+ "torpedo": 46582,
+ "torquay": 45738,
+ "torque": 31940,
+ "torre": 39563,
+ "torre": 38009,
+ "torrent": 42317,
+ "torrential": 41158,
+ "torres": 16049,
+ "tors": 2546,
+ "tortilla": 32683,
+ "torto": 24170,
+ "tortoise": 30178,
+ "torture": 16013,
+ "tortured": 29900,
+ "tory": 29390,
+ "tory": 4214,
+ "tos": 6094,
+ "tosc": 37719,
+ "tose": 38154,
+ "tosh": 17109,
+ "toshi": 31744,
+ "toss": 19656,
+ "tossed": 31296,
+ "tot": 4618,
+ "tot": 23659,
+ "total": 13507,
+ "total": 4445,
+ "totally": 5440,
+ "totals": 25772,
+ "tote": 48145,
+ "tote": 19031,
+ "totem": 45376,
+ "totes": 37199,
+ "tothe": 12222,
+ "toto": 39823,
+ "tots": 24978,
+ "totten": 14360,
+ "tottenham": 14889,
+ "tou": 1879,
+ "tou": 29261,
+ "touch": 9480,
+ "touch": 4526,
+ "touchdown": 18664,
+ "touchdowns": 37905,
+ "touched": 13190,
+ "touches": 14832,
+ "touching": 14088,
+ "touchscreen": 39095,
+ "tough": 12063,
+ "tough": 5499,
+ "tougher": 33722,
+ "toughest": 23773,
+ "toughness": 45522,
+ "toulou": 27145,
+ "toulouse": 30267,
+ "tour": 2710,
+ "tour": 1760,
+ "tourde": 39247,
+ "toured": 27654,
+ "touri": 4224,
+ "touring": 11853,
+ "tourism": 23661,
+ "tourism": 6556,
+ "tourist": 12123,
+ "tourists": 15546,
+ "tournament": 4097,
+ "tournaments": 23058,
+ "tourney": 12603,
+ "tours": 8948,
+ "tous": 37424,
+ "tout": 22300,
+ "touts": 41274,
+ "tov": 28970,
+ "tow": 11557,
+ "tow": 18653,
+ "toward": 8508,
+ "towards": 4447,
+ "towed": 45419,
+ "towel": 15953,
+ "towels": 26578,
+ "tower": 26669,
+ "tower": 4730,
+ "towering": 39444,
+ "towers": 12701,
+ "towie": 44613,
+ "towin": 45819,
+ "towing": 36963,
+ "town": 4068,
+ "town": 1605,
+ "townfc": 33981,
+ "townhall": 33408,
+ "townhouse": 40178,
+ "towns": 14173,
+ "townsend": 26826,
+ "township": 14622,
+ "townsville": 47330,
+ "towork": 48233,
+ "tox": 7742,
+ "tox": 16145,
+ "toxic": 27436,
+ "toxic": 12348,
+ "toxicity": 41234,
+ "toxin": 48899,
+ "toxins": 36618,
+ "toy": 14387,
+ "toy": 5988,
+ "toya": 37602,
+ "toyo": 7644,
+ "toyota": 8908,
+ "toys": 39508,
+ "toys": 7162,
+ "tp": 23760,
+ "tp": 15188,
+ "tpp": 29411,
+ "tps": 35246,
+ "tq": 43066,
+ "tr": 635,
+ "tr": 6337,
+ "tra": 752,
+ "tra": 2483,
+ "trac": 2266,
+ "trace": 48611,
+ "trace": 14767,
+ "traced": 47956,
+ "traces": 30913,
+ "tracey": 25558,
+ "tracing": 27897,
+ "track": 10887,
+ "track": 2700,
+ "tracked": 27049,
+ "tracker": 18123,
+ "tracking": 10428,
+ "tracklist": 39777,
+ "tracks": 7579,
+ "tract": 4690,
+ "traction": 10644,
+ "tractor": 14607,
+ "tractors": 37854,
+ "tracy": 32984,
+ "tracy": 15508,
+ "trad": 48716,
+ "trad": 38037,
+ "trade": 10457,
+ "trade": 3629,
+ "traded": 18860,
+ "trademark": 25011,
+ "trader": 17700,
+ "traders": 19112,
+ "trades": 18519,
+ "trading": 40083,
+ "trading": 6520,
+ "tradio": 20689,
+ "tradition": 20838,
+ "tradition": 8784,
+ "traditional": 41113,
+ "traditional": 5604,
+ "traditionally": 35532,
+ "traditions": 18016,
+ "traf": 3227,
+ "trafal": 32461,
+ "trafalgar": 36969,
+ "traff": 31571,
+ "traffic": 12080,
+ "traffic": 3399,
+ "trafficking": 15983,
+ "trafford": 22912,
+ "trage": 12430,
+ "tragedy": 14082,
+ "tragic": 14828,
+ "tragically": 39599,
+ "trail": 11523,
+ "trail": 4921,
+ "trailblazer": 41015,
+ "trailblazers": 35954,
+ "trailer": 4700,
+ "trailers": 24862,
+ "trailing": 37427,
+ "trails": 10633,
+ "train": 9122,
+ "train": 3231,
+ "trained": 10874,
+ "trainee": 25795,
+ "trainees": 30382,
+ "trainer": 9767,
+ "trainers": 18871,
+ "training": 34508,
+ "training": 2199,
+ "trains": 9541,
+ "trait": 35160,
+ "traitor": 31760,
+ "traitors": 42633,
+ "traits": 25748,
+ "trajec": 42042,
+ "trak": 24065,
+ "tral": 14609,
+ "tram": 9800,
+ "tram": 17500,
+ "tramp": 46289,
+ "trampol": 32905,
+ "trampoline": 42800,
+ "tramrahim": 35220,
+ "tran": 1357,
+ "tran": 22031,
+ "trance": 30584,
+ "trance": 18671,
+ "trancefamily": 39630,
+ "trane": 35779,
+ "tranqu": 18912,
+ "tranquil": 35764,
+ "tranquility": 36688,
+ "trans": 1826,
+ "trans": 8126,
+ "transaction": 24881,
+ "transactions": 21653,
+ "transat": 37872,
+ "transatlantic": 40703,
+ "transc": 21073,
+ "transcend": 47087,
+ "transcript": 39008,
+ "transcription": 48765,
+ "transfer": 22659,
+ "transfer": 7134,
+ "transferred": 29700,
+ "transferring": 40924,
+ "transfers": 21621,
+ "transform": 8142,
+ "transform": 12288,
+ "transformation": 34204,
+ "transformation": 7832,
+ "transformational": 47135,
+ "transformationtuesday": 36511,
+ "transformative": 38106,
+ "transformed": 17453,
+ "transformer": 38235,
+ "transformers": 17843,
+ "transforming": 44470,
+ "transforming": 19251,
+ "transforms": 30312,
+ "transgender": 17732,
+ "transi": 32236,
+ "transit": 10174,
+ "transiti": 22939,
+ "transition": 11391,
+ "transitional": 41519,
+ "transitioning": 43586,
+ "transitions": 39374,
+ "transl": 12243,
+ "translate": 22655,
+ "translated": 20752,
+ "translates": 36334,
+ "translating": 42156,
+ "translation": 12153,
+ "translations": 41367,
+ "translator": 36230,
+ "translucent": 49052,
+ "transm": 18861,
+ "transmission": 16103,
+ "transmitted": 48605,
+ "transmitter": 40457,
+ "transp": 11726,
+ "transpa": 18524,
+ "transparen": 16108,
+ "transparency": 16828,
+ "transparent": 19017,
+ "transpl": 16038,
+ "transplant": 41871,
+ "transplant": 18771,
+ "transplantation": 45207,
+ "transpor": 19406,
+ "transport": 10231,
+ "transport": 7362,
+ "transportation": 10911,
+ "transported": 29089,
+ "transporter": 43568,
+ "transporting": 42259,
+ "trap": 36224,
+ "trap": 9677,
+ "trape": 42435,
+ "trapped": 15592,
+ "traps": 28517,
+ "tras": 30638,
+ "trash": 39215,
+ "trash": 9798,
+ "traum": 22263,
+ "trauma": 13846,
+ "traumati": 46613,
+ "traumatic": 29958,
+ "trav": 7586,
+ "trav": 46955,
+ "trave": 35357,
+ "travel": 2824,
+ "travel": 1949,
+ "travelblog": 35957,
+ "travelblogger": 25494,
+ "travelchat": 46455,
+ "traveled": 20384,
+ "traveler": 17794,
+ "travelers": 20644,
+ "travelgram": 40069,
+ "traveling": 9365,
+ "travelled": 23428,
+ "traveller": 22546,
+ "travellers": 29583,
+ "travelling": 11190,
+ "travelphotography": 22808,
+ "travelpics": 32293,
+ "travels": 11472,
+ "traveltips": 36260,
+ "traveltuesday": 16713,
+ "traverse": 35058,
+ "travi": 46971,
+ "travis": 27441,
+ "travis": 12287,
+ "traw": 42288,
+ "trax": 34421,
+ "tray": 38470,
+ "tray": 14621,
+ "trays": 39798,
+ "trc": 41803,
+ "tre": 975,
+ "tre": 6033,
+ "treach": 46005,
+ "tread": 26182,
+ "tread": 35658,
+ "treadmill": 37780,
+ "treas": 8591,
+ "treason": 28103,
+ "treasure": 9922,
+ "treasured": 48068,
+ "treasurer": 26985,
+ "treasures": 16500,
+ "treasury": 20956,
+ "treat": 3968,
+ "treat": 3901,
+ "treated": 9772,
+ "treating": 13842,
+ "treatment": 4869,
+ "treatments": 15839,
+ "treats": 8878,
+ "treaty": 19967,
+ "treble": 33194,
+ "trecht": 33812,
+ "tree": 13354,
+ "tree": 2677,
+ "treehouse": 42387,
+ "trees": 4682,
+ "trek": 13236,
+ "trek": 8136,
+ "trekking": 25293,
+ "trell": 35159,
+ "tremb": 44043,
+ "tremend": 14659,
+ "tremendous": 15988,
+ "tren": 2579,
+ "trench": 23846,
+ "trenches": 38723,
+ "trend": 19986,
+ "trend": 6643,
+ "trending": 6087,
+ "trends": 7015,
+ "trendsetter": 46666,
+ "trendy": 23072,
+ "trent": 45885,
+ "trent": 15548,
+ "trenton": 37470,
+ "tres": 23569,
+ "tress": 4733,
+ "tresses": 24273,
+ "trevor": 23437,
+ "trevor": 13219,
+ "trex": 42114,
+ "trey": 36670,
+ "trey": 16939,
+ "tri": 924,
+ "tri": 9618,
+ "triad": 45602,
+ "trial": 5991,
+ "trials": 10992,
+ "triangle": 14615,
+ "triathlon": 18080,
+ "trib": 45151,
+ "tribal": 16629,
+ "tribe": 19943,
+ "tribe": 11365,
+ "tribeca": 35184,
+ "tribes": 26546,
+ "tribu": 3028,
+ "tribun": 14311,
+ "tribunal": 32911,
+ "tribune": 18556,
+ "tribute": 5493,
+ "tributes": 15537,
+ "tric": 9511,
+ "tric": 4081,
+ "trich": 39519,
+ "trick": 17177,
+ "trick": 8172,
+ "tricks": 13177,
+ "tricky": 22319,
+ "trics": 31437,
+ "trident": 35491,
+ "tridge": 18722,
+ "tried": 4554,
+ "tries": 4315,
+ "trife": 48962,
+ "trigge": 30509,
+ "trigger": 16158,
+ "triggered": 30924,
+ "triggers": 37319,
+ "tright": 29915,
+ "tril": 40626,
+ "trill": 39297,
+ "trilli": 39350,
+ "trillion": 20160,
+ "trilo": 15183,
+ "trilogy": 16862,
+ "trim": 14182,
+ "trimmed": 40657,
+ "trin": 6628,
+ "trinidad": 26244,
+ "trinity": 30744,
+ "trinity": 12267,
+ "trio": 10263,
+ "trip": 23421,
+ "trip": 2529,
+ "tripad": 37189,
+ "tripadvisor": 38708,
+ "triple": 16519,
+ "triple": 7673,
+ "triplets": 48601,
+ "tripod": 36141,
+ "tripoli": 40095,
+ "trippin": 43073,
+ "tripping": 35229,
+ "trippy": 35137,
+ "trips": 12292,
+ "tris": 29690,
+ "trish": 40511,
+ "trish": 37179,
+ "trisha": 39152,
+ "tristan": 25497,
+ "trit": 37087,
+ "triton": 45437,
+ "triu": 14782,
+ "trium": 21065,
+ "triumph": 26507,
+ "triumph": 15307,
+ "triumphant": 41918,
+ "trivi": 21228,
+ "trivia": 10642,
+ "triviatuesday": 45499,
+ "trix": 41017,
+ "tro": 1046,
+ "tro": 3332,
+ "trock": 44368,
+ "trojan": 30653,
+ "trojans": 25310,
+ "trol": 10306,
+ "troll": 39737,
+ "troll": 17103,
+ "trolley": 25124,
+ "trolling": 28552,
+ "trolls": 20890,
+ "tromb": 32390,
+ "trombone": 44423,
+ "tron": 19057,
+ "tron": 10684,
+ "tronic": 34258,
+ "tronics": 34397,
+ "troom": 23691,
+ "troop": 12492,
+ "troop": 24054,
+ "trooper": 18327,
+ "troopers": 23576,
+ "troops": 10109,
+ "trop": 31585,
+ "trope": 41150,
+ "trophies": 20998,
+ "trophy": 42676,
+ "trophy": 6502,
+ "tropic": 21794,
+ "tropic": 36736,
+ "tropical": 41699,
+ "tropical": 8686,
+ "tropics": 36940,
+ "tros": 40456,
+ "trose": 36022,
+ "trot": 30453,
+ "trotter": 38287,
+ "trou": 5181,
+ "troubad": 49037,
+ "trouble": 25669,
+ "trouble": 7848,
+ "troubled": 25568,
+ "troubles": 27254,
+ "trough": 39761,
+ "troupe": 34803,
+ "trous": 19727,
+ "trousers": 23172,
+ "trout": 14853,
+ "trove": 45350,
+ "trow": 46914,
+ "troy": 26283,
+ "troy": 12819,
+ "trs": 24770,
+ "tru": 931,
+ "tru": 25326,
+ "truck": 14781,
+ "truck": 4629,
+ "trucker": 45918,
+ "truckers": 43404,
+ "trucking": 26208,
+ "trucks": 9569,
+ "trude": 39017,
+ "trudeau": 15752,
+ "true": 13096,
+ "true": 2328,
+ "truec": 37583,
+ "truelove": 45711,
+ "truffle": 23064,
+ "truffles": 37057,
+ "truly": 4545,
+ "trum": 11766,
+ "trum": 11399,
+ "truman": 29414,
+ "trump": 9124,
+ "trump": 1797,
+ "trumpet": 23681,
+ "trumpp": 45550,
+ "trumprussia": 39135,
+ "trumps": 29793,
+ "trumptrain": 43595,
+ "trun": 16163,
+ "trun": 46661,
+ "trunk": 18347,
+ "trunks": 38531,
+ "truro": 43507,
+ "truss": 46080,
+ "trust": 17691,
+ "trust": 3876,
+ "truste": 17356,
+ "trusted": 16538,
+ "trustee": 30803,
+ "trustees": 28853,
+ "trusting": 33221,
+ "trusts": 27507,
+ "trustworthy": 46840,
+ "trusty": 37955,
+ "truth": 21335,
+ "truth": 4319,
+ "truths": 27179,
+ "trx": 31620,
+ "try": 4487,
+ "try": 1209,
+ "tryin": 31085,
+ "trying": 2551,
+ "tryna": 15702,
+ "tryout": 43832,
+ "tryouts": 28053,
+ "ts": 2290,
+ "ts": 590,
+ "tsa": 25977,
+ "tsal": 20438,
+ "tsb": 45015,
+ "tsc": 37437,
+ "tsch": 38778,
+ "tsd": 20611,
+ "tse": 49144,
+ "tsfor": 42654,
+ "tsford": 32823,
+ "tsh": 42872,
+ "tshirt": 14907,
+ "tshirts": 29377,
+ "tsi": 40048,
+ "tsi": 37867,
+ "tsk": 43600,
+ "tsla": 35681,
+ "tsm": 43452,
+ "tsman": 20046,
+ "tsn": 44921,
+ "tsn": 26896,
+ "tson": 42353,
+ "tson": 47140,
+ "tsp": 34230,
+ "tsu": 13950,
+ "tsu": 20175,
+ "tsun": 19155,
+ "tsunami": 24286,
+ "tsville": 29080,
+ "tt": 971,
+ "tt": 1402,
+ "tta": 2646,
+ "ttc": 27668,
+ "tte": 23105,
+ "tte": 3070,
+ "tted": 15163,
+ "tten": 11351,
+ "tten": 17479,
+ "tter": 18691,
+ "tter": 5165,
+ "tters": 6318,
+ "ttes": 9293,
+ "tti": 5237,
+ "ttin": 36589,
+ "tting": 1188,
+ "ttino": 47389,
+ "ttip": 46993,
+ "ttle": 9253,
+ "ttm": 46838,
+ "tto": 8759,
+ "tto": 8105,
+ "tton": 10562,
+ "ttot": 12480,
+ "ttp": 30828,
+ "ttr": 47589,
+ "tts": 11570,
+ "ttt": 17256,
+ "tttt": 33119,
+ "ttu": 44006,
+ "ttv": 24281,
+ "tty": 11457,
+ "tty": 1856,
+ "tu": 764,
+ "tu": 5760,
+ "tua": 41344,
+ "tual": 4799,
+ "tuan": 37297,
+ "tub": 34907,
+ "tub": 15450,
+ "tube": 38229,
+ "tube": 3308,
+ "tuber": 30371,
+ "tuberculo": 42606,
+ "tuberculosis": 43129,
+ "tubes": 22870,
+ "tubing": 40794,
+ "tubs": 41705,
+ "tubular": 48786,
+ "tuc": 14456,
+ "tuc": 43871,
+ "tuck": 22398,
+ "tucked": 26923,
+ "tucker": 39703,
+ "tucker": 15726,
+ "tucket": 32677,
+ "tucson": 17250,
+ "tudor": 24547,
+ "tue": 17515,
+ "tues": 2283,
+ "tues": 12113,
+ "tuesday": 10209,
+ "tuesday": 2519,
+ "tuesdaymotivation": 25432,
+ "tuesdays": 23195,
+ "tuesdaythoughts": 17988,
+ "tuf": 44510,
+ "tuff": 38868,
+ "tug": 47032,
+ "tug": 27902,
+ "tuition": 21129,
+ "tuk": 39271,
+ "tuk": 14993,
+ "tul": 9069,
+ "tul": 40837,
+ "tula": 36332,
+ "tulane": 44893,
+ "tulip": 28389,
+ "tulips": 30886,
+ "tulsa": 18850,
+ "tum": 12932,
+ "tum": 8843,
+ "tumb": 8831,
+ "tumble": 38284,
+ "tumbler": 48790,
+ "tumbling": 46226,
+ "tumblr": 11841,
+ "tummy": 26053,
+ "tumor": 22616,
+ "tumors": 39894,
+ "tumour": 45129,
+ "tun": 1415,
+ "tun": 21349,
+ "tuna": 15037,
+ "tundra": 39899,
+ "tune": 11427,
+ "tune": 3300,
+ "tuned": 5898,
+ "tunein": 16809,
+ "tuner": 42905,
+ "tunes": 31688,
+ "tunes": 10810,
+ "tunesapp": 32550,
+ "tung": 47940,
+ "tung": 31092,
+ "tuni": 16270,
+ "tunic": 43495,
+ "tuning": 19585,
+ "tunisia": 23346,
+ "tunnel": 11096,
+ "tunnels": 29814,
+ "tuous": 28738,
+ "tup": 37956,
+ "tup": 4507,
+ "tupac": 31506,
+ "tups": 44855,
+ "tur": 985,
+ "tur": 17182,
+ "tura": 16127,
+ "tural": 45143,
+ "tural": 4261,
+ "turb": 18973,
+ "turban": 48515,
+ "turbine": 26880,
+ "turbines": 38863,
+ "turbo": 23578,
+ "turbo": 13668,
+ "turbul": 31100,
+ "turbulent": 47871,
+ "ture": 4321,
+ "ture": 941,
+ "tured": 3987,
+ "turer": 11993,
+ "turers": 16956,
+ "tures": 2400,
+ "turf": 36762,
+ "turf": 12510,
+ "turi": 11896,
+ "turin": 36251,
+ "turing": 5812,
+ "turismo": 30202,
+ "turk": 8254,
+ "turk": 32507,
+ "turkey": 35977,
+ "turkey": 4790,
+ "turkeys": 37991,
+ "turkish": 48199,
+ "turkish": 9278,
+ "turks": 34344,
+ "turmeric": 34044,
+ "turmoil": 37751,
+ "turn": 5522,
+ "turn": 2105,
+ "turnaround": 32719,
+ "turnbull": 27863,
+ "turned": 3771,
+ "turner": 42867,
+ "turner": 8777,
+ "turning": 4976,
+ "turno": 21377,
+ "turnout": 11654,
+ "turnover": 30794,
+ "turnpike": 38301,
+ "turns": 3185,
+ "turnt": 28887,
+ "turntable": 37953,
+ "turnup": 30591,
+ "turo": 29224,
+ "turquo": 19390,
+ "turquoise": 19899,
+ "turt": 13716,
+ "turtle": 35943,
+ "turtle": 10912,
+ "turtles": 17862,
+ "tus": 24828,
+ "tus": 7079,
+ "tusc": 17909,
+ "tuscal": 42638,
+ "tuscaloosa": 44375,
+ "tuscan": 42865,
+ "tuscany": 20885,
+ "tuss": 31741,
+ "tut": 35121,
+ "tutor": 10054,
+ "tutor": 27858,
+ "tutorial": 12857,
+ "tutorials": 30973,
+ "tutoring": 37532,
+ "tutti": 46880,
+ "tutu": 35845,
+ "tux": 28720,
+ "tux": 49186,
+ "tuxedo": 40173,
+ "tv": 3197,
+ "tv": 1583,
+ "tvc": 49190,
+ "tvd": 25889,
+ "tvmiaw": 38554,
+ "tvn": 44232,
+ "tvs": 27114,
+ "tvtime": 19947,
+ "tvxq": 43968,
+ "tw": 966,
+ "tw": 12842,
+ "twa": 46954,
+ "twain": 30689,
+ "twal": 48126,
+ "tware": 5707,
+ "twc": 41217,
+ "twd": 29440,
+ "twd": 19343,
+ "twdfamily": 38218,
+ "twe": 18365,
+ "tweak": 48870,
+ "tweaks": 42661,
+ "twee": 1330,
+ "tweed": 26904,
+ "tweeps": 14928,
+ "tweet": 11826,
+ "tweet": 1842,
+ "tweeta": 32024,
+ "tweetapicture": 40596,
+ "tweeted": 7841,
+ "tweeter": 32876,
+ "tweeters": 31713,
+ "tweeting": 8901,
+ "tweets": 3560,
+ "tweetyour": 45033,
+ "twel": 14476,
+ "twelf": 39443,
+ "twelfth": 44072,
+ "twell": 38722,
+ "twell": 30162,
+ "twelve": 19694,
+ "twent": 27027,
+ "twenti": 35167,
+ "twenty": 13016,
+ "twentyon": 39609,
+ "twentyonepilots": 40007,
+ "twer": 13923,
+ "twerk": 28506,
+ "twi": 5537,
+ "twice": 6970,
+ "twick": 34326,
+ "twickenham": 39619,
+ "twil": 12804,
+ "twili": 35754,
+ "twilight": 46366,
+ "twilight": 14512,
+ "twill": 43703,
+ "twin": 9342,
+ "twin": 6769,
+ "twine": 42775,
+ "twinkle": 36545,
+ "twinning": 30156,
+ "twinpeaks": 32042,
+ "twins": 8040,
+ "twist": 10589,
+ "twisted": 18233,
+ "twister": 45933,
+ "twists": 34149,
+ "twit": 1643,
+ "twit": 18704,
+ "twitart": 27709,
+ "twitch": 13251,
+ "twitch": 9153,
+ "twitter": 7546,
+ "twitter": 1989,
+ "twitterkurds": 32722,
+ "twitterstorians": 35389,
+ "two": 17211,
+ "two": 1237,
+ "twol": 31964,
+ "twood": 40404,
+ "twood": 13245,
+ "twp": 33283,
+ "twright": 46778,
+ "twt": 6825,
+ "twx": 26830,
+ "twy": 45861,
+ "tx": 6636,
+ "tx": 5200,
+ "txhsfb": 34757,
+ "txlege": 26995,
+ "txst": 40761,
+ "txt": 24595,
+ "txwx": 22995,
+ "ty": 1260,
+ "ty": 744,
+ "tya": 41273,
+ "tycoon": 36803,
+ "tye": 43097,
+ "tyfree": 41215,
+ "tyga": 41952,
+ "tying": 22559,
+ "tyl": 47537,
+ "tyler": 14787,
+ "tyler": 7058,
+ "tym": 45772,
+ "tyne": 27000,
+ "tyne": 29729,
+ "tyour": 16823,
+ "type": 15673,
+ "type": 3877,
+ "typed": 40753,
+ "typeface": 44969,
+ "types": 7543,
+ "typewriter": 42180,
+ "typho": 17486,
+ "typhoon": 21110,
+ "typic": 21648,
+ "typical": 9854,
+ "typically": 23175,
+ "typing": 20102,
+ "typo": 18831,
+ "typo": 29076,
+ "typography": 24332,
+ "tyr": 15590,
+ "tyran": 46921,
+ "tyranny": 35402,
+ "tyre": 38330,
+ "tyre": 16864,
+ "tyres": 21376,
+ "tyrone": 30226,
+ "tyson": 16616,
+ "tz": 7710,
+ "tz": 4983,
+ "tzer": 45267,
+ "tzky": 47127,
+ "tzman": 46032,
+ "tzu": 34354,
+ "té": 27208,
+ "té": 39694,
+ "u": 84,
+ "u": 340,
+ "ua": 34075,
+ "ua": 8441,
+ "uaap": 46753,
+ "uaap": 43774,
+ "uab": 35587,
+ "uae": 9752,
+ "ual": 1921,
+ "ually": 10767,
+ "uan": 33062,
+ "uas": 38339,
+ "uav": 30303,
+ "ub": 18430,
+ "ub": 13494,
+ "uba": 29768,
+ "ubc": 42479,
+ "ubc": 29455,
+ "ube": 30892,
+ "uber": 25896,
+ "uber": 10668,
+ "ubi": 26758,
+ "ubio": 32867,
+ "ubiquit": 48129,
+ "ubis": 28248,
+ "ubisoft": 32051,
+ "ubs": 43851,
+ "ubun": 28184,
+ "ubuntu": 30791,
+ "uc": 4903,
+ "uc": 12438,
+ "uca": 30942,
+ "ucc": 44844,
+ "ucc": 29138,
+ "ucci": 30746,
+ "uccino": 30409,
+ "ucd": 44746,
+ "ucd": 43514,
+ "ucf": 24414,
+ "uch": 19465,
+ "uch": 22394,
+ "uchi": 37473,
+ "uci": 46354,
+ "uci": 28925,
+ "uck": 34189,
+ "ucl": 12013,
+ "ucl": 13647,
+ "ucla": 37667,
+ "ucla": 17259,
+ "ucn": 49036,
+ "uconn": 30549,
+ "ud": 6560,
+ "ud": 5765,
+ "uda": 22800,
+ "udaipur": 49385,
+ "uddin": 43035,
+ "ude": 37016,
+ "ude": 35194,
+ "ue": 16696,
+ "ue": 1190,
+ "uefa": 19189,
+ "uel": 24231,
+ "uer": 45951,
+ "ues": 2526,
+ "uf": 17777,
+ "uf": 19230,
+ "ufc": 20396,
+ "ufc": 6490,
+ "uff": 45701,
+ "ufo": 19443,
+ "ufos": 48234,
+ "ug": 3754,
+ "ug": 16061,
+ "uga": 16056,
+ "ugand": 25965,
+ "uganda": 11125,
+ "ugandan": 44206,
+ "ugby": 30658,
+ "ugh": 39736,
+ "ugh": 12755,
+ "ugliest": 43543,
+ "ugly": 36070,
+ "ugly": 8159,
+ "ugu": 18144,
+ "uh": 17661,
+ "uh": 9219,
+ "uhc": 44974,
+ "uhh": 35938,
+ "uhhh": 45270,
+ "uhm": 35614,
+ "uhur": 29434,
+ "uhuru": 35690,
+ "ui": 17326,
+ "ui": 11458,
+ "uil": 29395,
+ "uit": 30696,
+ "uit": 47584,
+ "uj": 33266,
+ "uji": 39672,
+ "uk": 2294,
+ "uk": 1432,
+ "uka": 23294,
+ "uke": 48836,
+ "uke": 28577,
+ "uked": 48987,
+ "uki": 37435,
+ "uki": 9009,
+ "ukin": 34996,
+ "ukip": 20360,
+ "uklabour": 36902,
+ "ukmfg": 38764,
+ "uko": 33562,
+ "ukone": 24682,
+ "ukrain": 15468,
+ "ukraine": 7768,
+ "ukrainian": 16927,
+ "ukrunchat": 34481,
+ "uku": 29541,
+ "uku": 36082,
+ "ukulele": 39094,
+ "ul": 914,
+ "ul": 6625,
+ "ula": 34104,
+ "ula": 9506,
+ "ular": 4927,
+ "ulary": 21701,
+ "ulate": 20467,
+ "ulation": 32896,
+ "ule": 35616,
+ "ules": 26274,
+ "ulf": 49331,
+ "uli": 41841,
+ "uli": 22174,
+ "ull": 33254,
+ "ulla": 30577,
+ "ullah": 45310,
+ "ullivan": 45252,
+ "ulls": 37418,
+ "ulo": 46084,
+ "ulo": 36738,
+ "ulous": 42490,
+ "ulous": 4281,
+ "ulously": 20167,
+ "ulster": 29709,
+ "ulster": 24639,
+ "ult": 4380,
+ "ulti": 11925,
+ "ulties": 21884,
+ "ultimat": 16522,
+ "ultimate": 34684,
+ "ultimate": 5377,
+ "ultimatefan": 48372,
+ "ultimatefanlive": 48644,
+ "ultimately": 23023,
+ "ultr": 25636,
+ "ultra": 11398,
+ "ultra": 8118,
+ "ultram": 44519,
+ "ultrasound": 29717,
+ "ulture": 22272,
+ "ulty": 8036,
+ "ulu": 41815,
+ "ulu": 15659,
+ "ulum": 17235,
+ "uly": 33220,
+ "ulysses": 46114,
+ "um": 1622,
+ "um": 1008,
+ "uma": 29982,
+ "uma": 9256,
+ "uman": 27112,
+ "umar": 25656,
+ "umass": 39390,
+ "umatic": 45006,
+ "umb": 7493,
+ "umber": 19195,
+ "umbrel": 34773,
+ "umbrella": 17143,
+ "umbrellas": 42782,
+ "umbria": 39287,
+ "umc": 39491,
+ "umd": 42067,
+ "ume": 38480,
+ "umen": 42832,
+ "uments": 25924,
+ "umer": 23539,
+ "umes": 21403,
+ "umi": 48772,
+ "umi": 15458,
+ "umich": 41294,
+ "umin": 31542,
+ "umm": 26129,
+ "umm": 21215,
+ "ummer": 47628,
+ "ummm": 33665,
+ "umni": 31739,
+ "ump": 22224,
+ "umpire": 36214,
+ "ums": 8643,
+ "umu": 39788,
+ "un": 569,
+ "un": 2271,
+ "una": 6385,
+ "unable": 17793,
+ "unacceptable": 25234,
+ "unanim": 20800,
+ "unanimous": 33520,
+ "unanimously": 31798,
+ "unanswered": 43611,
+ "unarmed": 41541,
+ "unas": 41366,
+ "unavailable": 48430,
+ "unaware": 33347,
+ "unbeat": 37056,
+ "unbeatable": 40267,
+ "unbeaten": 19228,
+ "unbeliev": 11383,
+ "unbelievable": 13306,
+ "unbelievably": 33781,
+ "unborn": 37257,
+ "unboxing": 32866,
+ "unbreakable": 32956,
+ "unbroken": 49271,
+ "unc": 24921,
+ "unc": 15322,
+ "uncanny": 32556,
+ "uncertain": 30384,
+ "uncertainty": 23956,
+ "unch": 1527,
+ "unchanged": 34272,
+ "uncharted": 34560,
+ "unci": 25521,
+ "unciation": 34117,
+ "uncle": 31537,
+ "uncle": 8002,
+ "unclear": 32955,
+ "uncles": 45335,
+ "uncomfortable": 22470,
+ "uncommon": 34888,
+ "uncondition": 46561,
+ "unconditional": 31112,
+ "unconscious": 34791,
+ "unconstitutional": 43585,
+ "unconventional": 39440,
+ "uncover": 33031,
+ "uncovered": 28234,
+ "uncture": 38736,
+ "uncut": 41056,
+ "und": 9762,
+ "und": 9732,
+ "unda": 39932,
+ "undant": 25377,
+ "unday": 29338,
+ "unde": 45226,
+ "undead": 40105,
+ "undecided": 49368,
+ "undefeated": 15326,
+ "undeni": 38424,
+ "under": 1473,
+ "under": 1798,
+ "underage": 45669,
+ "underattack": 35075,
+ "undercover": 21595,
+ "underdog": 44266,
+ "undere": 21675,
+ "underestim": 23348,
+ "underestimate": 31794,
+ "undergo": 31545,
+ "undergoing": 26419,
+ "undergrad": 38331,
+ "undergraduate": 24320,
+ "underground": 9396,
+ "undering": 30826,
+ "underlying": 31812,
+ "undermine": 42839,
+ "underneath": 20857,
+ "underrated": 19494,
+ "unders": 20376,
+ "understand": 47582,
+ "understand": 4600,
+ "understanding": 7522,
+ "understands": 21607,
+ "understatement": 38296,
+ "understood": 17303,
+ "undertaker": 40144,
+ "undertaking": 49067,
+ "undertale": 48283,
+ "underthe": 41161,
+ "underwater": 14760,
+ "underway": 6273,
+ "underwear": 21154,
+ "underwood": 21474,
+ "underworld": 34760,
+ "undi": 23845,
+ "undisclosed": 39334,
+ "undo": 35454,
+ "undocumented": 35414,
+ "undoub": 38836,
+ "undoubtedly": 42204,
+ "undp": 26691,
+ "une": 4522,
+ "une": 10966,
+ "unearth": 32716,
+ "unearthed": 36632,
+ "unemp": 15139,
+ "unemployed": 32721,
+ "unemployment": 19350,
+ "unes": 6394,
+ "unesco": 16216,
+ "uneven": 43204,
+ "unex": 9484,
+ "unexpe": 10802,
+ "unexpec": 31829,
+ "unexpected": 12293,
+ "unexpectedly": 35622,
+ "unf": 29285,
+ "unfair": 22193,
+ "unfinished": 26526,
+ "unfit": 45367,
+ "unfold": 38681,
+ "unfollow": 38797,
+ "unfor": 14010,
+ "unforgettable": 16173,
+ "unfortun": 10194,
+ "unfortunate": 22361,
+ "unfortunately": 12863,
+ "unfpa": 45048,
+ "ung": 10439,
+ "ung": 4334,
+ "unga": 19151,
+ "ungsoo": 25582,
+ "unh": 25365,
+ "unhappy": 26528,
+ "unhcr": 43451,
+ "unhealthy": 30994,
+ "uni": 1107,
+ "uni": 5926,
+ "unic": 7648,
+ "unicef": 38286,
+ "unicef": 19259,
+ "unicorn": 15660,
+ "unicorns": 35183,
+ "unidenti": 33707,
+ "unidentified": 35563,
+ "unification": 45036,
+ "unified": 20876,
+ "uniform": 11075,
+ "uniforms": 17838,
+ "unil": 32388,
+ "unilever": 48654,
+ "uniof": 21218,
+ "union": 14210,
+ "union": 3503,
+ "unions": 18353,
+ "unis": 30482,
+ "unis": 39266,
+ "unisex": 27609,
+ "unison": 46694,
+ "unit": 28522,
+ "unit": 5695,
+ "unite": 15078,
+ "unite": 11305,
+ "uniteblue": 20935,
+ "united": 10898,
+ "united": 2690,
+ "unitedstates": 39636,
+ "unitedway": 47486,
+ "unites": 32061,
+ "uniting": 31318,
+ "units": 10394,
+ "unity": 38300,
+ "unity": 8581,
+ "univ": 36680,
+ "univ": 14896,
+ "univer": 15574,
+ "univers": 5855,
+ "universal": 19148,
+ "universal": 8754,
+ "universe": 6104,
+ "universi": 41692,
+ "universit": 26019,
+ "universities": 16408,
+ "university": 40728,
+ "university": 2182,
+ "universityof": 46158,
+ "unk": 5542,
+ "unknown": 8685,
+ "unl": 43807,
+ "unlawful": 42305,
+ "unle": 19677,
+ "unlea": 23893,
+ "unleash": 26706,
+ "unleashed": 27955,
+ "unless": 10602,
+ "unlike": 16694,
+ "unlikely": 18904,
+ "unlimited": 11015,
+ "unlock": 18649,
+ "unlocked": 16770,
+ "unlocking": 40810,
+ "unlucky": 35029,
+ "unlv": 42283,
+ "unmanned": 36751,
+ "unmatched": 46054,
+ "unn": 38364,
+ "unnamed": 44985,
+ "unnecessary": 24100,
+ "unner": 31481,
+ "unning": 43282,
+ "unnoticed": 42807,
+ "uno": 32446,
+ "uno": 17078,
+ "unofficial": 22506,
+ "unpacking": 43589,
+ "unpaid": 32811,
+ "unparalleled": 44396,
+ "unplugged": 31724,
+ "unpopular": 40232,
+ "unprece": 23054,
+ "unprecedented": 23344,
+ "unpredictable": 38684,
+ "unra": 45150,
+ "unreal": 46980,
+ "unreal": 15636,
+ "unrelated": 38644,
+ "unreleased": 29654,
+ "unrest": 36452,
+ "uns": 25908,
+ "unsafe": 32071,
+ "unsc": 36395,
+ "unseen": 19069,
+ "unsigned": 39346,
+ "unsolved": 40836,
+ "unsplash": 46196,
+ "unstable": 34730,
+ "unstopp": 22105,
+ "unstoppable": 23484,
+ "unsuccessful": 47478,
+ "unsung": 33015,
+ "unsure": 26396,
+ "unt": 19654,
+ "unt": 6537,
+ "until": 1942,
+ "untitled": 21309,
+ "unto": 19801,
+ "untold": 32206,
+ "untouch": 44509,
+ "untouched": 42764,
+ "unused": 29636,
+ "unusual": 12613,
+ "unusually": 36465,
+ "unve": 6685,
+ "unveil": 20483,
+ "unveiled": 13572,
+ "unveiling": 20327,
+ "unveils": 15057,
+ "unwanted": 25285,
+ "unwind": 34064,
+ "unya": 37142,
+ "uo": 30874,
+ "uo": 36162,
+ "uof": 11155,
+ "uoft": 37329,
+ "uon": 48144,
+ "uous": 40185,
+ "up": 1083,
+ "up": 705,
+ "upa": 31727,
+ "upbeat": 39201,
+ "upcoming": 4196,
+ "upcycled": 46552,
+ "upd": 3226,
+ "update": 2491,
+ "updated": 5974,
+ "updates": 4904,
+ "updating": 22792,
+ "uper": 38082,
+ "uper": 33056,
+ "upfront": 42064,
+ "upgrade": 10365,
+ "upgraded": 18577,
+ "upgrades": 21253,
+ "upgrading": 34368,
+ "uph": 14128,
+ "uphill": 42767,
+ "uphol": 26195,
+ "uphold": 43897,
+ "upholstery": 44556,
+ "upl": 41939,
+ "uplift": 45389,
+ "uplifting": 29546,
+ "upload": 13968,
+ "uploaded": 16793,
+ "uploading": 30145,
+ "upon": 23524,
+ "upon": 5067,
+ "upp": 19549,
+ "upp": 45946,
+ "upper": 22465,
+ "upper": 7067,
+ "upri": 15982,
+ "upright": 29818,
+ "uprising": 26006,
+ "upro": 28922,
+ "ups": 6926,
+ "upscale": 47501,
+ "upset": 11214,
+ "upsets": 42637,
+ "upside": 15362,
+ "upstairs": 21387,
+ "upstate": 33335,
+ "upstream": 45517,
+ "upthe": 31510,
+ "upto": 26575,
+ "upton": 31910,
+ "uptown": 23807,
+ "upward": 32526,
+ "upwards": 34915,
+ "uq": 39591,
+ "ur": 565,
+ "ur": 1775,
+ "ura": 29337,
+ "ura": 3544,
+ "urable": 40194,
+ "ural": 23547,
+ "ural": 33948,
+ "uran": 16197,
+ "uranium": 29850,
+ "urban": 7931,
+ "urban": 5800,
+ "urbanart": 40834,
+ "urd": 47880,
+ "urday": 19742,
+ "urdu": 29976,
+ "ure": 5514,
+ "ure": 726,
+ "ured": 4210,
+ "urer": 20864,
+ "ures": 2288,
+ "urg": 35995,
+ "urge": 14852,
+ "urged": 23790,
+ "urgency": 47612,
+ "urgent": 13693,
+ "urgently": 34534,
+ "urges": 16692,
+ "urging": 27748,
+ "uri": 11052,
+ "uri": 8699,
+ "urie": 46429,
+ "urin": 45245,
+ "urine": 28864,
+ "uring": 1351,
+ "url": 23464,
+ "urn": 38075,
+ "uro": 17343,
+ "uro": 5925,
+ "urology": 48585,
+ "urope": 14918,
+ "urs": 4794,
+ "urself": 31942,
+ "urst": 19181,
+ "urstruly": 34751,
+ "urstrulymahesh": 35314,
+ "ursula": 38390,
+ "urt": 24309,
+ "uru": 16322,
+ "uru": 11768,
+ "uruguay": 27931,
+ "urus": 14246,
+ "urve": 24583,
+ "ury": 8642,
+ "ury": 2106,
+ "us": 904,
+ "us": 718,
+ "usa": 9491,
+ "usa": 2547,
+ "usability": 46736,
+ "usable": 22890,
+ "usaf": 25017,
+ "usage": 19137,
+ "usaid": 34507,
+ "usair": 36742,
+ "usairforce": 42179,
+ "usarmy": 19132,
+ "usatoday": 40263,
+ "usav": 36056,
+ "usb": 10281,
+ "usc": 13346,
+ "usc": 14995,
+ "uscg": 43932,
+ "usd": 7485,
+ "usda": 25829,
+ "use": 4419,
+ "use": 1483,
+ "used": 32289,
+ "used": 2026,
+ "useful": 9784,
+ "useless": 20154,
+ "usemb": 39700,
+ "user": 21248,
+ "user": 7031,
+ "username": 28162,
+ "users": 7433,
+ "uses": 5282,
+ "useum": 45189,
+ "usf": 32385,
+ "usf": 28942,
+ "usgs": 35103,
+ "ush": 12001,
+ "ush": 18335,
+ "usher": 27411,
+ "ushi": 47734,
+ "usi": 25540,
+ "usic": 34909,
+ "usic": 16753,
+ "using": 1996,
+ "usky": 45778,
+ "usl": 42113,
+ "usm": 40041,
+ "usmc": 21678,
+ "usmnt": 30662,
+ "usn": 40579,
+ "usnavy": 24500,
+ "usnews": 43752,
+ "uso": 21539,
+ "usopen": 21782,
+ "usp": 26651,
+ "usps": 39980,
+ "usrc": 33274,
+ "uss": 11545,
+ "uss": 9260,
+ "ussia": 29553,
+ "ussoccer": 42828,
+ "ussr": 32697,
+ "ust": 35501,
+ "ust": 24725,
+ "usu": 4254,
+ "usu": 40434,
+ "usual": 6129,
+ "usually": 8296,
+ "usur": 45582,
+ "uswnt": 35255,
+ "ut": 1419,
+ "ut": 3641,
+ "uta": 42706,
+ "uta": 25925,
+ "utah": 27474,
+ "utah": 9312,
+ "utc": 18196,
+ "utd": 10493,
+ "ute": 16856,
+ "ute": 3130,
+ "uten": 32089,
+ "uter": 39197,
+ "utes": 2850,
+ "uth": 48819,
+ "uth": 44750,
+ "uti": 24568,
+ "util": 28824,
+ "utili": 17015,
+ "utilities": 27210,
+ "utility": 14941,
+ "utilize": 36861,
+ "utilized": 47604,
+ "utilizing": 40212,
+ "utm": 47853,
+ "utmost": 42352,
+ "uto": 18866,
+ "uto": 13683,
+ "utopia": 34433,
+ "utpol": 42605,
+ "utr": 48726,
+ "utrecht": 37216,
+ "uts": 11740,
+ "utsa": 37528,
+ "utt": 17096,
+ "uttar": 40168,
+ "uttarak": 33755,
+ "uttarakhand": 35655,
+ "utter": 18769,
+ "utter": 24558,
+ "utterly": 21353,
+ "utto": 42183,
+ "utv": 36351,
+ "utz": 45320,
+ "uu": 5702,
+ "uu": 14553,
+ "uuu": 44355,
+ "uuu": 27656,
+ "uuuu": 16720,
+ "uuuu": 40797,
+ "uv": 23777,
+ "uv": 15977,
+ "uva": 23908,
+ "uw": 13933,
+ "uw": 19166,
+ "uwe": 48785,
+ "uwu": 35544,
+ "ux": 9251,
+ "ux": 6213,
+ "uy": 31929,
+ "uy": 48113,
+ "uz": 19398,
+ "uz": 36991,
+ "uzbe": 43007,
+ "uzbekistan": 45024,
+ "uzzi": 48210,
+ "v": 85,
+ "v": 341,
+ "va": 4648,
+ "va": 1892,
+ "vaa": 37488,
+ "vable": 23088,
+ "vac": 3125,
+ "vac": 34085,
+ "vaca": 48215,
+ "vacancies": 26333,
+ "vacancy": 21247,
+ "vacant": 25262,
+ "vacation": 28336,
+ "vacation": 6561,
+ "vacations": 29002,
+ "vacay": 44716,
+ "vacc": 13342,
+ "vaccin": 19164,
+ "vaccinated": 48134,
+ "vaccination": 32518,
+ "vaccine": 47780,
+ "vaccine": 17493,
+ "vaccines": 25860,
+ "vach": 46211,
+ "vacu": 16058,
+ "vacuum": 18420,
+ "vad": 11880,
+ "vada": 46759,
+ "vader": 21908,
+ "vae": 39384,
+ "vag": 13015,
+ "vague": 42154,
+ "vah": 26921,
+ "vai": 26893,
+ "vai": 36802,
+ "vail": 21189,
+ "vain": 25538,
+ "vais": 28719,
+ "vaj": 34206,
+ "vak": 16288,
+ "vak": 41597,
+ "val": 1214,
+ "val": 1560,
+ "vala": 48525,
+ "valdez": 40617,
+ "vale": 35554,
+ "vale": 10820,
+ "valedic": 43525,
+ "valen": 12630,
+ "valence": 30225,
+ "valenci": 34183,
+ "valencia": 16559,
+ "valent": 3655,
+ "valent": 15300,
+ "valentin": 48631,
+ "valentina": 43741,
+ "valentine": 11208,
+ "valentine": 5876,
+ "valentines": 10259,
+ "valentinesday": 12369,
+ "valentino": 29624,
+ "valeri": 31951,
+ "valerie": 25592,
+ "valet": 45749,
+ "vali": 8230,
+ "valiant": 33804,
+ "valid": 15126,
+ "validation": 32536,
+ "valkyrie": 42326,
+ "vall": 23523,
+ "vall": 35295,
+ "vallarta": 47874,
+ "valle": 24857,
+ "valle": 29105,
+ "valley": 18354,
+ "valley": 3136,
+ "valleys": 28649,
+ "valor": 30930,
+ "vals": 7431,
+ "valu": 6291,
+ "valuable": 10056,
+ "valuation": 25894,
+ "value": 41358,
+ "value": 4602,
+ "valued": 17801,
+ "values": 8857,
+ "valve": 17001,
+ "valves": 33517,
+ "vam": 9983,
+ "vamo": 46718,
+ "vamos": 30346,
+ "vamp": 10680,
+ "vampi": 47017,
+ "vampire": 47576,
+ "vampire": 13220,
+ "vampires": 30868,
+ "vamps": 44810,
+ "van": 2446,
+ "van": 2451,
+ "vana": 20543,
+ "vanc": 6320,
+ "vance": 31447,
+ "vancou": 6750,
+ "vancouver": 31904,
+ "vancouver": 7208,
+ "vand": 11691,
+ "vandalism": 45664,
+ "vander": 16264,
+ "vanderbilt": 33524,
+ "vandy": 39268,
+ "vane": 43828,
+ "vaness": 13328,
+ "vanessa": 16836,
+ "vangogh": 47849,
+ "vanguard": 27916,
+ "vani": 15396,
+ "vani": 26459,
+ "vania": 10998,
+ "vanilla": 11974,
+ "vanished": 43783,
+ "vanishing": 48296,
+ "vanity": 48353,
+ "vanity": 22938,
+ "vans": 11711,
+ "vant": 26298,
+ "vantage": 31749,
+ "vanu": 42892,
+ "vanuatu": 48766,
+ "vap": 10462,
+ "vape": 25423,
+ "vape": 20219,
+ "vaping": 29403,
+ "vapor": 37167,
+ "vapor": 30729,
+ "vapori": 46183,
+ "var": 3187,
+ "var": 12998,
+ "vara": 47492,
+ "varan": 36585,
+ "varanasi": 39364,
+ "vard": 21866,
+ "vard": 8773,
+ "vardy": 47371,
+ "vare": 38159,
+ "vares": 42895,
+ "vargas": 32752,
+ "vari": 3354,
+ "variable": 26416,
+ "varian": 34334,
+ "variant": 20293,
+ "variants": 38312,
+ "variation": 26420,
+ "variations": 29025,
+ "varied": 32334,
+ "varies": 32543,
+ "varieties": 23805,
+ "variety": 8396,
+ "various": 7395,
+ "varsity": 43716,
+ "varsity": 8574,
+ "varun": 48120,
+ "varun": 22069,
+ "vary": 18855,
+ "varying": 36456,
+ "vas": 5669,
+ "vas": 5995,
+ "vasc": 40995,
+ "vascular": 19218,
+ "vase": 20431,
+ "vasi": 49092,
+ "vast": 24413,
+ "vast": 16414,
+ "vastly": 48257,
+ "vat": 11588,
+ "vat": 18363,
+ "vatican": 21030,
+ "vation": 37884,
+ "vau": 6391,
+ "vaugh": 25158,
+ "vaughan": 21392,
+ "vaughn": 29013,
+ "vaul": 27469,
+ "vault": 15240,
+ "vaus": 40217,
+ "vaux": 27403,
+ "vauxhall": 29173,
+ "vaw": 47952,
+ "vay": 48000,
+ "vaz": 38142,
+ "vb": 29365,
+ "vb": 8778,
+ "vball": 38329,
+ "vc": 28670,
+ "vc": 7952,
+ "vcs": 43528,
+ "vcu": 40102,
+ "vd": 9515,
+ "vday": 42055,
+ "ve": 673,
+ "ve": 563,
+ "vea": 43798,
+ "veal": 36616,
+ "veau": 24419,
+ "vec": 19912,
+ "vector": 40453,
+ "vector": 21533,
+ "ved": 19515,
+ "ved": 1102,
+ "veda": 44401,
+ "vedere": 45660,
+ "vedi": 47971,
+ "vee": 35708,
+ "vee": 17073,
+ "veen": 22432,
+ "veer": 21243,
+ "veer": 22058,
+ "veg": 9048,
+ "veg": 16460,
+ "vega": 22930,
+ "vegan": 15705,
+ "vegan": 5615,
+ "vegans": 48514,
+ "vegas": 20288,
+ "vegas": 4413,
+ "vege": 6219,
+ "vegetable": 15725,
+ "vegetables": 14119,
+ "vegetarian": 14600,
+ "vegetation": 33947,
+ "veggie": 19401,
+ "veggies": 16767,
+ "vehic": 3973,
+ "vehicle": 5299,
+ "vehicles": 8361,
+ "veil": 23516,
+ "vein": 29169,
+ "veins": 28867,
+ "veit": 30620,
+ "vel": 942,
+ "vel": 1287,
+ "vela": 34898,
+ "veld": 34011,
+ "veled": 15370,
+ "veli": 49166,
+ "veling": 37970,
+ "vell": 21173,
+ "vell": 32997,
+ "velo": 14357,
+ "velo": 33850,
+ "velocity": 23811,
+ "vels": 5109,
+ "velve": 37849,
+ "velvet": 11063,
+ "vely": 1708,
+ "vember": 3477,
+ "vement": 3129,
+ "vements": 11104,
+ "ven": 1240,
+ "ven": 1638,
+ "vena": 47442,
+ "vend": 10851,
+ "vending": 29202,
+ "vendor": 21261,
+ "vendors": 20353,
+ "vene": 5365,
+ "veness": 10516,
+ "venetian": 34336,
+ "venezia": 34139,
+ "venezu": 10939,
+ "venezuela": 12839,
+ "venezuelan": 34699,
+ "veng": 31526,
+ "venge": 27757,
+ "vengeance": 32057,
+ "veni": 31142,
+ "venice": 11010,
+ "vening": 47532,
+ "venison": 40037,
+ "venom": 42491,
+ "venom": 21588,
+ "vens": 20884,
+ "vent": 4373,
+ "vent": 5687,
+ "ventil": 39522,
+ "ventilation": 35066,
+ "venting": 15731,
+ "vention": 4122,
+ "vents": 12833,
+ "ventu": 48217,
+ "ventura": 20921,
+ "venture": 37046,
+ "venture": 12543,
+ "ventures": 20829,
+ "venue": 5097,
+ "venues": 18120,
+ "venus": 14691,
+ "ver": 624,
+ "ver": 667,
+ "vera": 13350,
+ "verage": 3725,
+ "verb": 34952,
+ "verbal": 26522,
+ "verbally": 39985,
+ "verbs": 45687,
+ "verde": 16935,
+ "verdi": 42306,
+ "verdict": 18030,
+ "vere": 11135,
+ "vere": 34707,
+ "vered": 2868,
+ "verge": 23913,
+ "veri": 11638,
+ "verification": 33521,
+ "verified": 22555,
+ "verify": 34722,
+ "vering": 4630,
+ "veriz": 19707,
+ "verizon": 21532,
+ "verma": 41261,
+ "vermont": 19241,
+ "vern": 2214,
+ "vern": 12586,
+ "verne": 45553,
+ "vernon": 18348,
+ "vero": 45217,
+ "vero": 38208,
+ "verona": 31819,
+ "veronic": 39551,
+ "veronica": 24039,
+ "vers": 1219,
+ "vers": 2094,
+ "versa": 35765,
+ "versace": 25422,
+ "versail": 29857,
+ "versailles": 32129,
+ "versary": 2940,
+ "versatile": 18110,
+ "versatility": 41340,
+ "verse": 39466,
+ "verse": 3131,
+ "verses": 30769,
+ "versi": 8934,
+ "version": 3273,
+ "versions": 16190,
+ "versity": 1906,
+ "verst": 42484,
+ "verstappen": 45064,
+ "versus": 14548,
+ "versy": 18522,
+ "vert": 11742,
+ "verte": 35158,
+ "verted": 48173,
+ "verti": 30459,
+ "vertical": 14293,
+ "vertigo": 42477,
+ "verton": 40632,
+ "verts": 37265,
+ "very": 11698,
+ "very": 1070,
+ "veryday": 37944,
+ "verything": 45174,
+ "ves": 9616,
+ "ves": 1003,
+ "vesmatter": 47636,
+ "vespa": 46029,
+ "vessel": 16387,
+ "vessels": 22822,
+ "vest": 31657,
+ "vest": 12473,
+ "vesti": 40349,
+ "vests": 41906,
+ "vet": 12294,
+ "vet": 5951,
+ "veter": 4330,
+ "veteran": 20797,
+ "veteran": 8814,
+ "veterans": 7092,
+ "veteransday": 26409,
+ "veterin": 43959,
+ "veterinary": 25458,
+ "veto": 36570,
+ "vets": 13113,
+ "vette": 17045,
+ "vettel": 28700,
+ "vevo": 35141,
+ "vex": 36187,
+ "vex": 43978,
+ "vey": 34792,
+ "vey": 3884,
+ "vez": 35987,
+ "vez": 17226,
+ "vf": 25966,
+ "vfl": 33726,
+ "vfx": 30149,
+ "vg": 40591,
+ "vg": 22346,
+ "vh": 46953,
+ "vh": 23847,
+ "vhs": 21932,
+ "vi": 603,
+ "vi": 4259,
+ "via": 1048,
+ "viable": 25752,
+ "viadu": 37012,
+ "viaduct": 39113,
+ "vial": 39951,
+ "vian": 40487,
+ "vian": 16124,
+ "vibe": 37974,
+ "vibe": 12813,
+ "vibes": 7764,
+ "vibr": 9527,
+ "vibrant": 14270,
+ "vibration": 37456,
+ "vibrations": 43660,
+ "vic": 1555,
+ "vic": 4412,
+ "vica": 46168,
+ "vicar": 43899,
+ "vice": 43572,
+ "vice": 6931,
+ "vicente": 39411,
+ "vices": 8332,
+ "vich": 24143,
+ "vici": 46670,
+ "vicious": 25177,
+ "vick": 15116,
+ "vick": 29704,
+ "vickers": 48452,
+ "vicki": 34927,
+ "vicky": 37176,
+ "vicky": 25788,
+ "victi": 6861,
+ "victim": 9133,
+ "victims": 7131,
+ "victor": 2423,
+ "victor": 10690,
+ "victori": 17555,
+ "victoria": 39286,
+ "victoria": 6127,
+ "victorian": 12350,
+ "victorias": 47791,
+ "victories": 24577,
+ "victorious": 24033,
+ "victory": 36668,
+ "victory": 4127,
+ "vid": 17233,
+ "vid": 9284,
+ "vida": 19015,
+ "vidal": 36678,
+ "vide": 1334,
+ "vide": 45244,
+ "video": 9478,
+ "video": 1455,
+ "videogame": 35097,
+ "videogames": 21149,
+ "videos": 6081,
+ "vids": 23035,
+ "vidy": 29639,
+ "vidya": 45264,
+ "vie": 922,
+ "vie": 8538,
+ "vien": 36493,
+ "vienna": 12670,
+ "vier": 15352,
+ "vier": 11987,
+ "viera": 21114,
+ "viernes": 33826,
+ "vies": 22458,
+ "viest": 31979,
+ "viet": 17558,
+ "viet": 13128,
+ "vietnam": 19558,
+ "vietnam": 8623,
+ "vietnamese": 22382,
+ "view": 12004,
+ "view": 1093,
+ "viewed": 7226,
+ "viewer": 15061,
+ "viewers": 14275,
+ "viewing": 7124,
+ "viewpoint": 41604,
+ "views": 2758,
+ "vig": 8549,
+ "vig": 45083,
+ "vigil": 21538,
+ "vigil": 19896,
+ "vigilant": 43026,
+ "vigne": 40447,
+ "vigne": 34581,
+ "vigo": 44097,
+ "vigor": 26781,
+ "vii": 17759,
+ "viii": 20414,
+ "vijay": 12014,
+ "vijay": 10823,
+ "vijaysethu": 47966,
+ "vik": 10764,
+ "vik": 17181,
+ "vika": 39562,
+ "vikas": 37116,
+ "viking": 26663,
+ "viking": 15897,
+ "vikings": 11713,
+ "vikram": 41136,
+ "vikram": 24314,
+ "viktor": 36101,
+ "vil": 1338,
+ "vil": 3000,
+ "vila": 37505,
+ "vile": 27247,
+ "vill": 10481,
+ "vill": 45698,
+ "villa": 3203,
+ "villa": 7754,
+ "village": 34584,
+ "village": 4331,
+ "villagers": 34283,
+ "villages": 17621,
+ "villain": 15425,
+ "villains": 25271,
+ "villanova": 44025,
+ "villar": 35164,
+ "villas": 28907,
+ "ville": 11110,
+ "ville": 1930,
+ "villen": 46177,
+ "villi": 36907,
+ "vimeo": 48720,
+ "vin": 1379,
+ "vin": 2558,
+ "vina": 35682,
+ "vinai": 37396,
+ "vinaigrette": 39876,
+ "vinay": 43952,
+ "vince": 32429,
+ "vince": 6236,
+ "vincen": 33402,
+ "vincent": 29069,
+ "vincent": 10357,
+ "vinci": 30199,
+ "vind": 20275,
+ "vindic": 39582,
+ "vine": 8471,
+ "vine": 7721,
+ "vinegar": 23834,
+ "vines": 21268,
+ "vineyard": 16527,
+ "vineyards": 23082,
+ "ving": 5375,
+ "ving": 903,
+ "vingne": 42579,
+ "vings": 22510,
+ "vini": 48119,
+ "vinnie": 40885,
+ "vinny": 36794,
+ "vino": 14509,
+ "vinod": 43348,
+ "vins": 34820,
+ "vinson": 45945,
+ "vintag": 10936,
+ "vintage": 13654,
+ "vintage": 3266,
+ "viny": 40990,
+ "vinyl": 22835,
+ "vinyl": 5754,
+ "vio": 11913,
+ "vio": 20324,
+ "viol": 3164,
+ "viola": 27438,
+ "violate": 44875,
+ "violated": 38192,
+ "violating": 37554,
+ "violation": 22919,
+ "violations": 21969,
+ "violence": 5450,
+ "violent": 11565,
+ "violently": 47758,
+ "violet": 16118,
+ "violets": 42861,
+ "violin": 17058,
+ "violinist": 36299,
+ "vion": 35496,
+ "vious": 6418,
+ "viously": 7149,
+ "vip": 45714,
+ "vip": 7111,
+ "viper": 27401,
+ "vips": 41149,
+ "vir": 1790,
+ "vir": 25319,
+ "vira": 35910,
+ "viral": 11653,
+ "virat": 32473,
+ "virgil": 39076,
+ "virgin": 5651,
+ "virgin": 12103,
+ "virgini": 43426,
+ "virginia": 6728,
+ "virgo": 39978,
+ "viro": 32301,
+ "viron": 38309,
+ "virtu": 7977,
+ "virtual": 18059,
+ "virtual": 7790,
+ "virtually": 22475,
+ "virtualreality": 32608,
+ "virtue": 26860,
+ "virtues": 42167,
+ "virtuoso": 47027,
+ "virus": 11808,
+ "viruses": 34830,
+ "vis": 1301,
+ "vis": 5337,
+ "visa": 12802,
+ "visas": 41228,
+ "vise": 24977,
+ "vised": 14810,
+ "vish": 12024,
+ "vish": 29124,
+ "vishal": 33648,
+ "vishnu": 37816,
+ "visi": 1409,
+ "visibility": 15921,
+ "visible": 36658,
+ "visible": 8626,
+ "vising": 37439,
+ "vision": 11147,
+ "vision": 2515,
+ "visional": 24627,
+ "visionary": 22959,
+ "visions": 13804,
+ "visit": 3388,
+ "visit": 1600,
+ "visitation": 44370,
+ "visited": 5580,
+ "visiting": 4680,
+ "visitor": 13881,
+ "visitors": 9160,
+ "visits": 8489,
+ "visitscotland": 28760,
+ "visitspain": 48860,
+ "vism": 15514,
+ "viso": 46732,
+ "visor": 24217,
+ "vist": 21436,
+ "vista": 13865,
+ "visu": 7739,
+ "visual": 17004,
+ "visual": 7195,
+ "visualization": 28500,
+ "visualize": 45057,
+ "visually": 25743,
+ "visuals": 21315,
+ "viswas": 36513,
+ "viswasam": 47664,
+ "vit": 4056,
+ "vit": 35580,
+ "vita": 15700,
+ "vital": 32525,
+ "vital": 10585,
+ "vitality": 36385,
+ "vitam": 9856,
+ "vitamin": 13675,
+ "vitamins": 22582,
+ "vito": 36725,
+ "vity": 4893,
+ "vitz": 26188,
+ "vius": 41571,
+ "viv": 21827,
+ "viv": 35363,
+ "viva": 17399,
+ "vival": 35920,
+ "vive": 18980,
+ "vive": 24004,
+ "vivek": 36243,
+ "vivi": 11625,
+ "vivian": 30129,
+ "vivid": 22984,
+ "vivo": 28091,
+ "vivo": 25888,
+ "vix": 28976,
+ "vix": 34811,
+ "vixen": 38757,
+ "vixx": 32106,
+ "viz": 28251,
+ "viz": 31786,
+ "vj": 45439,
+ "vj": 30827,
+ "vk": 41893,
+ "vl": 37580,
+ "vl": 36442,
+ "vla": 23686,
+ "vlad": 41089,
+ "vladi": 19320,
+ "vladimir": 21702,
+ "vlive": 46797,
+ "vlog": 18894,
+ "vm": 16204,
+ "vm": 20269,
+ "vma": 35666,
+ "vmas": 30236,
+ "vmware": 29615,
+ "vn": 47098,
+ "vn": 25076,
+ "vo": 947,
+ "vo": 3951,
+ "voc": 4105,
+ "voc": 20855,
+ "vocab": 21346,
+ "vocabulary": 23804,
+ "vocal": 34037,
+ "vocal": 13147,
+ "vocali": 19134,
+ "vocalist": 22102,
+ "vocals": 17666,
+ "vocation": 20521,
+ "vocational": 33751,
+ "vod": 11820,
+ "vod": 35854,
+ "vodaf": 28436,
+ "vodafone": 38695,
+ "vodka": 13646,
+ "vogel": 44960,
+ "vogue": 24418,
+ "vogue": 13178,
+ "voic": 29185,
+ "voice": 13179,
+ "voice": 3386,
+ "voiced": 34352,
+ "voiceof": 44966,
+ "voiceover": 41979,
+ "voices": 9144,
+ "void": 21561,
+ "voip": 42762,
+ "voir": 16036,
+ "vol": 1343,
+ "vol": 7945,
+ "volatile": 41022,
+ "volatility": 32355,
+ "volcan": 9916,
+ "volcanic": 24072,
+ "volcano": 14581,
+ "volcanoes": 38055,
+ "voli": 40138,
+ "volk": 13432,
+ "volkswag": 14407,
+ "volkswagen": 15342,
+ "volley": 7130,
+ "volley": 34656,
+ "volleyball": 7458,
+ "volo": 44791,
+ "vols": 20404,
+ "volt": 26430,
+ "volta": 29879,
+ "volta": 33480,
+ "voltage": 23118,
+ "voltron": 39314,
+ "volu": 3563,
+ "volume": 8284,
+ "volumes": 22651,
+ "volun": 3356,
+ "voluntar": 48823,
+ "voluntary": 23815,
+ "volunte": 3556,
+ "volunteer": 32331,
+ "volunteer": 7114,
+ "volunteered": 34000,
+ "volunteering": 14902,
+ "volunteers": 5939,
+ "volution": 24043,
+ "volved": 42888,
+ "volvo": 39991,
+ "volvo": 16906,
+ "vom": 24198,
+ "vomit": 46485,
+ "von": 11269,
+ "von": 8497,
+ "voo": 19497,
+ "voodoo": 26869,
+ "voor": 34291,
+ "voor": 34464,
+ "vor": 8338,
+ "vor": 5308,
+ "vore": 18215,
+ "vortex": 30071,
+ "vos": 16863,
+ "vot": 48558,
+ "vote": 6830,
+ "vote": 2187,
+ "voted": 6454,
+ "votel": 41379,
+ "voter": 44474,
+ "voter": 14065,
+ "voters": 8925,
+ "votes": 6693,
+ "voting": 5756,
+ "vou": 11045,
+ "voucher": 18190,
+ "vouchers": 23384,
+ "vous": 10636,
+ "vow": 34787,
+ "vows": 21677,
+ "vox": 29215,
+ "vox": 22692,
+ "voy": 10622,
+ "voy": 15021,
+ "voyage": 16299,
+ "voyager": 29669,
+ "vp": 32758,
+ "vp": 3896,
+ "vpn": 38212,
+ "vr": 16840,
+ "vr": 5921,
+ "vre": 44500,
+ "vre": 17501,
+ "vs": 11385,
+ "vs": 1547,
+ "vsco": 26752,
+ "vsco": 32822,
+ "vscocam": 34694,
+ "vsky": 37791,
+ "vss": 31919,
+ "vt": 31732,
+ "vt": 10291,
+ "vu": 8664,
+ "vu": 13230,
+ "vue": 43915,
+ "vue": 19313,
+ "vuel": 31312,
+ "vuelta": 43856,
+ "vuitton": 26705,
+ "vul": 6856,
+ "vulcan": 34767,
+ "vulner": 11213,
+ "vulnerability": 28797,
+ "vulnerable": 14332,
+ "vulture": 34593,
+ "vultures": 47197,
+ "vv": 19264,
+ "vv": 35686,
+ "vw": 28650,
+ "vw": 13250,
+ "vx": 47644,
+ "vy": 11566,
+ "vy": 5157,
+ "w": 86,
+ "w": 342,
+ "wa": 869,
+ "wa": 2663,
+ "waa": 35874,
+ "wab": 19893,
+ "wab": 36852,
+ "wac": 27445,
+ "wac": 37947,
+ "wack": 22880,
+ "wack": 38270,
+ "wacky": 34318,
+ "waco": 36035,
+ "wad": 11133,
+ "wad": 30451,
+ "wada": 40006,
+ "wade": 40237,
+ "wade": 14180,
+ "wadi": 37253,
+ "waf": 17638,
+ "wafc": 49086,
+ "waff": 13940,
+ "waffle": 20375,
+ "waffles": 24205,
+ "wag": 5764,
+ "wag": 19177,
+ "wage": 10716,
+ "wager": 43430,
+ "wages": 19114,
+ "wagner": 18081,
+ "wagon": 13260,
+ "wagons": 47944,
+ "wags": 48580,
+ "wah": 24812,
+ "wah": 18014,
+ "wahl": 27500,
+ "wahlberg": 35151,
+ "wahoo": 47995,
+ "wai": 11469,
+ "wai": 21569,
+ "waifu": 46551,
+ "waikiki": 44907,
+ "wain": 28358,
+ "wain": 20120,
+ "wainwright": 45878,
+ "waist": 36946,
+ "waist": 18459,
+ "wait": 10021,
+ "wait": 1885,
+ "waite": 24272,
+ "waited": 18492,
+ "waiter": 32946,
+ "waitin": 44482,
+ "waiting": 2680,
+ "waitress": 39760,
+ "waitrose": 37164,
+ "waits": 21361,
+ "waiver": 42866,
+ "waj": 49367,
+ "wak": 11172,
+ "wak": 36015,
+ "waka": 42696,
+ "wake": 10501,
+ "wake": 5731,
+ "wakefield": 26358,
+ "wakes": 29108,
+ "wakeup": 26328,
+ "wakeup": 35380,
+ "wakeupamerica": 37474,
+ "waking": 13025,
+ "wal": 1056,
+ "wal": 6903,
+ "wala": 16468,
+ "walang": 49180,
+ "walcott": 45744,
+ "wald": 46930,
+ "wald": 15724,
+ "walden": 39311,
+ "waldo": 32440,
+ "waldorf": 38227,
+ "wale": 41247,
+ "wale": 20336,
+ "wales": 25383,
+ "wales": 5110,
+ "walgreens": 38490,
+ "wali": 37576,
+ "wali": 14768,
+ "walia": 44455,
+ "walk": 8588,
+ "walk": 2374,
+ "walkaway": 48255,
+ "walked": 8667,
+ "walker": 24735,
+ "walker": 6150,
+ "walkers": 23366,
+ "walkin": 45792,
+ "walking": 12644,
+ "walking": 3941,
+ "walkingdead": 14948,
+ "walkout": 47470,
+ "walks": 8192,
+ "walkway": 36614,
+ "wall": 4316,
+ "wall": 2569,
+ "walla": 26007,
+ "walla": 39982,
+ "wallabies": 48926,
+ "wallace": 12535,
+ "wallart": 36223,
+ "walled": 36567,
+ "waller": 45340,
+ "wallet": 12154,
+ "wallets": 38550,
+ "walleye": 49099,
+ "wallis": 42206,
+ "wallpaper": 10560,
+ "wallpapers": 29841,
+ "walls": 8258,
+ "wallstreet": 45341,
+ "wally": 26024,
+ "walmart": 11972,
+ "walnut": 16310,
+ "walnuts": 38294,
+ "walsall": 42935,
+ "walsh": 12856,
+ "walt": 23535,
+ "walt": 14312,
+ "waltdisneyworld": 36505,
+ "walter": 31156,
+ "walter": 10645,
+ "walters": 25532,
+ "waltham": 42742,
+ "waltham": 45581,
+ "walton": 19485,
+ "waltz": 35982,
+ "wam": 20503,
+ "wamy": 46970,
+ "wan": 2060,
+ "wan": 4557,
+ "wana": 30830,
+ "wand": 14636,
+ "wand": 28559,
+ "wanda": 25070,
+ "wander": 12985,
+ "wander": 24473,
+ "wandered": 46593,
+ "wanderers": 27540,
+ "wandering": 22597,
+ "wanderlust": 16129,
+ "wane": 27459,
+ "wang": 19731,
+ "wang": 11900,
+ "wani": 21674,
+ "wankers": 42189,
+ "wann": 23622,
+ "wanna": 35940,
+ "wanna": 3836,
+ "wannabe": 40730,
+ "wannaone": 44832,
+ "want": 18356,
+ "want": 1280,
+ "wanted": 3146,
+ "wanting": 12801,
+ "wants": 3107,
+ "wap": 27393,
+ "wap": 30368,
+ "waq": 47512,
+ "war": 984,
+ "war": 2238,
+ "wara": 21631,
+ "warbler": 33891,
+ "warcraft": 13660,
+ "ward": 7728,
+ "ward": 1460,
+ "warden": 27798,
+ "wardly": 30780,
+ "wardro": 14247,
+ "wardrobe": 15020,
+ "wards": 2593,
+ "ware": 7416,
+ "ware": 4476,
+ "wareagle": 35716,
+ "warehouse": 13054,
+ "wareness": 41601,
+ "wareness": 35870,
+ "wares": 30692,
+ "warfare": 15739,
+ "warhammer": 26832,
+ "warhol": 27554,
+ "wari": 20977,
+ "wark": 46346,
+ "wark": 15164,
+ "warlock": 42455,
+ "warm": 14725,
+ "warm": 3616,
+ "warmed": 36695,
+ "warmer": 14328,
+ "warmest": 30910,
+ "warming": 8606,
+ "warmly": 45322,
+ "warmongers": 33205,
+ "warms": 32917,
+ "warmth": 19636,
+ "warmup": 29904,
+ "warmups": 44094,
+ "warn": 19360,
+ "warned": 16409,
+ "warner": 28564,
+ "warner": 13402,
+ "warning": 4994,
+ "warnings": 18098,
+ "warns": 14086,
+ "waron": 38947,
+ "warp": 32411,
+ "warped": 32125,
+ "warran": 17392,
+ "warrant": 22554,
+ "warrants": 45677,
+ "warranty": 23999,
+ "warren": 23143,
+ "warren": 9234,
+ "warri": 4109,
+ "warrington": 31203,
+ "warrior": 18998,
+ "warrior": 8148,
+ "warriors": 6421,
+ "wars": 3931,
+ "warsaw": 21072,
+ "warship": 47846,
+ "wart": 43535,
+ "wart": 7346,
+ "wartime": 42998,
+ "warts": 21781,
+ "warwick": 23081,
+ "warwick": 22215,
+ "warwickshire": 36766,
+ "wary": 36213,
+ "was": 3398,
+ "was": 739,
+ "wasabi": 47334,
+ "wash": 3363,
+ "wash": 7810,
+ "washed": 14092,
+ "washer": 24085,
+ "washes": 38950,
+ "washing": 13029,
+ "washington": 16774,
+ "washington": 4365,
+ "washingtondc": 40225,
+ "washingtonpost": 28426,
+ "wasn": 5044,
+ "wasnt": 29607,
+ "wasp": 24889,
+ "wasps": 35300,
+ "wassup": 45708,
+ "wast": 28886,
+ "waste": 18157,
+ "waste": 6065,
+ "wasted": 18278,
+ "wasteland": 44035,
+ "wastewater": 34463,
+ "wasting": 25577,
+ "wat": 800,
+ "wat": 10621,
+ "wata": 42509,
+ "watch": 7046,
+ "watch": 1239,
+ "watchdog": 35303,
+ "watched": 5775,
+ "watcher": 35971,
+ "watchers": 28443,
+ "watches": 9521,
+ "watchin": 32432,
+ "watching": 2113,
+ "water": 2505,
+ "water": 1573,
+ "watercolor": 14211,
+ "watercolour": 18377,
+ "waterfall": 16403,
+ "waterfalls": 26692,
+ "waterford": 24448,
+ "waterfront": 16605,
+ "waterhouse": 45072,
+ "watering": 19871,
+ "waterloo": 17465,
+ "watermelon": 19889,
+ "waterproof": 17613,
+ "waters": 7753,
+ "watershed": 33204,
+ "waterstones": 45014,
+ "waterways": 37395,
+ "watford": 23162,
+ "watfordfc": 37328,
+ "wati": 27966,
+ "watkins": 22539,
+ "watson": 35490,
+ "watson": 9294,
+ "watt": 22899,
+ "watt": 15805,
+ "wattpad": 32351,
+ "watts": 14750,
+ "wau": 9479,
+ "wav": 6054,
+ "wave": 17530,
+ "wave": 4535,
+ "waved": 44657,
+ "waver": 25997,
+ "waves": 7882,
+ "waving": 26545,
+ "wavy": 31941,
+ "waw": 22039,
+ "wawrinka": 48414,
+ "wawx": 47387,
+ "wax": 18789,
+ "wax": 11910,
+ "waxing": 38781,
+ "way": 3079,
+ "way": 923,
+ "wayback": 47822,
+ "wayne": 23632,
+ "wayne": 7003,
+ "ways": 1248,
+ "waz": 20889,
+ "waz": 48835,
+ "wb": 10726,
+ "wb": 12377,
+ "wba": 22675,
+ "wbb": 14482,
+ "wbc": 26745,
+ "wbo": 49053,
+ "wbz": 35471,
+ "wc": 4842,
+ "wc": 5755,
+ "wcc": 47166,
+ "wcc": 34926,
+ "wcpo": 46624,
+ "wcs": 39916,
+ "wcvb": 32709,
+ "wcw": 9041,
+ "wd": 15998,
+ "wd": 7494,
+ "wdw": 40334,
+ "we": 598,
+ "we": 649,
+ "wea": 37146,
+ "wea": 47301,
+ "weak": 12128,
+ "weak": 10128,
+ "weaker": 39735,
+ "weakness": 21448,
+ "weaknesses": 43487,
+ "weal": 14759,
+ "wealth": 33150,
+ "wealth": 7904,
+ "wealthy": 22617,
+ "weap": 6156,
+ "weapon": 42612,
+ "weapon": 10537,
+ "weapons": 10007,
+ "wear": 12206,
+ "wear": 2839,
+ "wearab": 22983,
+ "wearable": 44943,
+ "wearable": 24973,
+ "wearables": 30319,
+ "weare": 4264,
+ "weare": 27867,
+ "weareall": 45980,
+ "wearec": 43620,
+ "wearen": 45635,
+ "weareone": 16149,
+ "weareoneexo": 16448,
+ "wearethe": 40242,
+ "wearing": 3309,
+ "wears": 11869,
+ "weary": 38766,
+ "weasel": 44308,
+ "weather": 8808,
+ "weather": 2237,
+ "weathercee": 44980,
+ "weatherchannel": 42138,
+ "weav": 22260,
+ "weave": 22450,
+ "weaver": 20297,
+ "weaving": 27131,
+ "web": 2055,
+ "web": 4601,
+ "webb": 15708,
+ "webber": 34248,
+ "webcam": 24211,
+ "webcam": 22589,
+ "webcamtoy": 27719,
+ "webcast": 28256,
+ "webcomic": 34286,
+ "webcomics": 39811,
+ "webdesign": 20470,
+ "webdev": 37000,
+ "webdevelopment": 47553,
+ "weber": 20179,
+ "webin": 8460,
+ "webinar": 8921,
+ "webinars": 47755,
+ "webpage": 46964,
+ "webs": 32829,
+ "webseries": 44819,
+ "website": 3364,
+ "websites": 19278,
+ "webster": 19471,
+ "websummit": 48069,
+ "wec": 33152,
+ "wechat": 46124,
+ "wed": 1687,
+ "wed": 3478,
+ "wedd": 7576,
+ "wedding": 11204,
+ "wedding": 3101,
+ "weddings": 15964,
+ "wedge": 21446,
+ "wedges": 33179,
+ "wedne": 2380,
+ "wednesday": 9311,
+ "wednesday": 2689,
+ "wednesdaymotivation": 37860,
+ "wednesdays": 24943,
+ "wednesdaywisdom": 11445,
+ "wedo": 43432,
+ "weds": 19107,
+ "wee": 716,
+ "wee": 8288,
+ "weed": 36935,
+ "weed": 8015,
+ "weeds": 26326,
+ "week": 1286,
+ "week": 994,
+ "weekday": 29244,
+ "weekdays": 44330,
+ "weekend": 17205,
+ "weekend": 1456,
+ "weekender": 36547,
+ "weekends": 14564,
+ "weekly": 34652,
+ "weekly": 5885,
+ "weeknd": 29925,
+ "weeks": 2898,
+ "weeksary": 24628,
+ "ween": 17517,
+ "ween": 1599,
+ "weep": 39270,
+ "weeping": 36629,
+ "weer": 32491,
+ "weet": 17742,
+ "weets": 13454,
+ "wef": 23313,
+ "weg": 47867,
+ "weg": 47561,
+ "wego": 44784,
+ "wego": 28220,
+ "weh": 48458,
+ "weh": 40313,
+ "weho": 47798,
+ "wei": 6958,
+ "wei": 20952,
+ "weibo": 20613,
+ "weigh": 10565,
+ "weigh": 17346,
+ "weighed": 33210,
+ "weighing": 24455,
+ "weighs": 20481,
+ "weight": 12723,
+ "weight": 3868,
+ "weighted": 43179,
+ "weightlifting": 36164,
+ "weightloss": 20359,
+ "weights": 21374,
+ "weil": 43720,
+ "weiler": 42203,
+ "wein": 29134,
+ "wein": 37684,
+ "weiner": 38822,
+ "weinstein": 34367,
+ "weir": 11299,
+ "weir": 25517,
+ "weird": 27981,
+ "weird": 5613,
+ "weirdest": 29482,
+ "weirdo": 32476,
+ "weis": 26251,
+ "weiser": 34833,
+ "weiss": 24794,
+ "wel": 1267,
+ "wel": 8042,
+ "welch": 25820,
+ "welcom": 11578,
+ "welcome": 18318,
+ "welcome": 1881,
+ "welcomed": 12590,
+ "welcomes": 9304,
+ "welcometo": 47511,
+ "welcoming": 8775,
+ "weld": 39776,
+ "welding": 24956,
+ "welfare": 12129,
+ "well": 3277,
+ "well": 1123,
+ "wellbeing": 14273,
+ "weller": 40921,
+ "welling": 49165,
+ "wellington": 15389,
+ "wellness": 40574,
+ "wellness": 9904,
+ "wells": 42705,
+ "wells": 9804,
+ "welove": 13573,
+ "welp": 28391,
+ "wels": 20852,
+ "welsh": 19173,
+ "welsh": 10977,
+ "welt": 38595,
+ "welter": 37115,
+ "welterweight": 39617,
+ "wemb": 15213,
+ "wembley": 16579,
+ "wen": 6590,
+ "wen": 11278,
+ "wend": 15166,
+ "wendell": 42091,
+ "wendy": 31616,
+ "wendy": 14074,
+ "wenger": 21105,
+ "went": 18633,
+ "went": 2437,
+ "wentworth": 36423,
+ "wentz": 39179,
+ "wer": 6316,
+ "wer": 2980,
+ "were": 15461,
+ "were": 1365,
+ "wered": 6605,
+ "weren": 13611,
+ "werewolf": 32001,
+ "werk": 30176,
+ "werner": 29917,
+ "wers": 7110,
+ "wes": 18620,
+ "wes": 14738,
+ "wesle": 29606,
+ "wesley": 17332,
+ "wesleyan": 32509,
+ "wesome": 33292,
+ "wess": 44431,
+ "west": 2973,
+ "west": 1593,
+ "westbound": 29208,
+ "westbrook": 26948,
+ "westchester": 36675,
+ "westcoast": 44610,
+ "westend": 44815,
+ "wester": 9846,
+ "western": 17079,
+ "western": 4463,
+ "westfield": 32309,
+ "westh": 36798,
+ "westin": 43232,
+ "westlake": 41535,
+ "westminster": 15158,
+ "weston": 22771,
+ "westside": 33762,
+ "westwood": 26371,
+ "westworld": 42287,
+ "wet": 12406,
+ "wet": 6682,
+ "weta": 40946,
+ "wethenorth": 45281,
+ "wethepeople": 48030,
+ "wether": 33794,
+ "wether": 48405,
+ "wetland": 37357,
+ "wetlands": 26547,
+ "wett": 41971,
+ "wetter": 43957,
+ "wewant": 39280,
+ "wewill": 37241,
+ "wex": 17234,
+ "wexford": 29876,
+ "wexmondays": 49042,
+ "wey": 30376,
+ "wey": 19781,
+ "weymouth": 41433,
+ "wf": 14576,
+ "wf": 22313,
+ "wfa": 44606,
+ "wfc": 36431,
+ "wfp": 35193,
+ "wftv": 47075,
+ "wg": 21091,
+ "wg": 25857,
+ "wga": 32354,
+ "wgn": 48828,
+ "wh": 573,
+ "wh": 13844,
+ "wha": 18994,
+ "wha": 25884,
+ "whal": 38967,
+ "whale": 37083,
+ "whale": 11650,
+ "whales": 17722,
+ "wham": 42506,
+ "whar": 15517,
+ "wharf": 22452,
+ "wharton": 43320,
+ "what": 4268,
+ "what": 768,
+ "whatcha": 37160,
+ "whate": 6695,
+ "whatever": 6743,
+ "whati": 23500,
+ "whats": 9263,
+ "whats": 13084,
+ "whatsapp": 10119,
+ "whatsoever": 39928,
+ "whatson": 35632,
+ "whatyou": 30508,
+ "whe": 2009,
+ "whead": 34583,
+ "wheat": 20505,
+ "wheat": 10303,
+ "wheaton": 46933,
+ "wheel": 7360,
+ "wheel": 6744,
+ "wheelchair": 17713,
+ "wheeler": 18405,
+ "wheeling": 34839,
+ "wheels": 8025,
+ "whel": 9792,
+ "whelan": 40715,
+ "when": 8753,
+ "when": 827,
+ "whenever": 10500,
+ "where": 7052,
+ "where": 1234,
+ "whereabouts": 47808,
+ "whereas": 42234,
+ "wheres": 46345,
+ "wherever": 14103,
+ "whereyou": 46837,
+ "whether": 5903,
+ "whew": 39016,
+ "whey": 34556,
+ "whi": 4295,
+ "whi": 33129,
+ "which": 1448,
+ "whiche": 48719,
+ "whichever": 49138,
+ "whil": 8499,
+ "while": 1519,
+ "whilst": 8596,
+ "whim": 27766,
+ "whimsical": 42282,
+ "whip": 14412,
+ "whipped": 22323,
+ "whipping": 41567,
+ "whir": 20873,
+ "whirl": 30962,
+ "whirlwind": 47771,
+ "whis": 6024,
+ "whiskey": 41381,
+ "whiskey": 11610,
+ "whisky": 37567,
+ "whisky": 12599,
+ "whisp": 21986,
+ "whispe": 30356,
+ "whisper": 27616,
+ "whisperer": 41368,
+ "whispering": 42599,
+ "whispers": 29133,
+ "whist": 13640,
+ "whistle": 23972,
+ "whistle": 19746,
+ "whistleblower": 40410,
+ "whistler": 29633,
+ "whit": 4398,
+ "whit": 31498,
+ "whitaker": 35851,
+ "whitby": 30858,
+ "white": 4699,
+ "white": 1579,
+ "whiteboard": 40839,
+ "whitec": 24575,
+ "whitehall": 42827,
+ "whitehead": 43560,
+ "whitehouse": 20776,
+ "whitening": 35540,
+ "whitepaper": 42713,
+ "whites": 35886,
+ "whites": 18835,
+ "whitesox": 28816,
+ "whitewater": 49350,
+ "whitfield": 48404,
+ "whitley": 40564,
+ "whitman": 32394,
+ "whitney": 43021,
+ "whitney": 18048,
+ "whitt": 33784,
+ "whittaker": 47595,
+ "whl": 25801,
+ "who": 2969,
+ "who": 822,
+ "whoa": 16943,
+ "whoever": 11137,
+ "whois": 41884,
+ "whole": 10360,
+ "whole": 2954,
+ "wholefoods": 42840,
+ "wholesale": 18306,
+ "wholesome": 35959,
+ "whom": 38158,
+ "whom": 12873,
+ "whoo": 20003,
+ "whoo": 49290,
+ "whoop": 22060,
+ "whoops": 28433,
+ "whopping": 34384,
+ "whore": 31690,
+ "whos": 41460,
+ "whos": 27130,
+ "whose": 6933,
+ "whouse": 45927,
+ "whs": 26292,
+ "wht": 32470,
+ "whufc": 31695,
+ "whun": 18272,
+ "why": 11040,
+ "why": 1182,
+ "whyte": 42386,
+ "wi": 820,
+ "wi": 5585,
+ "wib": 45303,
+ "wic": 7834,
+ "wich": 9759,
+ "wich": 5238,
+ "wichita": 22566,
+ "wick": 6798,
+ "wick": 6479,
+ "wicked": 32579,
+ "wicked": 12825,
+ "wicker": 38096,
+ "wicket": 19180,
+ "wickets": 22110,
+ "wicklow": 39039,
+ "wicz": 30121,
+ "wid": 11886,
+ "wid": 20886,
+ "wide": 19341,
+ "wide": 3184,
+ "widely": 16195,
+ "widening": 46598,
+ "wider": 21263,
+ "widesp": 20598,
+ "widespread": 21258,
+ "widget": 43906,
+ "wido": 28068,
+ "widow": 19949,
+ "widows": 42129,
+ "width": 23571,
+ "wie": 21378,
+ "wie": 9131,
+ "wielding": 47272,
+ "wien": 38131,
+ "wiener": 40567,
+ "wies": 42788,
+ "wif": 37572,
+ "wife": 3607,
+ "wifey": 35282,
+ "wifi": 11026,
+ "wig": 23690,
+ "wig": 12216,
+ "wigan": 23130,
+ "wiggins": 32329,
+ "wiggle": 47812,
+ "wight": 41278,
+ "wight": 15545,
+ "wigs": 31207,
+ "wii": 8005,
+ "wiiu": 40980,
+ "wiki": 10373,
+ "wiki": 24265,
+ "wikileaks": 28731,
+ "wikipedia": 15176,
+ "wil": 1352,
+ "wil": 20581,
+ "wilbur": 43069,
+ "wilcox": 43231,
+ "wild": 2780,
+ "wild": 3220,
+ "wildatlantic": 35500,
+ "wildatlanticway": 35776,
+ "wildcard": 37360,
+ "wildcat": 49077,
+ "wildcat": 25870,
+ "wildcats": 15909,
+ "wilde": 23498,
+ "wilder": 14343,
+ "wilder": 23499,
+ "wilderness": 16506,
+ "wildest": 43028,
+ "wildfire": 22788,
+ "wildfires": 29184,
+ "wildflower": 27628,
+ "wildflower": 33181,
+ "wildflowerhour": 31302,
+ "wildflowers": 29136,
+ "wildlife": 13298,
+ "wildlife": 5250,
+ "wildlifephotography": 32307,
+ "wildlifewednesday": 48537,
+ "wildly": 35981,
+ "wildoz": 40113,
+ "wiley": 32747,
+ "wilhelm": 39696,
+ "wilkes": 39548,
+ "wilkins": 36986,
+ "wilkinson": 26797,
+ "will": 5062,
+ "will": 751,
+ "willam": 43276,
+ "willard": 44920,
+ "wille": 48739,
+ "willem": 38044,
+ "willi": 2256,
+ "william": 8420,
+ "william": 4705,
+ "williams": 38452,
+ "williams": 4075,
+ "williamsburg": 30683,
+ "williamson": 20793,
+ "willie": 13907,
+ "willing": 34160,
+ "willing": 11718,
+ "willingness": 40573,
+ "willis": 18491,
+ "willow": 33887,
+ "willow": 15665,
+ "wills": 26913,
+ "willy": 34502,
+ "willy": 19599,
+ "wilmington": 28052,
+ "wilms": 47879,
+ "wilshere": 48359,
+ "wilson": 23629,
+ "wilson": 5622,
+ "wilt": 23394,
+ "wilt": 47357,
+ "wilton": 46638,
+ "wiltshire": 28025,
+ "wim": 8662,
+ "wim": 27580,
+ "wimble": 11752,
+ "wimbledon": 12229,
+ "win": 831,
+ "win": 1225,
+ "winchester": 20647,
+ "wind": 6812,
+ "wind": 3630,
+ "winder": 44454,
+ "winder": 46245,
+ "winding": 22390,
+ "windmill": 34084,
+ "windo": 3110,
+ "window": 26675,
+ "window": 4879,
+ "windows": 5437,
+ "winds": 12668,
+ "winds": 7012,
+ "windshield": 33002,
+ "windsor": 44322,
+ "windsor": 12884,
+ "windy": 13446,
+ "wine": 7375,
+ "wine": 2604,
+ "winelover": 26357,
+ "winemaker": 41588,
+ "wineoclock": 43846,
+ "wineries": 49349,
+ "winery": 15500,
+ "wines": 8263,
+ "winetasting": 41288,
+ "winewednesday": 35447,
+ "wing": 8141,
+ "wing": 1340,
+ "winged": 24993,
+ "winger": 22727,
+ "winget": 44578,
+ "wings": 5178,
+ "wink": 34455,
+ "wink": 25859,
+ "winkle": 36430,
+ "winn": 38104,
+ "winne": 46273,
+ "winner": 32961,
+ "winner": 2520,
+ "winners": 4320,
+ "winni": 13018,
+ "winnie": 29022,
+ "winning": 42099,
+ "winning": 2577,
+ "winnings": 46490,
+ "winnipeg": 14369,
+ "winona": 49202,
+ "wins": 46839,
+ "wins": 2718,
+ "winslow": 39658,
+ "winston": 14848,
+ "winter": 7340,
+ "winter": 2541,
+ "winters": 21587,
+ "wintry": 39504,
+ "wip": 10447,
+ "wipe": 26761,
+ "wiped": 31822,
+ "wipes": 33463,
+ "wir": 16849,
+ "wir": 44838,
+ "wire": 7558,
+ "wire": 7794,
+ "wired": 18935,
+ "wireless": 9103,
+ "wires": 24311,
+ "wiring": 36434,
+ "wirral": 34675,
+ "wis": 3392,
+ "wis": 20405,
+ "wiscon": 9857,
+ "wisconsin": 10265,
+ "wisdom": 42474,
+ "wisdom": 5425,
+ "wise": 19116,
+ "wise": 5558,
+ "wisely": 26173,
+ "wiser": 44859,
+ "wish": 11328,
+ "wish": 2412,
+ "wished": 25883,
+ "wishes": 6045,
+ "wishing": 5307,
+ "wishlist": 31969,
+ "wit": 584,
+ "wit": 8531,
+ "witch": 20139,
+ "witch": 10083,
+ "witchcraft": 35065,
+ "witcher": 33684,
+ "witches": 21673,
+ "with": 1435,
+ "with": 593,
+ "withdra": 24696,
+ "withdraw": 31670,
+ "withdrawal": 25765,
+ "withdrawn": 46687,
+ "withdraws": 48637,
+ "wither": 39655,
+ "witherspoon": 45409,
+ "within": 4154,
+ "withme": 44670,
+ "without": 32836,
+ "without": 2193,
+ "withstand": 42236,
+ "withthe": 36872,
+ "withus": 30572,
+ "withyou": 30351,
+ "witne": 12096,
+ "witness": 8793,
+ "witnessed": 20187,
+ "witnesses": 22778,
+ "witnessing": 33618,
+ "wits": 30938,
+ "witt": 38194,
+ "witt": 17168,
+ "witter": 31597,
+ "witty": 29970,
+ "witz": 44186,
+ "witz": 13265,
+ "wiv": 48925,
+ "wives": 14378,
+ "wiwx": 44461,
+ "wiz": 7730,
+ "wiz": 23178,
+ "wizar": 49121,
+ "wizard": 30490,
+ "wizard": 14295,
+ "wizards": 19140,
+ "wizkid": 40146,
+ "wj": 19739,
+ "wj": 35453,
+ "wk": 11512,
+ "wk": 11528,
+ "wkend": 42336,
+ "wknd": 20851,
+ "wks": 25508,
+ "wku": 43377,
+ "wl": 13299,
+ "wl": 9613,
+ "wm": 20268,
+ "wm": 15790,
+ "wn": 1186,
+ "wn": 757,
+ "wnba": 32358,
+ "wned": 8628,
+ "wns": 12950,
+ "wnt": 22484,
+ "wny": 24833,
+ "wo": 1613,
+ "wo": 11132,
+ "woah": 17751,
+ "wob": 35984,
+ "woc": 39011,
+ "wod": 41522,
+ "woes": 27860,
+ "wof": 45671,
+ "woj": 48931,
+ "wok": 28912,
+ "woke": 9331,
+ "woken": 43697,
+ "woking": 43931,
+ "wol": 2798,
+ "wol": 48622,
+ "wold": 42399,
+ "wolf": 9453,
+ "wolf": 5916,
+ "wolfe": 24989,
+ "wolff": 34369,
+ "wolfgang": 34061,
+ "wolfpack": 30887,
+ "wolve": 45101,
+ "wolver": 14334,
+ "wolverhampton": 34518,
+ "wolverine": 23353,
+ "wolverines": 42003,
+ "wolves": 9372,
+ "wom": 1087,
+ "womack": 48980,
+ "woman": 15716,
+ "woman": 2308,
+ "womanc": 35630,
+ "womancrush": 37721,
+ "womancrushwednesday": 39714,
+ "womanin": 30562,
+ "womaninbiz": 36482,
+ "womb": 37023,
+ "women": 3648,
+ "women": 1507,
+ "womenin": 13062,
+ "womeninscience": 41343,
+ "womeninstem": 29380,
+ "womenintech": 31470,
+ "womenof": 48421,
+ "womens": 12822,
+ "womens": 14408,
+ "womensart": 38548,
+ "womensday": 13956,
+ "womenshi": 22887,
+ "womenshistorymonth": 24982,
+ "womensmarch": 30102,
+ "won": 1528,
+ "won": 1749,
+ "wonder": 2070,
+ "wonder": 3936,
+ "wondercon": 46944,
+ "wondered": 15550,
+ "wonderful": 2582,
+ "wonderfully": 23245,
+ "wondering": 8360,
+ "wonderland": 13874,
+ "wonders": 14048,
+ "wonderwoman": 31000,
+ "wondo": 38402,
+ "wondr": 46771,
+ "wong": 17876,
+ "wonka": 43463,
+ "wont": 43174,
+ "wont": 15952,
+ "woo": 1867,
+ "woo": 9322,
+ "wood": 3269,
+ "wood": 1704,
+ "woodbridge": 49074,
+ "wooden": 48226,
+ "wooden": 9057,
+ "woodland": 44314,
+ "woodland": 17447,
+ "woodlands": 32430,
+ "woodley": 40566,
+ "woodpecker": 32684,
+ "woods": 6267,
+ "woodson": 48967,
+ "woodstock": 29486,
+ "woodward": 27419,
+ "woodwork": 47386,
+ "woodworking": 29267,
+ "woody": 38627,
+ "woody": 17144,
+ "woof": 34234,
+ "woof": 24028,
+ "woohoo": 20172,
+ "wook": 29192,
+ "wool": 9967,
+ "wool": 13283,
+ "woolf": 43728,
+ "woolly": 47722,
+ "woon": 33126,
+ "wooo": 43217,
+ "woop": 31884,
+ "woot": 22466,
+ "wor": 641,
+ "worcester": 22172,
+ "worcester": 19580,
+ "worcestershire": 38440,
+ "worcestershirehour": 43644,
+ "word": 8272,
+ "word": 2653,
+ "wordof": 33500,
+ "wordoftheday": 43594,
+ "wordpress": 15193,
+ "words": 31007,
+ "words": 2709,
+ "wore": 8953,
+ "work": 1636,
+ "work": 951,
+ "workday": 29735,
+ "worked": 5410,
+ "worker": 8098,
+ "workers": 4795,
+ "workflow": 28502,
+ "workforce": 14672,
+ "workin": 31825,
+ "workin": 26323,
+ "working": 20806,
+ "working": 1699,
+ "workinprogress": 46086,
+ "workout": 6773,
+ "workouts": 22779,
+ "workplace": 11959,
+ "workplaces": 47383,
+ "works": 2322,
+ "workshop": 3832,
+ "workshops": 12262,
+ "workspace": 34470,
+ "worl": 5221,
+ "world": 2334,
+ "world": 1002,
+ "worlda": 46627,
+ "worldbank": 36759,
+ "worldbookday": 31191,
+ "worldcup": 42525,
+ "worldcup": 8650,
+ "worlden": 44668,
+ "worldenviron": 47115,
+ "worldenvironmentday": 47522,
+ "worldly": 36268,
+ "worldo": 41698,
+ "worldof": 22636,
+ "worldre": 33951,
+ "worlds": 7691,
+ "worldseries": 26695,
+ "worldtour": 23202,
+ "worldwater": 41176,
+ "worldwaterday": 44520,
+ "worldwide": 6214,
+ "worm": 33709,
+ "worm": 10945,
+ "worms": 20231,
+ "worn": 9037,
+ "worried": 11911,
+ "worries": 17684,
+ "worry": 7534,
+ "worrying": 24058,
+ "worse": 8236,
+ "worsen": 46344,
+ "worshi": 31840,
+ "worship": 46399,
+ "worship": 9023,
+ "worst": 5719,
+ "wort": 30209,
+ "worth": 10671,
+ "worth": 2450,
+ "worthing": 39929,
+ "worthit": 40830,
+ "worthless": 44736,
+ "worths": 44633,
+ "worthwhile": 36295,
+ "worthy": 8881,
+ "worx": 44973,
+ "wot": 24863,
+ "wou": 5279,
+ "would": 39873,
+ "would": 1311,
+ "wouldn": 5878,
+ "wouldnt": 41595,
+ "wound": 19231,
+ "wounded": 14859,
+ "wounds": 21290,
+ "woven": 19830,
+ "wow": 22191,
+ "wow": 2781,
+ "woz": 44558,
+ "wozni": 47782,
+ "wp": 15378,
+ "wp": 13302,
+ "wpg": 35048,
+ "wps": 33386,
+ "wq": 45195,
+ "wr": 1189,
+ "wr": 8028,
+ "wra": 3852,
+ "wra": 46004,
+ "wral": 49050,
+ "wrangler": 30923,
+ "wrap": 7094,
+ "wrapped": 9875,
+ "wrapping": 15223,
+ "wraps": 18236,
+ "wrath": 29783,
+ "wray": 48943,
+ "wrc": 16004,
+ "wre": 3168,
+ "wreath": 23091,
+ "wrec": 20879,
+ "wreck": 28775,
+ "wreck": 15017,
+ "wrecked": 32695,
+ "wreckem": 45676,
+ "wrecking": 36956,
+ "wrecks": 45545,
+ "wren": 20191,
+ "wren": 31970,
+ "wrench": 30980,
+ "wrest": 4177,
+ "wrestle": 17097,
+ "wrestle": 28086,
+ "wrestlemania": 18849,
+ "wrestler": 19790,
+ "wrestlers": 25902,
+ "wrestling": 31292,
+ "wrestling": 5904,
+ "wrexham": 34479,
+ "wri": 7667,
+ "wri": 42007,
+ "wright": 28616,
+ "wright": 6991,
+ "wrights": 43711,
+ "wrigley": 33538,
+ "wrink": 22201,
+ "wrinkle": 46642,
+ "wrinkles": 35525,
+ "wrist": 19243,
+ "wrist": 16139,
+ "wristband": 36890,
+ "wristbands": 44864,
+ "writ": 2902,
+ "write": 28874,
+ "write": 4946,
+ "writer": 27886,
+ "writer": 4422,
+ "writers": 18742,
+ "writers": 7307,
+ "writerslife": 25007,
+ "writes": 8023,
+ "writing": 16053,
+ "writing": 2979,
+ "writingcommunity": 39178,
+ "writings": 36259,
+ "written": 5231,
+ "wro": 5447,
+ "wrong": 18381,
+ "wrong": 3669,
+ "wrongly": 45642,
+ "wrote": 5796,
+ "wrought": 48125,
+ "wrs": 45280,
+ "ws": 6300,
+ "ws": 799,
+ "wsb": 30681,
+ "wsbtv": 38394,
+ "wsj": 19764,
+ "wski": 12548,
+ "wsl": 43706,
+ "wsoc": 40253,
+ "wson": 33954,
+ "wsop": 41231,
+ "wsu": 44674,
+ "wsu": 32913,
+ "wsw": 43285,
+ "wt": 15873,
+ "wt": 12255,
+ "wta": 25984,
+ "wtc": 39718,
+ "wtf": 6891,
+ "wth": 23021,
+ "wthr": 45269,
+ "wti": 47345,
+ "wto": 36406,
+ "wts": 32159,
+ "wu": 9710,
+ "wu": 9837,
+ "wud": 43870,
+ "wul": 35154,
+ "wunder": 36661,
+ "wur": 24040,
+ "wurst": 44409,
+ "wusa": 40021,
+ "wut": 28590,
+ "wv": 18920,
+ "wv": 14743,
+ "wvu": 44878,
+ "wvu": 25879,
+ "ww": 3181,
+ "ww": 4491,
+ "wwc": 26505,
+ "wwdc": 47441,
+ "wwe": 12112,
+ "wwe": 5290,
+ "wwen": 23308,
+ "wwenetwork": 37228,
+ "wwenxt": 39898,
+ "wwer": 32038,
+ "wwf": 23332,
+ "wwfc": 42681,
+ "wwg": 35322,
+ "wwi": 20194,
+ "wwii": 10261,
+ "www": 26074,
+ "www": 9667,
+ "wwwbigbaldhead": 30761,
+ "wwww": 34224,
+ "wwww": 25200,
+ "wwwww": 48268,
+ "wwx": 47431,
+ "wx": 18192,
+ "wx": 3561,
+ "wy": 4665,
+ "wy": 7625,
+ "wyatt": 21660,
+ "wyd": 33113,
+ "wye": 48436,
+ "wye": 43751,
+ "wylie": 49330,
+ "wyn": 11802,
+ "wyn": 17504,
+ "wynn": 36117,
+ "wynne": 35951,
+ "wynonna": 41456,
+ "wynonnaearp": 43755,
+ "wyoming": 18693,
+ "x": 87,
+ "x": 343,
+ "xa": 24831,
+ "xan": 45530,
+ "xander": 45601,
+ "xavi": 36342,
+ "xavier": 41044,
+ "xavier": 18567,
+ "xb": 33678,
+ "xbox": 18063,
+ "xbox": 7748,
+ "xboxone": 27410,
+ "xc": 12515,
+ "xchange": 49132,
+ "xd": 6380,
+ "xe": 42886,
+ "xe": 19183,
+ "xen": 15568,
+ "xer": 49005,
+ "xf": 35274,
+ "xfactor": 25211,
+ "xfinity": 35107,
+ "xford": 34732,
+ "xh": 45771,
+ "xham": 25284,
+ "xi": 2467,
+ "xi": 7376,
+ "xia": 19854,
+ "xia": 20724,
+ "xian": 42570,
+ "xiao": 49318,
+ "xiaomi": 27477,
+ "xico": 38469,
+ "xide": 17398,
+ "xie": 40122,
+ "xie": 15976,
+ "xii": 36525,
+ "xiii": 28199,
+ "xim": 11217,
+ "xin": 27053,
+ "xin": 41517,
+ "xing": 14383,
+ "xion": 24164,
+ "xis": 35793,
+ "xit": 5316,
+ "xiumin": 36563,
+ "xiv": 16125,
+ "xj": 42453,
+ "xl": 36529,
+ "xl": 8833,
+ "xley": 38223,
+ "xm": 18626,
+ "xma": 48805,
+ "xmas": 48848,
+ "xmas": 6425,
+ "xmen": 28708,
+ "xn": 25388,
+ "xo": 26936,
+ "xo": 9000,
+ "xon": 29186,
+ "xon": 8482,
+ "xox": 11531,
+ "xox": 34050,
+ "xoxo": 13313,
+ "xp": 15651,
+ "xper": 32200,
+ "xperia": 37615,
+ "xpo": 44377,
+ "xpress": 31809,
+ "xq": 40606,
+ "xr": 26276,
+ "xrp": 26965,
+ "xs": 16397,
+ "xt": 1052,
+ "xtina": 45520,
+ "xton": 32666,
+ "xton": 10597,
+ "xtra": 26969,
+ "xtre": 27025,
+ "xtreme": 33483,
+ "xu": 42063,
+ "xu": 37198,
+ "xv": 17768,
+ "xvi": 44031,
+ "xx": 5675,
+ "xx": 3553,
+ "xxl": 29777,
+ "xxx": 33923,
+ "xxx": 8352,
+ "xxxx": 32035,
+ "xxxx": 22819,
+ "xxxxx": 44195,
+ "xy": 20023,
+ "xy": 11443,
+ "y": 88,
+ "y": 344,
+ "ya": 5018,
+ "ya": 1430,
+ "yaa": 48847,
+ "yaa": 34498,
+ "yaan": 34680,
+ "yab": 27737,
+ "yach": 9039,
+ "yacht": 43806,
+ "yacht": 12859,
+ "yachts": 29260,
+ "yad": 13276,
+ "yad": 40047,
+ "yadav": 26650,
+ "yaf": 38019,
+ "yag": 35081,
+ "yah": 16170,
+ "yah": 12381,
+ "yaho": 37929,
+ "yahoo": 38152,
+ "yahoo": 16846,
+ "yak": 11014,
+ "yak": 29074,
+ "yaki": 44677,
+ "yaku": 29572,
+ "yakuza": 42628,
+ "yal": 16198,
+ "yal": 13418,
+ "yale": 39926,
+ "yale": 17157,
+ "yall": 9210,
+ "yam": 6666,
+ "yam": 19318,
+ "yama": 23512,
+ "yamaha": 18854,
+ "yan": 3949,
+ "yan": 4788,
+ "yana": 18698,
+ "yand": 38609,
+ "yang": 23818,
+ "yang": 12605,
+ "yani": 26439,
+ "yankee": 21554,
+ "yankees": 11889,
+ "yann": 40246,
+ "yann": 38657,
+ "yao": 45231,
+ "yap": 48700,
+ "yap": 34468,
+ "yar": 6786,
+ "yar": 23071,
+ "yard": 20234,
+ "yard": 4313,
+ "yards": 7550,
+ "yarmouth": 45941,
+ "yarn": 19702,
+ "yarra": 46824,
+ "yas": 8168,
+ "yas": 20570,
+ "yash": 30216,
+ "yash": 37836,
+ "yasi": 37700,
+ "yasss": 23873,
+ "yat": 29443,
+ "yat": 34965,
+ "yates": 27677,
+ "yatra": 38932,
+ "yav": 41275,
+ "yaw": 31989,
+ "yawn": 48643,
+ "yay": 20614,
+ "yay": 6712,
+ "yaya": 37608,
+ "yaz": 19348,
+ "yaz": 42252,
+ "yb": 41785,
+ "yb": 27615,
+ "yc": 11931,
+ "ycle": 38089,
+ "yd": 29896,
+ "yd": 9534,
+ "yday": 15899,
+ "yds": 24819,
+ "ye": 693,
+ "ye": 4582,
+ "yea": 13687,
+ "yeah": 29405,
+ "yeah": 3908,
+ "year": 5163,
+ "year": 935,
+ "yearbook": 21636,
+ "yearling": 48392,
+ "yearly": 24541,
+ "yearof": 31944,
+ "yearofthe": 47899,
+ "years": 30864,
+ "years": 1151,
+ "yearsof": 14932,
+ "yearswith": 45249,
+ "yeast": 25819,
+ "yeats": 44903,
+ "yed": 28137,
+ "yed": 3301,
+ "yee": 18114,
+ "yee": 23108,
+ "yeezy": 24901,
+ "yeg": 16854,
+ "yeg": 11976,
+ "yegfood": 48711,
+ "yeh": 21331,
+ "yel": 3323,
+ "yel": 48164,
+ "yell": 30824,
+ "yelled": 39199,
+ "yelling": 26581,
+ "yellow": 12059,
+ "yellow": 4481,
+ "yellowstone": 29241,
+ "yelp": 31674,
+ "yemen": 29276,
+ "yemen": 12513,
+ "yemeni": 44656,
+ "yemi": 42267,
+ "yen": 29602,
+ "yen": 17960,
+ "yeo": 32292,
+ "yeo": 43830,
+ "yeol": 15808,
+ "yeon": 16602,
+ "yep": 10964,
+ "yer": 15491,
+ "yer": 2371,
+ "yers": 3722,
+ "yes": 21620,
+ "yes": 1958,
+ "yess": 42778,
+ "yess": 40189,
+ "yesss": 36210,
+ "yessss": 45620,
+ "yester": 1905,
+ "yesterday": 1926,
+ "yesterdays": 36238,
+ "yesung": 38527,
+ "yet": 2296,
+ "yeti": 34228,
+ "yev": 39855,
+ "yew": 34660,
+ "yey": 45447,
+ "yg": 16396,
+ "ygk": 44758,
+ "ygo": 46166,
+ "yh": 41978,
+ "yi": 5826,
+ "yi": 14762,
+ "yield": 16825,
+ "yields": 24856,
+ "yikes": 25094,
+ "yin": 26476,
+ "yin": 23543,
+ "ying": 42933,
+ "ying": 910,
+ "yixing": 32120,
+ "yk": 30965,
+ "yl": 2656,
+ "yl": 4045,
+ "ylan": 41875,
+ "ylde": 42850,
+ "yle": 32305,
+ "yle": 10770,
+ "ylene": 34239,
+ "yler": 48081,
+ "yles": 42860,
+ "ylon": 22375,
+ "ylor": 48468,
+ "ym": 1786,
+ "ym": 19587,
+ "yman": 29077,
+ "ymc": 47101,
+ "ymca": 22369,
+ "yment": 8199,
+ "ymes": 39968,
+ "ymi": 5271,
+ "ymm": 37133,
+ "ymoun": 41426,
+ "ymouth": 36429,
+ "yn": 2823,
+ "yn": 4100,
+ "yne": 18238,
+ "ynes": 18020,
+ "ynn": 10499,
+ "ynna": 48292,
+ "ynwa": 27372,
+ "yo": 586,
+ "yo": 3497,
+ "yoda": 31922,
+ "yof": 5966,
+ "yofficial": 21818,
+ "yofthe": 43983,
+ "yog": 34985,
+ "yog": 36539,
+ "yoga": 25872,
+ "yoga": 5523,
+ "yogh": 32626,
+ "yoghurt": 33491,
+ "yogi": 22766,
+ "yogur": 16137,
+ "yogurt": 16819,
+ "yoh": 48880,
+ "yoke": 41969,
+ "yoko": 25929,
+ "yoko": 32256,
+ "yokohama": 42409,
+ "yol": 19387,
+ "yol": 35218,
+ "yolanda": 43845,
+ "yolo": 20905,
+ "yom": 34718,
+ "yom": 44527,
+ "yon": 10147,
+ "yon": 7604,
+ "yong": 27960,
+ "yong": 20887,
+ "yonge": 48592,
+ "yoo": 25842,
+ "yoo": 20775,
+ "yoon": 30863,
+ "yoon": 22113,
+ "yoona": 32736,
+ "yoongi": 24037,
+ "yor": 2028,
+ "yor": 21132,
+ "york": 5318,
+ "york": 2705,
+ "yorker": 23865,
+ "yorkers": 41041,
+ "yorks": 39093,
+ "yorkshi": 43367,
+ "yorkshire": 27007,
+ "yorkshire": 8633,
+ "yoruba": 46083,
+ "yos": 35607,
+ "yosemite": 25893,
+ "yoshi": 22920,
+ "yoshi": 25354,
+ "yot": 22875,
+ "yotes": 46157,
+ "yotpo": 26113,
+ "you": 1562,
+ "you": 592,
+ "youare": 33879,
+ "youcan": 32498,
+ "youknow": 47919,
+ "youknow": 41088,
+ "youn": 1596,
+ "young": 6939,
+ "young": 1888,
+ "younger": 10414,
+ "youngest": 12316,
+ "youngjae": 46426,
+ "youngster": 35881,
+ "youngsters": 28098,
+ "younow": 33831,
+ "your": 2130,
+ "your": 695,
+ "youre": 28344,
+ "youre": 19695,
+ "yourown": 28583,
+ "yours": 3834,
+ "yourself": 3053,
+ "yourselves": 19747,
+ "youth": 10743,
+ "youth": 3281,
+ "youthful": 37480,
+ "youths": 23614,
+ "youts": 22737,
+ "youtu": 13868,
+ "youtube": 31258,
+ "youtube": 3895,
+ "youtuber": 24720,
+ "youtubers": 36822,
+ "youu": 35055,
+ "youuu": 35324,
+ "youuuu": 47123,
+ "yoy": 41865,
+ "yp": 38370,
+ "yp": 34734,
+ "ypg": 37386,
+ "yql": 46122,
+ "yqr": 36881,
+ "yr": 18395,
+ "yr": 4333,
+ "yrs": 4822,
+ "ys": 1971,
+ "ys": 961,
+ "yser": 33121,
+ "ysis": 4843,
+ "ysl": 45681,
+ "ysm": 23842,
+ "yst": 40528,
+ "yt": 36777,
+ "yt": 14779,
+ "ytd": 47524,
+ "yte": 48172,
+ "yu": 3371,
+ "yu": 8887,
+ "yuan": 26236,
+ "yuck": 48282,
+ "yugo": 48231,
+ "yuh": 42547,
+ "yui": 47932,
+ "yuk": 17037,
+ "yuk": 24063,
+ "yuki": 34010,
+ "yukon": 27094,
+ "yul": 39832,
+ "yum": 6869,
+ "yum": 7259,
+ "yuma": 47566,
+ "yummy": 7687,
+ "yun": 14976,
+ "yun": 18288,
+ "yung": 44545,
+ "yung": 17676,
+ "yunho": 39748,
+ "yup": 13231,
+ "yur": 42533,
+ "yuri": 23823,
+ "yusuf": 33222,
+ "yuv": 36784,
+ "yves": 33698,
+ "yvon": 23327,
+ "yvonne": 32583,
+ "yvr": 29058,
+ "yw": 33741,
+ "yx": 35624,
+ "yxe": 34240,
+ "yy": 3433,
+ "yy": 8321,
+ "yya": 37444,
+ "yyc": 27542,
+ "yyc": 11741,
+ "yyj": 26203,
+ "yyy": 11514,
+ "yyyy": 38749,
+ "yyyy": 16955,
+ "yyyyy": 26089,
+ "yyyyyy": 47055,
+ "yz": 37579,
+ "yz": 46451,
+ "yü": 48232,
+ "z": 89,
+ "z": 345,
+ "za": 3710,
+ "za": 2186,
+ "zab": 22982,
+ "zable": 37002,
+ "zac": 25501,
+ "zac": 19159,
+ "zach": 13401,
+ "zach": 11815,
+ "zachary": 32401,
+ "zack": 30567,
+ "zack": 19120,
+ "zad": 47314,
+ "zad": 27838,
+ "zada": 34889,
+ "zaf": 21837,
+ "zafar": 46668,
+ "zag": 26091,
+ "zag": 29346,
+ "zagre": 34107,
+ "zagreb": 35355,
+ "zah": 23258,
+ "zah": 43297,
+ "zaha": 44408,
+ "zai": 44329,
+ "zai": 27065,
+ "zain": 34400,
+ "zain": 45366,
+ "zak": 13050,
+ "zak": 20738,
+ "zaki": 48091,
+ "zal": 20552,
+ "zal": 33298,
+ "zam": 7218,
+ "zam": 41578,
+ "zambia": 21671,
+ "zan": 7284,
+ "zan": 17835,
+ "zana": 39643,
+ "zand": 37712,
+ "zane": 34786,
+ "zani": 45373,
+ "zania": 15059,
+ "zano": 27637,
+ "zanzi": 47835,
+ "zap": 24134,
+ "zapp": 33504,
+ "zappa": 46592,
+ "zar": 5458,
+ "zar": 16392,
+ "zara": 24454,
+ "zardari": 20174,
+ "zas": 48261,
+ "zation": 3683,
+ "zawa": 49281,
+ "zay": 7102,
+ "zayed": 36726,
+ "zayn": 22292,
+ "zayn": 10308,
+ "zaynmalik": 25278,
+ "zazzle": 47857,
+ "ze": 2254,
+ "ze": 1298,
+ "zeal": 44951,
+ "zealand": 7618,
+ "zeb": 46518,
+ "zebra": 47394,
+ "zebra": 22548,
+ "zed": 21047,
+ "zed": 1993,
+ "zedd": 45608,
+ "zee": 25468,
+ "zee": 14080,
+ "zeiss": 47460,
+ "zeit": 37898,
+ "zeit": 37906,
+ "zek": 40829,
+ "zeke": 47065,
+ "zel": 10389,
+ "zel": 12027,
+ "zelda": 17138,
+ "zell": 39526,
+ "zen": 8518,
+ "zen": 3928,
+ "zend": 33478,
+ "zendaya": 35956,
+ "zenith": 44740,
+ "zens": 15298,
+ "zeph": 40726,
+ "zepp": 22977,
+ "zeppelin": 25408,
+ "zer": 6118,
+ "zer": 3716,
+ "zero": 14867,
+ "zero": 5848,
+ "zers": 9547,
+ "zes": 4073,
+ "zest": 37709,
+ "zet": 34098,
+ "zeta": 30954,
+ "zetta": 45993,
+ "zeus": 32800,
+ "zey": 46647,
+ "zh": 33389,
+ "zh": 41621,
+ "zhang": 21127,
+ "zhen": 37374,
+ "zhen": 33236,
+ "zhou": 17384,
+ "zhu": 42049,
+ "zi": 2651,
+ "zi": 5819,
+ "zia": 13764,
+ "zid": 30235,
+ "zidane": 34643,
+ "zie": 29316,
+ "zie": 8956,
+ "zieg": 40157,
+ "ziegler": 46812,
+ "ziel": 32151,
+ "zier": 15399,
+ "zies": 38001,
+ "ziest": 28159,
+ "zig": 15950,
+ "zig": 21345,
+ "ziggy": 39274,
+ "zik": 30125,
+ "zika": 28783,
+ "zil": 25039,
+ "zil": 33190,
+ "zilla": 17879,
+ "zim": 8112,
+ "zim": 22577,
+ "zimbab": 12373,
+ "zimbabwe": 45668,
+ "zimbabwe": 13583,
+ "zimmer": 27452,
+ "zimmer": 35211,
+ "zimmerman": 38231,
+ "zin": 14085,
+ "zin": 21278,
+ "zinc": 27458,
+ "zind": 26206,
+ "zindabad": 42208,
+ "zine": 16100,
+ "zing": 25062,
+ "zing": 3152,
+ "zinger": 42027,
+ "zio": 13906,
+ "zion": 31763,
+ "zion": 20963,
+ "zione": 36161,
+ "zionist": 33078,
+ "zip": 26479,
+ "zip": 16083,
+ "zipper": 33670,
+ "zir": 31892,
+ "zl": 39168,
+ "zlat": 32489,
+ "zlatan": 37877,
+ "zm": 43691,
+ "zman": 24248,
+ "zn": 18004,
+ "zo": 4397,
+ "zo": 5056,
+ "zodi": 22660,
+ "zodiac": 27753,
+ "zoe": 43114,
+ "zoe": 16662,
+ "zoey": 39871,
+ "zog": 40680,
+ "zol": 25939,
+ "zola": 46105,
+ "zom": 6623,
+ "zombi": 29452,
+ "zombie": 11819,
+ "zombies": 46702,
+ "zombies": 16517,
+ "zon": 15109,
+ "zon": 14618,
+ "zona": 42134,
+ "zone": 37197,
+ "zone": 4442,
+ "zones": 17247,
+ "zoning": 36790,
+ "zoo": 8182,
+ "zoo": 7147,
+ "zoom": 32671,
+ "zoom": 13909,
+ "zor": 17605,
+ "zou": 38072,
+ "zr": 39275,
+ "zs": 35248,
+ "zshq": 41442,
+ "zt": 42629,
+ "zu": 4091,
+ "zu": 14184,
+ "zucchini": 29873,
+ "zucker": 26890,
+ "zuckerberg": 30066,
+ "zul": 31146,
+ "zulu": 32821,
+ "zum": 35094,
+ "zuma": 23326,
+ "zumba": 32976,
+ "zun": 42440,
+ "zur": 17128,
+ "zurich": 21288,
+ "zw": 42188,
+ "zx": 31604,
+ "zy": 6615,
+ "zy": 2303,
+ "zyk": 39112,
+ "zyme": 36472,
+ "zyn": 45287,
+ "zz": 1544,
+ "zz": 4943,
+ "zza": 14642,
+ "zzi": 13974,
+ "zzie": 18635,
+ "zzle": 7873,
+ "zzled": 39075,
+ "zzo": 14036,
+ "zzy": 21275,
+ "zzy": 8353,
+ "zzz": 20055,
+ "zzzz": 35742,
+ "zzzz": 43103,
+ "{": 90,
+ "{": 346,
+ "{}": 39025,
+ "|": 91,
+ "|#": 31183,
+ "|": 347,
+ "|@": 41677,
+ "||": 7566,
+ "}": 92,
+ "}": 348,
+ "~": 93,
+ "~!": 31181,
+ "~\"": 48442,
+ "~": 349,
+ "~>": 43291,
+ "~@": 44247,
+ "~~": 11461,
+ "~~": 16671,
+ "~~~": 32472,
+ "~~~~": 28295,
+ "¡": 94,
+ "¡": 350,
+ "¡ï¸ı": 15113,
+ "¡ï¸ı": 4174,
+ "¡ľ": 43991,
+ "¢": 95,
+ "¢": 351,
+ "£": 96,
+ "£": 352,
+ "£ï¸ı": 18446,
+ "¤": 97,
+ "¤": 353,
+ "¥": 98,
+ "¥": 354,
+ "¦": 99,
+ "¦": 355,
+ "¦Ī": 47615,
+ "§": 100,
+ "§": 356,
+ "¨": 101,
+ "¨": 357,
+ "©": 102,
+ "©": 358,
+ "ª": 103,
+ "ª": 359,
+ "«": 104,
+ "«": 360,
+ "¬": 105,
+ "¬": 361,
+ "‘": 31736,
+ "®": 106,
+ "®": 362,
+ "¯": 107,
+ "¯": 363,
+ "°": 108,
+ "°:": 21787,
+ "°": 364,
+ "°ï¸ı": 34777,
+ "±": 109,
+ "±": 365,
+ "±ï¸ı": 41020,
+ "²": 110,
+ "²": 366,
+ "³": 111,
+ "³": 367,
+ "³ï¸ı": 22195,
+ "³ï¸ı": 24706,
+ "´": 112,
+ "´": 368,
+ "µ": 113,
+ "µ": 369,
+ "µï¸ı": 27605,
+ "¶": 114,
+ "¶": 370,
+ "·": 115,
+ "·": 371,
+ "¸": 116,
+ "¸": 372,
+ "¸ë": 19693,
+ "¹": 117,
+ "¹": 373,
+ "º": 118,
+ "º": 374,
+ "»": 119,
+ "»": 375,
+ "¼": 120,
+ "¼": 376,
+ "½": 121,
+ "½": 377,
+ "½ï¸ı": 31333,
+ "¾": 122,
+ "¾": 378,
+ "¿": 123,
+ "¿": 379,
+ "À": 124,
+ "À": 380,
+ "Á": 125,
+ "Á": 381,
+ "Â": 126,
+ "Â": 382,
+ "¡": 26868,
+ "¡": 10830,
+ "¡¡": 45505,
+ "¢": 41359,
+ "£": 31117,
+ "£": 1950,
+ "Â¥": 20199,
+ "¨": 19957,
+ "¨¨": 23089,
+ "¨¨¨¨": 41223,
+ "©": 31148,
+ "©": 5811,
+ "«": 14434,
+ "®": 30857,
+ "®": 8436,
+ "¯": 38682,
+ "¯": 43593,
+ "¯\\": 44096,
+ "¯\\_(": 45115,
+ "°": 21305,
+ "°": 6858,
+ "²": 41175,
+ "´": 30560,
+ "´": 12559,
+ "·": 14844,
+ "º": 28059,
+ "»": 31642,
+ "»": 7599,
+ "½": 33613,
+ "¿": 44559,
+ "¿": 17133,
+ "ÂŃ": 22618,
+ "Ã": 127,
+ "Ã": 383,
+ "á": 7261,
+ "á": 22229,
+ "án": 38340,
+ "án": 21385,
+ "â": 26170,
+ "ã": 19339,
+ "ão": 21141,
+ "ä": 10896,
+ "ä": 47276,
+ "än": 42787,
+ "Ã¥": 23176,
+ "æ": 42495,
+ "ç": 10067,
+ "ça": 22711,
+ "è": 12138,
+ "è": 37761,
+ "ère": 30272,
+ "ès": 41210,
+ "é": 3459,
+ "é": 4166,
+ "éal": 45251,
+ "ée": 13489,
+ "és": 20507,
+ "ê": 27515,
+ "ë": 29526,
+ "ë": 40520,
+ "î": 48704,
+ "ï": 35689,
+ "ñ": 6445,
+ "ña": 17753,
+ "ño": 16574,
+ "ños": 40104,
+ "ó": 8891,
+ "ó": 27733,
+ "ón": 13926,
+ "ô": 26815,
+ "ö": 7255,
+ "ö": 37423,
+ "ör": 31762,
+ "ø": 17483,
+ "ø": 45598,
+ "ú": 17963,
+ "ú": 36019,
+ "ü": 6522,
+ "ü": 47177,
+ "ür": 26132,
+ "ÃĹ": 16165,
+ "Ãł": 36149,
+ "Ãł": 21259,
+ "ÃŃ": 8366,
+ "ÃŃ": 23928,
+ "ÃŃa": 16609,
+ "ÃŃn": 33623,
+ "Ä": 128,
+ "Ä": 384,
+ "ı": 18562,
+ "ı": 41901,
+ "Äģ": 23134,
+ "Äĩ": 31719,
+ "Äį": 45414,
+ "ÄŁ": 26540,
+ "Å": 129,
+ "Å": 385,
+ "Å¡": 35621,
+ "ÅĤ": 40419,
+ "Åį": 41267,
+ "ÅŁ": 21254,
+ "ÅŁ": 40706,
+ "Æ": 130,
+ "Æ": 386,
+ "Ç": 131,
+ "Ç": 387,
+ "È": 132,
+ "È": 388,
+ "É": 133,
+ "É": 389,
+ "Ê": 134,
+ "Ê": 390,
+ "Ë": 135,
+ "Ë": 391,
+ "Ì": 136,
+ "Ì": 392,
+ "Ìĩ": 16384,
+ "Í": 137,
+ "Í": 393,
+ "Î": 138,
+ "Î": 394,
+ "Ï": 139,
+ "Ï": 395,
+ "Ïī": 38065,
+ "Ð": 140,
+ "Ð": 396,
+ "а": 16912,
+ "а": 27080,
+ "аÐ": 31090,
+ "в": 39813,
+ "е": 22176,
+ "и": 16701,
+ "иÐ": 29503,
+ "к": 27152,
+ "л": 47611,
+ "м": 38018,
+ "н": 22705,
+ "о": 13506,
+ "о": 29386,
+ "оÐ": 20978,
+ "од": 38416,
+ "оÑĤ": 28599,
+ "п": 26302,
+ "пÑĢи": 46321,
+ "пÑĢиÑĢода": 48150,
+ "Ñ": 141,
+ "Ñ": 397,
+ "ÑĢ": 16370,
+ "ÑĢи": 41092,
+ "ÑĢод": 47039,
+ "ÑĢода": 47929,
+ "Ñģ": 23669,
+ "ÑĤ": 17875,
+ "Ñĥ": 39729,
+ "ÑĦ": 27993,
+ "ÑĦоÑĤ": 35155,
+ "ÑĦоÑĤо": 38981,
+ "Ñĭ": 45001,
+ "Ò": 142,
+ "Ò": 398,
+ "Ó": 143,
+ "Ó": 399,
+ "Ô": 144,
+ "Ô": 400,
+ "Õ": 145,
+ "Õ": 401,
+ "Ö": 146,
+ "Ö": 402,
+ "×": 147,
+ "×": 403,
+ "Ø": 148,
+ "Ø": 404,
+ "ا": 6042,
+ "ا": 22625,
+ "اØ": 13189,
+ "ار": 40137,
+ "اÙ": 8453,
+ "اÙĦ": 12973,
+ "اÙħ": 47626,
+ "اÙĨ": 42773,
+ "اÙĨ": 33200,
+ "ب": 16378,
+ "ب": 35330,
+ "Ø©": 20915,
+ "ت": 18197,
+ "ت": 44333,
+ "ج": 26375,
+ "Ø®": 41495,
+ "د": 19872,
+ "د": 35566,
+ "ر": 10948,
+ "ر": 24933,
+ "رÙĬ": 43273,
+ "ز": 36169,
+ "س": 17856,
+ "Ø´": 28770,
+ "ص": 27271,
+ "Ø·": 32050,
+ "ع": 18843,
+ "غ": 48510,
+ "ØŃ": 25722,
+ "Ù": 149,
+ "Ù": 405,
+ "Ùģ": 24112,
+ "ÙĤ": 27585,
+ "Ùĥ": 33499,
+ "ÙĦ": 14251,
+ "ÙĦ": 37899,
+ "Ùħ": 12986,
+ "Ùħ": 29945,
+ "ÙĨ": 16655,
+ "ÙĨ": 25386,
+ "Ùĩ": 34274,
+ "Ùĩ": 31343,
+ "ÙĪ": 12203,
+ "ÙĪ": 38310,
+ "ÙĪØ±": 48242,
+ "ÙĬ": 12046,
+ "ÙĬ": 23853,
+ "Ú": 150,
+ "Ú": 406,
+ "Ú©": 26475,
+ "Û": 151,
+ "Û": 407,
+ "Ûģ": 40480,
+ "ÛĮ": 21452,
+ "ÛĮ": 32703,
+ "Ü": 152,
+ "Ü": 408,
+ "Ý": 153,
+ "Ý": 409,
+ "Þ": 154,
+ "Þ": 410,
+ "ß": 155,
+ "ß": 411,
+ "à": 156,
+ "à": 412,
+ "à¤": 3124,
+ "त": 27263,
+ "द": 29552,
+ "न": 26090,
+ "प": 44149,
+ "ब": 43599,
+ "म": 48254,
+ "म": 26774,
+ "य": 37299,
+ "र": 39136,
+ "र": 19052,
+ "ल": 30881,
+ "व": 39545,
+ "श": 43181,
+ "स": 28505,
+ "ह": 29446,
+ "ा": 37973,
+ "ा": 13343,
+ "ि": 26721,
+ "à¤Ĥ": 30833,
+ "à¤ķ": 22067,
+ "à¤Ĺ": 42598,
+ "à¤ľ": 39561,
+ "à¥": 7410,
+ "à¥Ģ": 45791,
+ "à¥Ģ": 25751,
+ "à¥ģ": 39653,
+ "à¥ĩ": 48612,
+ "à¥ĩ": 25130,
+ "à¥ĭ": 34452,
+ "à¥į": 19389,
+ "à¦": 11322,
+ "া": 41532,
+ "à§": 26339,
+ "à¨": 15741,
+ "à©": 32086,
+ "àª": 22990,
+ "à«": 48347,
+ "à¬": 32791,
+ "à®": 6022,
+ "த": 34691,
+ "ன": 43394,
+ "ப": 47388,
+ "à®®": 35463,
+ "à®°": 43270,
+ "ல": 47705,
+ "ா": 32831,
+ "ி": 27126,
+ "à®ķ": 36168,
+ "à®Ł": 45263,
+ "à¯": 11259,
+ "à¯ģ": 33115,
+ "à¯į": 16631,
+ "à°": 12100,
+ "à±": 23550,
+ "à±į": 46098,
+ "à²": 9992,
+ "ಿ": 47797,
+ "à³": 20745,
+ "à³į": 36148,
+ "à´": 15418,
+ "àµ": 27392,
+ "àµį": 45266,
+ "à¶": 29881,
+ "à·": 30766,
+ "à¸": 1777,
+ "ม": 26137,
+ "ม": 29570,
+ "ย": 27241,
+ "ย": 33091,
+ "ร": 32225,
+ "ร": 27331,
+ "ล": 34696,
+ "ล": 32746,
+ "ว": 26990,
+ "ว": 30245,
+ "ส": 37883,
+ "ส": 35737,
+ "ห": 33064,
+ "ะ": 43920,
+ "ะ": 49234,
+ "ั": 14978,
+ "า": 11529,
+ "า": 38476,
+ "าà¸": 12330,
+ "ิ": 17092,
+ "ี": 22421,
+ "ี": 20278,
+ "ีà¹Ī": 31511,
+ "ื": 47991,
+ "ุ": 30524,
+ "ู": 35273,
+ "à¸ģ": 30767,
+ "à¸ģà¸": 31474,
+ "à¸Ħ": 31757,
+ "à¸Ħà¸": 39628,
+ "à¸ĩ": 24603,
+ "à¸ĩ": 33382,
+ "à¸Ī": 47608,
+ "à¸Ĭ": 46324,
+ "à¸Ķ": 31107,
+ "à¸Ķ": 38825,
+ "à¸ķ": 40273,
+ "à¸ķ": 41108,
+ "à¸Ĺ": 36171,
+ "à¸Ļ": 17474,
+ "à¸Ļ": 17639,
+ "à¸Ļà¸": 23121,
+ "à¸ļ": 33859,
+ "à¸ļ": 39616,
+ "à¸ŀ": 48171,
+ "à¸Ń": 13398,
+ "à¸Ń": 32818,
+ "à¸Ńà¸": 14649,
+ "à¸Ńà¸ĩ": 46622,
+ "à¹": 4484,
+ "à¹Ģ": 13729,
+ "à¹Ģà¸": 14076,
+ "à¹ģà¸": 23916,
+ "à¹Ĥ": 33118,
+ "à¹ĥ": 40962,
+ "à¹Ħà¸": 31718,
+ "à¹ĩ": 38699,
+ "à¹Ī": 11722,
+ "à¹ī": 13123,
+ "à¹Į": 28353,
+ "à¼": 46186,
+ "à½": 39219,
+ "á": 157,
+ "á": 413,
+ "á´": 19036,
+ "áµ": 17330,
+ "áĢ": 45932,
+ "áĥ": 24829,
+ "áĥ¦": 32193,
+ "â": 158,
+ "â": 414,
+ "â¤": 25087,
+ "⤵ï¸ı": 36026,
+ "â¬": 7930,
+ "â¬ħï¸ı": 42111,
+ "â¬Ĩ": 27718,
+ "â¬Ĩï¸ı": 32798,
+ "â¬ĩ": 10917,
+ "â¬ĩ": 39370,
+ "â¬ĩï¸ı": 25621,
+ "â¬ĩï¸ı": 13984,
+ "â¬ĩï¸ıâ¬ĩï¸ı": 40159,
+ "âĢ": 728,
+ "âĢ¢": 9485,
+ "âĢ¢": 2701,
+ "âĢ¢âĢ¢": 15006,
+ "âĢ¢âĢ¢": 47575,
+ "âĢ¢âĢ¢âĢ¢âĢ¢": 27502,
+ "âĢ¢âĢ¢âĢ¢âĢ¢âĢ¢âĢ¢âĢ¢âĢ¢": 48630,
+ "â̦": 7095,
+ "â̦\"": 20215,
+ "â̦..": 47779,
+ "â̦.": 18615,
+ "â̦/": 29842,
+ "â̦": 959,
+ "â̦â̦": 40066,
+ "â̲": 32633,
+ "â̳": 25061,
+ "â̼": 6578,
+ "â̼ï¸ı": 15622,
+ "â̼ï¸ı": 8310,
+ "â̼ï¸ıâ̼ï¸ı": 33218,
+ "âĢĭ": 17086,
+ "âĢĭ": 9844,
+ "âĢį": 4244,
+ "âĢįâĻ": 5177,
+ "âĢįâĻĢï¸ı": 18897,
+ "âĢįâĻĢï¸ı": 9605,
+ "âĢįâĻĤ": 8832,
+ "âĢįâĻĤï¸ı": 21779,
+ "âĢįâĻĤï¸ı": 10613,
+ "âĢİ": 31001,
+ "âĢIJ": 34512,
+ "âĢĵ": 21070,
+ "âĢĵ": 1224,
+ "âĢĶ": 6718,
+ "âĢĶ": 2005,
+ "âĢĶ>": 26341,
+ "âĢĶ@": 28470,
+ "âĢĶâĢĶ": 10037,
+ "âĢĶâĢĶ": 44800,
+ "âĢĶâĢĶâĢĶâĢĶ": 17797,
+ "âĢĶâĢĶâĢĶâĢĶâĢĶâĢĶâĢĶâĢĶ": 34432,
+ "âĢķ": 14236,
+ "âģ": 1667,
+ "âģ£": 31089,
+ "âģ£": 16845,
+ "âģ¦": 2773,
+ "âģ¦": 34855,
+ "âģ¦@": 2859,
+ "âģ¦âģ¦@": 27783,
+ "âģ©": 20097,
+ "âģ©,": 48749,
+ "âģ©.": 35777,
+ "âģ©": 2918,
+ "âģīï¸ı": 46534,
+ "âģł": 23881,
+ "âģł": 13503,
+ "âģłâģł": 33488,
+ "âĤ": 5227,
+ "âĤ¬": 34919,
+ "âĤ¬": 6309,
+ "âĤ¹": 21777,
+ "âĥ": 2805,
+ "âĥ£": 11250,
+ "âĥ£": 3076,
+ "âĥ£@": 48291,
+ "âĦ": 8604,
+ "âĦ¢": 29438,
+ "âĦ¢": 11675,
+ "âĦ¹": 45462,
+ "âĨ": 6059,
+ "âĨĴ": 7481,
+ "âĨĵ": 41603,
+ "âĩ": 27228,
+ "âĪ": 17788,
+ "âī": 22684,
+ "âīĪ": 45451,
+ "âĮ": 17848,
+ "âĮļ": 31301,
+ "âĮļï¸ı": 35931,
+ "âı": 7960,
+ "âı©": 40847,
+ "âı°": 12714,
+ "âı±": 33149,
+ "âı³": 47617,
+ "âĵ": 27400,
+ "âĶ": 13389,
+ "âĶĢ": 45139,
+ "âĶģ": 42022,
+ "âķ": 17027,
+ "âķIJ": 48039,
+ "âĸ": 4168,
+ "âĸª": 21203,
+ "âĸª": 36628,
+ "âĸªï¸ı": 24974,
+ "âĸ«": 39478,
+ "âĸ¬": 33798,
+ "âĸ¬âĸ¬": 36975,
+ "âĸ¶": 12509,
+ "âĸ¶": 21126,
+ "âĸ¶ï¸ı": 14442,
+ "âĸº": 46061,
+ "âĸº": 12086,
+ "âĸ½": 45634,
+ "âĸł": 36791,
+ "âĹ": 9323,
+ "âĹĨ": 48961,
+ "âĹı": 26999,
+ "âĺ": 1741,
+ "âĺ®": 45851,
+ "âĺ¹": 28811,
+ "âĺ¹ï¸ı": 39605,
+ "âĺº": 5010,
+ "âĺº": 8703,
+ "âĺºâĺº": 46051,
+ "âĺºï¸ı": 11506,
+ "âĺºï¸ı": 7779,
+ "âĺºï¸ıâĺºï¸ı": 41315,
+ "âĺ¼": 38877,
+ "âĺĢ": 32146,
+ "âĺĢ": 22242,
+ "âĺĢï¸ı": 12817,
+ "âĺĢï¸ı": 8219,
+ "âĺĢï¸ıâĺĢï¸ı": 44550,
+ "âĺģ": 25195,
+ "âĺģï¸ı": 35197,
+ "âĺĥ": 38972,
+ "âĺħ": 9339,
+ "âĺħ": 10643,
+ "âĺħâĺħ": 12681,
+ "âĺħâĺħ": 36644,
+ "âĺħâĺħâĺħâĺħ": 34431,
+ "âĺħâĺħâĺħâĺħ": 44034,
+ "âĺħâĺħâĺħâĺħâĺħ": 45984,
+ "âĺĨ": 23941,
+ "âĺĨ": 13439,
+ "âĺİ": 24045,
+ "âĺİ": 45493,
+ "âĺİï¸ı": 27219,
+ "âĺij": 20983,
+ "âĺij": 42300,
+ "âĺijï¸ı": 22291,
+ "âĺĶï¸ı": 31238,
+ "âĺķ": 11454,
+ "âĺķ": 26561,
+ "âĺķï¸ı": 25839,
+ "âĺķï¸ı": 15499,
+ "âĺĺ": 23483,
+ "âĺĺï¸ı": 31454,
+ "âĺĿ": 21982,
+ "âĺĿï¸ı": 38891,
+ "âĺŀ": 31255,
+ "âĺłï¸ı": 34672,
+ "âĻ": 1548,
+ "âĻ¡": 11091,
+ "âĻ¡": 6251,
+ "âĻ¡âĻ¡": 22360,
+ "âĻ¡âĻ¡": 34267,
+ "âĻ¡âĻ¡âĻ¡": 36611,
+ "âϤ": 47435,
+ "âĻ¥": 4622,
+ "âĻ¥": 3405,
+ "âĻ¥âĻ¥": 12975,
+ "âĻ¥âĻ¥": 19604,
+ "âĻ¥âĻ¥âĻ¥": 23255,
+ "âĻ¥âĻ¥âĻ¥âĻ¥": 49020,
+ "âĻ¥ï¸ı": 17774,
+ "âĻ¥ï¸ı": 10561,
+ "âĻ¥ï¸ıâĻ¥ï¸ı": 40309,
+ "âϦ": 32376,
+ "âϦ": 47547,
+ "âĻ©": 30339,
+ "âĻ©âĻ«": 31636,
+ "âĻª": 27364,
+ "âĻª": 12382,
+ "âĻ«": 39217,
+ "âĻ«": 10814,
+ "âϬ": 24753,
+ "âĻ»": 39611,
+ "âĻ»ï¸ı": 46075,
+ "âļ": 2234,
+ "âļ¡": 40098,
+ "âļ¡": 20712,
+ "âļ¡ï¸ı": 19500,
+ "âļ¡ï¸ı": 11605,
+ "âļ¡ï¸ıâļ¡ï¸ı": 45922,
+ "âļª": 11922,
+ "âļª": 36373,
+ "âļªï¸ı": 22251,
+ "âļªï¸ı": 17885,
+ "âļ«": 15374,
+ "âļ«ï¸ı": 26529,
+ "âļ«ï¸ı": 24649,
+ "âļ½": 4867,
+ "âļ½": 13173,
+ "âļ½âļ½": 43259,
+ "âļ½ï¸ı": 11342,
+ "âļ½ï¸ı": 6768,
+ "âļ½ï¸ıâļ½ï¸ı": 30358,
+ "âļ½ï¸ıâļ½ï¸ı": 44148,
+ "âļ¾": 11314,
+ "âļ¾": 34717,
+ "âļ¾ï¸ı": 24727,
+ "âļ¾ï¸ı": 14858,
+ "âļĵ": 23522,
+ "âļĵï¸ı": 35299,
+ "âļĶï¸ı": 29361,
+ "âļľ": 47491,
+ "âļł": 39203,
+ "âļłï¸ı": 40966,
+ "âļłï¸ı": 15596,
+ "âĽ": 7956,
+ "âĽ³ï¸ı": 29204,
+ "âĽĦ": 30668,
+ "âĽĦï¸ı": 45465,
+ "âľ": 1508,
+ "⾨": 7181,
+ "⾨": 3531,
+ "⾨⾨": 35174,
+ "⾨⾨": 21985,
+ "⾨⾨⾨": 39424,
+ "âľĤ": 38602,
+ "âľħ": 29544,
+ "âľħ": 5564,
+ "âľĪ": 10682,
+ "âľĪ": 30712,
+ "âľĪï¸ı": 26176,
+ "âľĪï¸ı": 13413,
+ "âľĬ": 12392,
+ "âľĬ": 17819,
+ "âľĬðŁı½": 48547,
+ "âľĬðŁı¾": 41185,
+ "âľĭ": 39383,
+ "âľĭ": 30239,
+ "âľĮ": 6419,
+ "âľĮ": 12656,
+ "âľĮï¸ı": 21906,
+ "âľĮï¸ı": 12239,
+ "âľĮðŁı»": 30538,
+ "âľĮðŁı¼": 30588,
+ "âľį": 20872,
+ "âľįï¸ı": 30888,
+ "âľı": 32574,
+ "âľıï¸ı": 40724,
+ "âľĵ": 36700,
+ "âľĶ": 47200,
+ "âľĶ": 13749,
+ "âľĶï¸ı": 40544,
+ "âľĶï¸ı": 9191,
+ "âľĸï¸ı": 44133,
+ "âľĿ": 42220,
+ "âĿ": 1045,
+ "âĿ£": 37007,
+ "âĿ£": 25623,
+ "âĿ£ï¸ı": 25240,
+ "âĿ¤": 1266,
+ "âĿ¤": 2720,
+ "âĿ¤âĿ¤": 9033,
+ "âĿ¤âĿ¤": 14058,
+ "âĿ¤âĿ¤âĿ¤": 16708,
+ "âĿ¤âĿ¤âĿ¤âĿ¤": 37918,
+ "âĿ¤âĿ¤âĿ¤âĿ¤": 43970,
+ "âĿ¤ï¸ı": 2626,
+ "âĿ¤ï¸ı#": 30281,
+ "âĿ¤ï¸ı.": 45326,
+ "âĿ¤ï¸ı": 1752,
+ "âĿ¤ï¸ı@": 31187,
+ "âĿ¤ï¸ıâĿ¤ï¸ı": 6713,
+ "âĿ¤ï¸ıâĿ¤ï¸ı": 10363,
+ "âĿ¤ï¸ıâĿ¤ï¸ıâĿ¤ï¸ı": 12282,
+ "âĿ¤ï¸ıâĿ¤ï¸ıâĿ¤ï¸ıâĿ¤ï¸ı": 39167,
+ "âĿ¤ï¸ıâĿ¤ï¸ıâĿ¤ï¸ıâĿ¤ï¸ı": 29880,
+ "âĿ¤ï¸ıðŁĴĻ": 37380,
+ "âĿ¤ï¸ıðŁĺį": 37272,
+ "âĿ¤ï¸ıðŁĺĺ": 41800,
+ "âĿ¤ðŁĺį": 49120,
+ "âĿ¥": 36914,
+ "âĿĦ": 8501,
+ "âĿĦ": 30494,
+ "âĿĦï¸ı": 16834,
+ "âĿĦï¸ı": 12402,
+ "âĿĦï¸ıâĿĦï¸ı": 41626,
+ "âĿĮ": 44485,
+ "âĿĮ": 17975,
+ "âĿĵ": 29791,
+ "âĿĹ": 12868,
+ "âĿĹ": 29079,
+ "âĿĹï¸ı": 28642,
+ "âĿĹï¸ı": 17391,
+ "âĿĿ": 46951,
+ "âŀ": 3257,
+ "âŀ¡": 12854,
+ "âŀ¡ï¸ı": 31860,
+ "âŀ¡ï¸ı": 4956,
+ "âŀ¤": 18651,
+ "âŀķ": 46526,
+ "âŀĸ": 21327,
+ "âŀĸ": 34902,
+ "âŀĸâŀĸ": 23316,
+ "âŀĸâŀĸâŀĸâŀĸ": 40401,
+ "âŀľ": 23775,
+ "âł": 5689,
+ "âłĢ": 9691,
+ "âłĢ": 8621,
+ "âłĢâłĢ": 11466,
+ "âłĢâłĢ": 39092,
+ "âłĢâłĢâłĢâłĢ": 20976,
+ "âłĢâłĢâłĢâłĢâłĢâłĢâłĢâłĢ": 46063,
+ "âŃ": 5527,
+ "âŃIJ": 6410,
+ "âŃIJ": 19012,
+ "âŃIJâŃIJ": 32663,
+ "âŃIJï¸ı": 12427,
+ "âŃIJï¸ı": 10251,
+ "âŃIJï¸ıâŃIJï¸ı": 18640,
+ "âŃIJï¸ıâŃIJï¸ıâŃIJï¸ı": 40746,
+ "ã": 159,
+ "ã": 415,
+ "ãĢ": 4092,
+ "ãĢģ": 45262,
+ "ãĢĤ": 38060,
+ "ãĢĤ": 38000,
+ "ãĢĬ": 39920,
+ "ãĢĭ": 32898,
+ "ãĢĮ": 18116,
+ "ãĢį": 19149,
+ "ãĢİ": 26947,
+ "ãĢı": 30293,
+ "ãĢIJ": 12534,
+ "ãĢij": 12990,
+ "ãĢľ": 39581,
+ "ãģ": 4813,
+ "ãģ¦": 48029,
+ "ãģ¨": 34671,
+ "ãģ¨ç¹ĭãģ": 47310,
+ "ãģ¨ç¹ĭãģĮãĤĬãģŁãģĦ": 48290,
+ "ãģª": 29104,
+ "ãģ®": 21575,
+ "ãģ·": 44130,
+ "ãģĦ": 33523,
+ "ãģĦ": 38850,
+ "ãģĨ": 44235,
+ "ãģį": 42184,
+ "ãĤ": 3909,
+ "ãĤ¢": 26560,
+ "ãĤ¤": 19319,
+ "ãĤ¤ãĥ": 36294,
+ "ãĤ«": 37367,
+ "ãĤ¯": 31574,
+ "ãĤ·": 37665,
+ "ãĤ¸": 32234,
+ "ãĤ¸ãĥ": 43491,
+ "ãĤ¹": 22694,
+ "ãĤ¹": 39220,
+ "ãĤ¹ãĥ": 32421,
+ "ãĤ¿": 34941,
+ "ãĤĬãģ": 40500,
+ "ãĤĮ": 45211,
+ "ãĤŃ": 47121,
+ "ãĥ": 2429,
+ "ãĥ©": 23007,
+ "ãĥª": 32115,
+ "ãĥ«": 33257,
+ "ãĥ¬": 32965,
+ "ãĥ³": 17671,
+ "ãĥ³": 26875,
+ "ãĥ³ãĤ": 45105,
+ "ãĥ³ãĥ": 25914,
+ "ãĥ»": 8415,
+ "ãĥ»": 11158,
+ "ãĥ»ãĥ»": 13949,
+ "ãĥ»ãĥ»ãĥ»": 14234,
+ "ãĥ¼": 13457,
+ "ãĥ¼": 30391,
+ "ãĥ¼ãĥ": 18584,
+ "ãĥĥ": 28902,
+ "ãĥĦ": 32173,
+ "ãĥĪ": 42384,
+ "ãĥİ": 39967,
+ "ãĥķãĤ": 33371,
+ "ãĥŀ": 48924,
+ "ãĥŃ": 35827,
+ "ãħ": 5947,
+ "ãħ¤": 21096,
+ "ãħ¤ãħ¤": 22583,
+ "ãħ¤ãħ¤ãħ¤ãħ¤": 39329,
+ "ãħĭ": 13052,
+ "ãħĭ": 25108,
+ "ãħĭãħĭ": 16604,
+ "ãħĭãħĭ": 42581,
+ "ãħĭãħĭãħĭ": 46407,
+ "ãħĭãħĭãħĭãħĭ": 39362,
+ "ãħł": 16089,
+ "ãħł": 25781,
+ "ãħłãħł": 22021,
+ "ãħłãħł": 34398,
+ "ãħłãħłãħłãħł": 47028,
+ "ä": 160,
+ "ä": 416,
+ "ä¸": 19759,
+ "ä¹": 41854,
+ "äº": 21078,
+ "人": 36839,
+ "ä»": 37743,
+ "ä½": 47466,
+ "å": 161,
+ "å": 417,
+ "å¤": 23170,
+ "å¥": 29290,
+ "å®": 27047,
+ "å°": 34720,
+ "å±": 46096,
+ "å¸": 42021,
+ "å¹": 38780,
+ "åħ": 34314,
+ "åĨ": 27972,
+ "åĨĻ": 44653,
+ "åĪ": 42748,
+ "åĭ": 47505,
+ "åı": 34517,
+ "åIJ": 41673,
+ "åĽ": 39027,
+ "åľ": 37746,
+ "åŃ": 35751,
+ "æ": 162,
+ "æ": 418,
+ "æĸ": 29032,
+ "æĹ": 22265,
+ "æĹ¥": 39121,
+ "æĹ¥": 37156,
+ "æĺ": 42891,
+ "æĻ": 48132,
+ "æľ": 19277,
+ "æľ¬": 44353,
+ "æĿ": 27667,
+ "æĿ±": 48338,
+ "ç": 163,
+ "ç": 419,
+ "ç¥": 26369,
+ "ç¥Ń": 42557,
+ "çµ": 37810,
+ "ç¹": 43431,
+ "ç¹ĭãģ": 45930,
+ "çĶ": 20211,
+ "çĶŁ": 33375,
+ "çľ": 33440,
+ "羣": 41570,
+ "è": 164,
+ "è": 420,
+ "èª": 34002,
+ "èªķ": 41293,
+ "é": 165,
+ "é": 421,
+ "éģ": 44854,
+ "éĩ": 38283,
+ "ê": 166,
+ "ê": 422,
+ "ê°": 21122,
+ "ê°ĵ": 41076,
+ "ê°ĵìĦ¸ë¸IJ": 41689,
+ "ê°ķ": 45758,
+ "ê²": 35555,
+ "ê³": 36216,
+ "êµ": 31871,
+ "ê·": 42680,
+ "ê¸": 32495,
+ "ê¹": 24531,
+ "ê¹Ģ": 25203,
+ "ë": 167,
+ "ë": 423,
+ "ë¦": 24621,
+ "리": 47649,
+ "ë§": 28024,
+ "ë§Ī": 40027,
+ "ëª": 36311,
+ "ë¯": 19528,
+ "민": 34442,
+ "민": 44632,
+ "ë°": 15810,
+ "ë°©": 23273,
+ "ë°©íĥ": 25081,
+ "ë°©íĥĦ": 25641,
+ "ë°©íĥĦìĨĮëħĦëĭ": 26068,
+ "ë°©íĥĦìĨĮëħĦëĭ¨": 27129,
+ "ë°ķ": 40988,
+ "ë²": 48267,
+ "ë³": 44693,
+ "ë¹": 24193,
+ "ëĤ": 27252,
+ "ëĤĺ": 48484,
+ "ëĭ": 13094,
+ "ëĭ¤": 46680,
+ "ëĭĪ": 33708,
+ "ëį": 45543,
+ "ëı": 31972,
+ "ëĵ": 30850,
+ "ëĿ": 44317,
+ "ì": 168,
+ "ì": 424,
+ "ì£": 39856,
+ "주": 45161,
+ "ì¤": 31153,
+ "ì§": 16279,
+ "ì§Ģ": 28836,
+ "ì§Ħ": 38890,
+ "ì°": 40742,
+ "ì¶": 42476,
+ "ì¶ķ": 46403,
+ "ì¶ķíķĺ": 47866,
+ "ì¹": 45088,
+ "ìĤ": 31061,
+ "ìĥ": 30587,
+ "ìĥĿ": 47858,
+ "ìĦ": 15074,
+ "ìĦ¸ë": 29254,
+ "ìĦ¸ë¸": 29658,
+ "ìĦ¸ë¸IJ": 41415,
+ "ìĨ": 15115,
+ "ìĨĮë": 20515,
+ "ìĨĮëħ": 21391,
+ "ìĨĮëħĦëĭ": 25887,
+ "ìĪ": 32757,
+ "ìĬ": 12125,
+ "ìĬ¤": 20305,
+ "ìĬ¤": 23829,
+ "ìĭ": 23924,
+ "ìķ": 16071,
+ "ìķĦ": 23233,
+ "ìĸ": 31625,
+ "ìĹ": 13252,
+ "ìĹIJ": 37622,
+ "ìĹij": 31036,
+ "ìĹijìĨ": 42763,
+ "ìĹijìĨĮ": 45606,
+ "ìĺ": 21144,
+ "ìĻ": 39405,
+ "ìļ": 18541,
+ "ìļ°": 38415,
+ "ìļ°": 49344,
+ "ìĽ": 22543,
+ "ìĽIJ": 36495,
+ "ìľ": 20909,
+ "ìľł": 42890,
+ "ìĿ": 8276,
+ "ìĿ´": 12286,
+ "ìĿ´": 34746,
+ "ìĿ´ì": 37590,
+ "ìĿ¼": 43406,
+ "ìŀ": 20849,
+ "ìł": 20580,
+ "ìłķ": 34725,
+ "í": 169,
+ "í": 425,
+ "íģ": 35641,
+ "íģ¬": 45832,
+ "íĤ": 43565,
+ "íĥ": 15012,
+ "íĥĢ": 41126,
+ "íĥľ": 37663,
+ "íĬ": 23215,
+ "íĬ¸": 48974,
+ "íĬ¸": 39820,
+ "íĭ": 34350,
+ "íĶ": 29450,
+ "íķ": 15197,
+ "íķ´": 35286,
+ "íķĺ": 33992,
+ "íĺ": 15962,
+ "íĺ¸": 39657,
+ "íĺĦ": 34645,
+ "íĻ": 31882,
+ "î": 170,
+ "î": 426,
+ "îĢ": 36288,
+ "îĦ": 35368,
+ "îĮ": 41006,
+ "îIJ": 16929,
+ "îIJĴ": 40100,
+ "ï": 171,
+ "ï": 427,
+ "ï¸": 842,
+ "ï¸İ": 24029,
+ "ï¸ı": 1392,
+ "ï¸ı#": 46997,
+ "ï¸ı:": 32604,
+ "ï¸ı": 1001,
+ "ï¸ı@": 34600,
+ "ï¸ıâĥ£": 17394,
+ "ï¸ıâĥ£-": 40376,
+ "ï¸ıâĥ£": 4603,
+ "ï¿": 27850,
+ "�": 47356,
+ "�": 39802,
+ "ð": 172,
+ "ð": 428,
+ "ðĿ": 6874,
+ "ðĿIJ": 15889,
+ "ðĿij": 43794,
+ "ðĿĴ": 43387,
+ "ðĿĵ": 47110,
+ "ðĿĹ": 18865,
+ "ðĿĺ": 26109,
+ "ðĿĻ": 29415,
+ "ðŁ": 558,
+ "ð٤": 1793,
+ "ðŁ¤£": 9665,
+ "ðŁ¤£": 9909,
+ "ðŁ¤£ðŁ¤£": 16430,
+ "ðŁ¤£ðŁ¤£": 31009,
+ "ðŁ¤£ðŁ¤£ðŁ¤£": 32262,
+ "ðŁ¤¤": 39550,
+ "ðŁ¤¤": 26759,
+ "ðŁ¤¦": 17186,
+ "ðŁ¤§": 40983,
+ "ðŁ¤©": 27351,
+ "ðŁ¤©": 16074,
+ "ðŁ¤ª": 44230,
+ "ðŁ¤ª": 24920,
+ "ðŁ¤«": 47671,
+ "ðŁ¤¯": 37595,
+ "ðŁ¤·": 13185,
+ "ðŁ¤·ðŁı»âĢįâĻĢï¸ı": 46770,
+ "ð٤ij": 34801,
+ "ð٤ĵ": 36580,
+ "ð٤ĵ": 18928,
+ "ð٤Ķ": 12706,
+ "ð٤Ķ": 6497,
+ "ð٤Ķð٤Ķ": 28490,
+ "ð٤Ķð٤Ķð٤Ķ": 43361,
+ "ð٤ĸ": 46146,
+ "ð٤Ĺ": 16646,
+ "ð٤Ĺ": 10465,
+ "ð٤Ĺð٤Ĺ": 44321,
+ "ð٤ĺ": 10623,
+ "ð٤ĺ": 17288,
+ "ð٤ĺðŁı»": 46449,
+ "ð٤ĺðŁı»": 30891,
+ "ð٤ĺðŁı¼": 31458,
+ "ð٤ĺðŁı½": 49362,
+ "ð٤Ļ": 23800,
+ "ð٤Ļ": 39101,
+ "ð٤Ŀ": 35242,
+ "ð٤ŀ": 29463,
+ "ð٤ŀ": 38597,
+ "ðŁ¤Ł": 48509,
+ "ðŁ¤ł": 36737,
+ "ð٤Ń": 47289,
+ "ðŁ¥": 4156,
+ "ðŁ¥°": 29246,
+ "ðŁ¥°": 17597,
+ "ðŁ¥³": 45823,
+ "ðŁ¥³": 28055,
+ "ðŁ¥º": 43380,
+ "ðŁ¥º": 36858,
+ "ðŁ¥Ĥ": 43805,
+ "ðŁ¥Ĥ": 25212,
+ "ðŁ¥ĥ": 47790,
+ "ðŁ¥ĩ": 34372,
+ "ðŁ¥ĩ": 20069,
+ "ðŁ¥Ī": 35858,
+ "ðŁ¥ī": 36782,
+ "ðŁ¥Ĭ": 29275,
+ "ð٦": 6040,
+ "ð٦ģ": 36367,
+ "ð٦ģ": 26056,
+ "ð٦ĥ": 40184,
+ "ð٦Ħ": 37659,
+ "ð٦ħ": 28800,
+ "ð٦Ī": 48984,
+ "ð٦ĭ": 49325,
+ "ð٦ĭ": 28985,
+ "ð٧": 8792,
+ "ðŁ§¡": 30996,
+ "ðŁ§¡": 24578,
+ "ð٧IJ": 33549,
+ "ðŁħ": 22010,
+ "ðŁĨ": 9536,
+ "ðŁĨķ": 34956,
+ "ðŁĨĺ": 39868,
+ "ðŁĨļ": 16325,
+ "ðŁĩ": 1173,
+ "ðŁĩ¦": 12469,
+ "ðŁĩ¦": 28565,
+ "ðŁĩ¦ðŁĩ": 33196,
+ "ðŁĩ¦ðŁĩ·": 41629,
+ "ðŁĩ¦ðŁĩº": 25192,
+ "ðŁĩ§": 14660,
+ "ðŁĩ§ðŁĩ": 37342,
+ "ðŁĩ§ðŁĩª": 38794,
+ "ðŁĩ§ðŁĩ·": 28182,
+ "ðŁĩ¨": 8889,
+ "ðŁĩ¨ðŁĩ": 8989,
+ "ðŁĩ¨ðŁĩ¦": 34324,
+ "ðŁĩ¨ðŁĩ¦": 16364,
+ "ðŁĩ¨ðŁĩ³": 36819,
+ "ðŁĩ¨ðŁĩŃ": 41119,
+ "ðŁĩ©": 15222,
+ "ðŁĩ©ðŁĩ": 36350,
+ "ðŁĩ©ðŁĩª": 21531,
+ "ðŁĩª": 11428,
+ "ðŁĩª": 12331,
+ "ðŁĩªðŁĩ": 13917,
+ "ðŁĩªðŁĩ¸": 22177,
+ "ðŁĩªðŁĩº": 34655,
+ "ðŁĩ«": 12977,
+ "ðŁĩ«ðŁĩ·": 39109,
+ "ðŁĩ«ðŁĩ·": 16223,
+ "ðŁĩ¬": 8129,
+ "ðŁĩ¬ðŁĩ": 8354,
+ "ðŁĩ¬ðŁĩ§": 23762,
+ "ðŁĩ¬ðŁĩ§": 11559,
+ "ðŁĩ®": 8268,
+ "ðŁĩ®ðŁĩ": 8347,
+ "ðŁĩ®ðŁĩª": 34148,
+ "ðŁĩ®ðŁĩ³": 47299,
+ "ðŁĩ®ðŁĩ³": 23602,
+ "ðŁĩ®ðŁĩ¹": 42034,
+ "ðŁĩ®ðŁĩ¹": 17070,
+ "ðŁĩ¯": 20090,
+ "ðŁĩ¯ðŁĩ": 22924,
+ "ðŁĩ¯ðŁĩµ": 26527,
+ "ðŁĩ°": 28232,
+ "ðŁĩ±": 29533,
+ "ðŁĩ±ðŁĩ": 40941,
+ "ðŁĩ²": 16411,
+ "ðŁĩ²ðŁĩ": 17562,
+ "ðŁĩ²ðŁĩ½": 32073,
+ "ðŁĩ³": 16645,
+ "ðŁĩ³ðŁĩ": 17747,
+ "ðŁĩ³ðŁĩ±": 36747,
+ "ðŁĩµ": 12127,
+ "ðŁĩµðŁĩ": 13608,
+ "ðŁĩµðŁĩ°": 37764,
+ "ðŁĩµðŁĩ¹": 42621,
+ "ðŁĩµðŁĩŃ": 42777,
+ "ðŁĩ·": 16026,
+ "ðŁĩ·": 9869,
+ "ðŁĩ·ðŁĩº": 37902,
+ "ðŁĩ¸": 19447,
+ "ðŁĩ¸ðŁĩ": 33325,
+ "ðŁĩ¸ðŁĩª": 39260,
+ "ðŁĩ¹": 21810,
+ "ðŁĩ¹ðŁĩ": 36250,
+ "ðŁĩº": 4054,
+ "ðŁĩº": 17467,
+ "ðŁĩºðŁĩ": 4131,
+ "ðŁĩºðŁĩ¸": 8907,
+ "ðŁĩºðŁĩ¸": 5688,
+ "ðŁĩºðŁĩ¸ðŁĩºðŁĩ¸": 18739,
+ "ðŁĩºðŁĩ¸ðŁĩºðŁĩ¸": 41411,
+ "ðŁĩºðŁĩ¸ðŁĩºðŁĩ¸ðŁĩºðŁĩ¸": 43357,
+ "ðŁĩ¿": 25520,
+ "ðŁĩ¿ðŁĩ¦": 36982,
+ "ðŁĩŃ": 30370,
+ "ðŁĮ": 1576,
+ "ðŁĮ±": 35318,
+ "ðŁĮ±": 20665,
+ "ðŁĮ²": 34071,
+ "ðŁĮ²": 28154,
+ "ðŁĮ³": 44265,
+ "ðŁĮ³": 28543,
+ "ðŁĮ´": 20643,
+ "ðŁĮ´": 15968,
+ "ðŁĮµ": 40871,
+ "ðŁĮ·": 32328,
+ "ðŁĮ·": 24259,
+ "ðŁĮ¸": 16314,
+ "ðŁĮ¸": 10980,
+ "ðŁĮ¸ðŁĮ¸": 46210,
+ "ðŁĮ¹": 14990,
+ "ðŁĮ¹": 10662,
+ "ðŁĮ¹ðŁĮ¹": 37933,
+ "ðŁĮº": 27608,
+ "ðŁĮº": 19829,
+ "ðŁĮ»": 27196,
+ "ðŁĮ»": 19772,
+ "ðŁĮ¼": 36484,
+ "ðŁĮ¼": 26312,
+ "ðŁĮ¾": 39796,
+ "ðŁĮ¿": 27736,
+ "ðŁĮ¿": 18588,
+ "ðŁĮĢ": 34348,
+ "ðŁĮħ": 27547,
+ "ðŁĮĪ": 23038,
+ "ðŁĮĪ": 13042,
+ "ðŁĮĬ": 20465,
+ "ðŁĮĬ": 14302,
+ "ðŁĮĮ": 43393,
+ "ðŁĮį": 34931,
+ "ðŁĮį": 18641,
+ "ðŁĮİ": 31125,
+ "ðŁĮİ": 16969,
+ "ðŁĮı": 31527,
+ "ðŁĮIJ": 33071,
+ "ðŁĮĻ": 42330,
+ "ðŁĮĻ": 23283,
+ "ðŁĮļ": 49004,
+ "ðŁĮļ": 27877,
+ "ðŁĮŀ": 21152,
+ "ðŁĮŀ": 12980,
+ "ðŁĮŁ": 13196,
+ "ðŁĮŁ": 8542,
+ "ðŁĮŁðŁĮŁ": 26014,
+ "ðŁį": 2011,
+ "ðŁį¦": 47375,
+ "ðŁį¦": 32032,
+ "ðŁį©": 38379,
+ "ðŁįª": 38958,
+ "ðŁį«": 47994,
+ "ðŁį«": 33401,
+ "ðŁį°": 43732,
+ "ðŁį°": 30051,
+ "ðŁį³": 37441,
+ "ðŁį´": 41531,
+ "ðŁį´": 25338,
+ "ðŁį·": 24445,
+ "ðŁį·": 18072,
+ "ðŁį¸": 43058,
+ "ðŁį¸": 31217,
+ "ðŁį¹": 35598,
+ "ðŁįº": 31081,
+ "ðŁįº": 21590,
+ "ðŁį»": 22793,
+ "ðŁį»": 13167,
+ "ðŁį¾": 27294,
+ "ðŁį¾": 21656,
+ "ðŁįĢ": 22865,
+ "ðŁįĢ": 15764,
+ "ðŁįģ": 29837,
+ "ðŁįģ": 23075,
+ "ðŁįĤ": 35015,
+ "ðŁįĤ": 25721,
+ "ðŁįĥ": 27157,
+ "ðŁįĥ": 20147,
+ "ðŁįĩ": 48697,
+ "ðŁįĬ": 35001,
+ "ðŁįĬ": 28036,
+ "ðŁįĭ": 39543,
+ "ðŁįĮ": 44987,
+ "ðŁįį": 48946,
+ "ðŁįİ": 32069,
+ "ðŁįij": 32889,
+ "ðŁįĴ": 33160,
+ "ðŁįĵ": 44739,
+ "ðŁįĵ": 33456,
+ "ðŁįĶ": 46415,
+ "ðŁįĶ": 36031,
+ "ðŁįķ": 31469,
+ "ðŁįķ": 23904,
+ "ðŁįŃ": 42100,
+ "ðŁİ": 1165,
+ "ðŁİ£": 43158,
+ "ðŁİ¤": 23490,
+ "ðŁİ¤": 15690,
+ "ðŁİ¥": 22186,
+ "ðŁİ¥:": 43640,
+ "ðŁİ¥": 13233,
+ "ðŁİ§": 31254,
+ "ðŁİ§": 14266,
+ "ðŁİ¨": 31953,
+ "ðŁİ¨": 13461,
+ "ðŁİ©": 37701,
+ "ðŁİ«": 30331,
+ "ðŁİ¬": 36020,
+ "ðŁİ¬": 18150,
+ "ðŁİ®": 29312,
+ "ðŁİ¯": 23114,
+ "ðŁİµ": 27435,
+ "ðŁİµ": 14946,
+ "ðŁİ¶": 11755,
+ "ðŁİ¶": 6011,
+ "ðŁİ¶ðŁİ¶": 36283,
+ "ðŁİ¸": 29135,
+ "ðŁİ¸": 22122,
+ "ðŁİ¹": 43493,
+ "ðŁİ¼": 34949,
+ "ðŁİ¼": 23757,
+ "ðŁİ¾": 41982,
+ "ðŁİ¾": 24222,
+ "ðŁİĢ": 34347,
+ "ðŁİĢ": 20151,
+ "ðŁİģ": 18368,
+ "ðŁİģ": 13462,
+ "ðŁİĤ": 13026,
+ "ðŁİĤ": 10392,
+ "ðŁİĤðŁİĤ": 39338,
+ "ðŁİĥ": 22622,
+ "ðŁİĥ": 16780,
+ "ðŁİĦ": 12942,
+ "ðŁİĦ": 11267,
+ "ðŁİħ": 17685,
+ "ðŁİħ": 24276,
+ "ðŁİĨ": 39222,
+ "ðŁİĪ": 16142,
+ "ðŁİĪ": 14448,
+ "ðŁİĪðŁİī": 48049,
+ "ðŁİī": 4310,
+ "ðŁİī:": 17310,
+ "ðŁİī": 3986,
+ "ðŁİīðŁİ": 11473,
+ "ðŁİīðŁİĪ": 40499,
+ "ðŁİīðŁİĪ": 34008,
+ "ðŁİīðŁİī": 25159,
+ "ðŁİīðŁİī": 13450,
+ "ðŁİīðŁİīðŁİī": 20828,
+ "ðŁİīðŁİĬ": 31662,
+ "ðŁİīðŁİĬ": 30781,
+ "ðŁİĬ": 22763,
+ "ðŁİĬ": 22425,
+ "ðŁİĬðŁİī": 48801,
+ "ðŁİĵ": 28916,
+ "ðŁİĵ": 18744,
+ "ðŁİĻ": 29001,
+ "ðŁİĻ": 29753,
+ "ðŁİĻï¸ı": 44205,
+ "ðŁİŁ": 19248,
+ "ðŁİŁ": 21107,
+ "ðŁİŁï¸ı": 30243,
+ "ðŁİŃ": 28856,
+ "ðŁı": 1109,
+ "ðŁı¡": 27318,
+ "ðŁı³ï¸ı": 26844,
+ "ðŁı³ï¸ıâĢį": 27093,
+ "ðŁı³ï¸ıâĢįðŁĮĪ": 32610,
+ "ðŁı´": 39690,
+ "ðŁı´": 19704,
+ "ðŁı»": 5042,
+ "ðŁı»": 3702,
+ "ðŁı»âĢį": 46250,
+ "ðŁı»âĢįâĻĢï¸ı": 48391,
+ "ðŁı»âĢįâĻĢï¸ı": 23595,
+ "ðŁı»âĢįâĻĤï¸ı": 30984,
+ "ðŁı¼": 6193,
+ "ðŁı¼": 4027,
+ "ðŁı¼âĢįâĻĢï¸ı": 28955,
+ "ðŁı½": 8514,
+ "ðŁı½": 6114,
+ "ðŁı½âĢįâĻĢï¸ı": 37036,
+ "ðŁı½âĢįâĻĤï¸ı": 43157,
+ "ðŁı¾": 10230,
+ "ðŁı¾": 7778,
+ "ðŁı¾âĢįâĻĤï¸ı": 47189,
+ "ðŁı¿": 29854,
+ "ðŁı¿": 21094,
+ "ðŁıĢ": 13708,
+ "ðŁıĢ": 8813,
+ "ðŁıĢðŁıĢ": 43169,
+ "ðŁıģ": 29423,
+ "ðŁıģ": 17473,
+ "ðŁıĥ": 16820,
+ "ðŁıĥ": 32751,
+ "ðŁıħ": 25500,
+ "ðŁıĨ": 9585,
+ "ðŁıĨ": 5596,
+ "ðŁıĨðŁıĨ": 18946,
+ "ðŁıĨðŁıĨ": 38269,
+ "ðŁıĨðŁıĨðŁıĨ": 44484,
+ "ðŁıĩ": 45789,
+ "ðŁıĩ": 40288,
+ "ðŁıĪ": 16144,
+ "ðŁıĪ": 10477,
+ "ðŁıī": 26020,
+ "ðŁıĬ": 33061,
+ "ðŁıĬ": 47830,
+ "ðŁıĮ": 41116,
+ "ðŁıı": 32460,
+ "ðŁıIJ": 46334,
+ "ðŁıIJ": 29433,
+ "ðŁıĴ": 37756,
+ "ðŁıŁ": 35914,
+ "ðŁıŁ": 26472,
+ "ðŁıŁï¸ı": 42627,
+ "ðŁıł": 33727,
+ "ðŁIJ": 2074,
+ "ðŁIJ¢": 37049,
+ "ðŁIJ£": 39597,
+ "ðŁIJ¥": 42981,
+ "ðŁIJ¦": 37260,
+ "ðŁIJ¬": 44238,
+ "ðŁIJ¯": 34825,
+ "ðŁIJ¯": 26111,
+ "ðŁIJ°": 35378,
+ "ðŁIJ°": 25050,
+ "ðŁIJ±": 35710,
+ "ðŁIJ±": 22979,
+ "ðŁIJ´": 33509,
+ "ðŁIJ¶": 14466,
+ "ðŁIJ¶": 10631,
+ "ðŁIJ·": 38408,
+ "ðŁIJ¸": 45597,
+ "ðŁIJ¸": 40298,
+ "ðŁIJº": 44281,
+ "ðŁIJº": 31445,
+ "ðŁIJ»": 30750,
+ "ðŁIJ»": 25322,
+ "ðŁIJ¼": 46234,
+ "ðŁIJ¾": 16057,
+ "ðŁIJ¾": 11317,
+ "ðŁIJ¾ðŁIJ¾": 42202,
+ "ðŁIJī": 46908,
+ "ðŁIJĬ": 43974,
+ "ðŁIJį": 48903,
+ "ðŁIJį": 30177,
+ "ðŁIJİ": 48281,
+ "ðŁIJİ": 32726,
+ "ðŁIJIJ": 47735,
+ "ðŁIJIJ": 27954,
+ "ðŁIJij": 49389,
+ "ðŁIJķ": 41069,
+ "ðŁIJĺ": 38733,
+ "ðŁIJĿ": 30619,
+ "ðŁIJĿ": 20111,
+ "ðŁIJŁ": 42084,
+ "ðŁIJŁ": 29989,
+ "ðŁIJł": 42725,
+ "ðŁij": 964,
+ "ðŁij£": 39755,
+ "ðŁij§": 48938,
+ "ðŁij¨": 18966,
+ "ðŁij¨âĢį": 25023,
+ "ðŁij©": 18800,
+ "ðŁij©âĢį": 26304,
+ "ðŁij«": 47106,
+ "ðŁij«": 35457,
+ "ðŁij®": 42686,
+ "ðŁij¯": 25910,
+ "ðŁij¯": 20582,
+ "ðŁij¶": 26187,
+ "ðŁij¶": 33189,
+ "ðŁij¸": 26268,
+ "ðŁij¸": 36645,
+ "ðŁij¹": 46766,
+ "ðŁij»": 24625,
+ "ðŁij»": 16243,
+ "ðŁij¼": 25270,
+ "ðŁij¼": 31083,
+ "ðŁij½": 42677,
+ "ðŁij½": 26257,
+ "ðŁijĢ": 11524,
+ "ðŁijĢ": 5908,
+ "ðŁijĢðŁijĢ": 31561,
+ "ðŁijģ": 47796,
+ "ðŁijģ": 45705,
+ "ðŁijĦ": 47445,
+ "ðŁijħ": 31833,
+ "ðŁijħ": 24672,
+ "ðŁijĨ": 42975,
+ "ðŁijĨ": 45194,
+ "ðŁijĩ": 7662,
+ "ðŁijĩ": 7475,
+ "ðŁijĩðŁı»": 45811,
+ "ðŁijĩðŁı»": 32813,
+ "ðŁijĩðŁı¼": 37504,
+ "ðŁijĩðŁijĩ": 17915,
+ "ðŁijĩðŁijĩ": 31891,
+ "ðŁijĩðŁijĩðŁijĩ": 35627,
+ "ðŁijĪ": 32794,
+ "ðŁijĪ": 20832,
+ "ðŁijī": 9477,
+ "ðŁijī": 3988,
+ "ðŁijīðŁı»": 23481,
+ "ðŁijīðŁı¼": 27534,
+ "ðŁijīðŁı½": 38059,
+ "ðŁijīðŁijī": 41480,
+ "ðŁijĬ": 8897,
+ "ðŁijĬ": 9704,
+ "ðŁijĬðŁı»": 47393,
+ "ðŁijĬðŁı»": 29152,
+ "ðŁijĬðŁı¼": 49000,
+ "ðŁijĬðŁı¼": 30115,
+ "ðŁijĬðŁijĬ": 46521,
+ "ðŁijĭ": 19351,
+ "ðŁijĭ": 17686,
+ "ðŁijĮ": 4890,
+ "ðŁijĮ": 4494,
+ "ðŁijĮðŁı»": 31818,
+ "ðŁijĮðŁı»": 18606,
+ "ðŁijĮðŁı¼": 37655,
+ "ðŁijĮðŁı¼": 20031,
+ "ðŁijĮðŁı½": 35834,
+ "ðŁijĮðŁijĮ": 36139,
+ "ðŁijĮðŁijĮ": 21435,
+ "ðŁijĮðŁijĮðŁijĮ": 40876,
+ "ðŁijį": 4686,
+ "ðŁijį": 4201,
+ "ðŁijįðŁı»": 25803,
+ "ðŁijįðŁı»": 15129,
+ "ðŁijįðŁı¼": 37285,
+ "ðŁijįðŁı¼": 19689,
+ "ðŁijįðŁı½": 43722,
+ "ðŁijįðŁijį": 33012,
+ "ðŁijįðŁijį": 18997,
+ "ðŁijįðŁijįðŁijį": 37284,
+ "ðŁijİ": 39702,
+ "ðŁijİ": 32568,
+ "ðŁijı": 3802,
+ "ðŁijı": 4829,
+ "ðŁijıðŁı»": 19236,
+ "ðŁijıðŁı»": 17029,
+ "ðŁijıðŁı»ðŁijıðŁı»": 35254,
+ "ðŁijıðŁı¼": 24496,
+ "ðŁijıðŁı¼": 19979,
+ "ðŁijıðŁı¼ðŁijıðŁı¼": 46712,
+ "ðŁijıðŁı½": 40796,
+ "ðŁijıðŁı½": 33978,
+ "ðŁijıðŁı¾": 45450,
+ "ðŁijıðŁijı": 10356,
+ "ðŁijıðŁijı": 16706,
+ "ðŁijıðŁijıðŁijı": 17254,
+ "ðŁijIJ": 40877,
+ "ðŁijij": 14955,
+ "ðŁijij": 8717,
+ "ðŁijijðŁijij": 48532,
+ "ðŁijķ": 47865,
+ "ðŁijŁ": 41183,
+ "ðŁijł": 41264,
+ "ðŁijŃ": 34175,
+ "ðŁijŃ": 27943,
+ "ðŁĴ": 837,
+ "ðŁĴ¡": 24081,
+ "ðŁĴ£": 36862,
+ "ðŁĴ£": 29006,
+ "ðŁĴ¤": 34706,
+ "ðŁĴ¤": 25632,
+ "ðŁĴ¥": 12209,
+ "ðŁĴ¥": 7347,
+ "ðŁĴ¥ðŁĴ¥": 27396,
+ "ðŁĴ¥ðŁĴ¥": 39246,
+ "ðŁĴ¥ðŁĴ¥ðŁĴ¥": 48890,
+ "ðŁĴ¦": 21180,
+ "ðŁĴ¦": 14060,
+ "ðŁĴ¦ðŁĴ¦": 44469,
+ "ðŁĴ§": 34095,
+ "ðŁĴ¨": 27408,
+ "ðŁĴ¨": 17891,
+ "ðŁĴ©": 48621,
+ "ðŁĴ©": 28847,
+ "ðŁĴª": 5475,
+ "ðŁĴª": 6440,
+ "ðŁĴªðŁı»": 31669,
+ "ðŁĴªðŁı»": 21903,
+ "ðŁĴªðŁı¼": 32041,
+ "ðŁĴªðŁı¼": 20759,
+ "ðŁĴªðŁı½": 46380,
+ "ðŁĴªðŁı½": 31111,
+ "ðŁĴªðŁı¾": 39398,
+ "ðŁĴªðŁĴª": 24747,
+ "ðŁĴªðŁĴªðŁĴª": 39913,
+ "ðŁĴ«": 25770,
+ "ðŁĴ«": 12526,
+ "ðŁĴ¬": 30947,
+ "ðŁĴ¯": 10611,
+ "ðŁĴ¯": 7018,
+ "ðŁĴ¯ðŁĴ¯": 30234,
+ "ðŁĴ¯ðŁĴ¯": 44070,
+ "ðŁĴ°": 20454,
+ "ðŁĴ°": 14078,
+ "ðŁĴ°ðŁĴ°": 41747,
+ "ðŁĴµ": 47412,
+ "ðŁĴµ": 38041,
+ "ðŁĴ¸": 37696,
+ "ðŁĴ¸": 25957,
+ "ðŁĴ»": 33433,
+ "ðŁĴ»": 18135,
+ "ðŁĴ¿": 39541,
+ "ðŁĴĢ": 14888,
+ "ðŁĴĢ": 12158,
+ "ðŁĴĢðŁĴĢ": 30884,
+ "ðŁĴģ": 13997,
+ "ðŁĴģ": 14392,
+ "ðŁĴĥ": 9947,
+ "ðŁĴĥ": 14333,
+ "ðŁĴĥðŁı»": 38624,
+ "ðŁĴĥðŁĴĥ": 28041,
+ "ðŁĴĦ": 46116,
+ "ðŁĴĦ": 34571,
+ "ðŁĴħ": 27457,
+ "ðŁĴħ": 32414,
+ "ðŁĴī": 44316,
+ "ðŁĴī": 30503,
+ "ðŁĴĭ": 12217,
+ "ðŁĴĭ": 7417,
+ "ðŁĴĭðŁĴĭ": 29214,
+ "ðŁĴĮ": 40817,
+ "ðŁĴį": 35850,
+ "ðŁĴį": 24898,
+ "ðŁĴİ": 25938,
+ "ðŁĴİ": 15874,
+ "ðŁĴIJ": 27375,
+ "ðŁĴIJ": 20554,
+ "ðŁĴij": 49404,
+ "ðŁĴĵ": 20628,
+ "ðŁĴĵ": 12568,
+ "ðŁĴĵðŁĴĵ": 43505,
+ "ðŁĴĶ": 18880,
+ "ðŁĴĶ": 10704,
+ "ðŁĴĶðŁĴĶ": 44673,
+ "ðŁĴķ": 5412,
+ "ðŁĴķ": 3082,
+ "ðŁĴķðŁĴķ": 23106,
+ "ðŁĴķðŁĴķ": 14117,
+ "ðŁĴķðŁĴķðŁĴķ": 26772,
+ "ðŁĴĸ": 8466,
+ "ðŁĴĸ": 5582,
+ "ðŁĴĸðŁĴĸ": 19562,
+ "ðŁĴĸðŁĴĸ": 30595,
+ "ðŁĴĸðŁĴĸðŁĴĸ": 33915,
+ "ðŁĴĹ": 10148,
+ "ðŁĴĹ": 6690,
+ "ðŁĴĹðŁĴĹ": 47158,
+ "ðŁĴĹðŁĴĹ": 24064,
+ "ðŁĴĹðŁĴĹðŁĴĹ": 36990,
+ "ðŁĴĺ": 18223,
+ "ðŁĴĺ": 10816,
+ "ðŁĴĺðŁĴĺ": 40464,
+ "ðŁĴĻ": 5305,
+ "ðŁĴĻ": 4074,
+ "ðŁĴĻðŁĴĻ": 17833,
+ "ðŁĴĻðŁĴĻ": 27101,
+ "ðŁĴĻðŁĴĻðŁĴĻ": 30698,
+ "ðŁĴĻðŁĴĽ": 46804,
+ "ðŁĴĻðŁĴĽ": 26230,
+ "ðŁĴĻðŁĴľ": 47931,
+ "ðŁĴĻðŁĴľ": 42541,
+ "ðŁĴļ": 8102,
+ "ðŁĴļ": 6521,
+ "ðŁĴļðŁĴļ": 27497,
+ "ðŁĴļðŁĴļ": 46209,
+ "ðŁĴļðŁĴļðŁĴļ": 46182,
+ "ðŁĴļðŁĴĽ": 41232,
+ "ðŁĴĽ": 8221,
+ "ðŁĴĽ": 6233,
+ "ðŁĴĽðŁĴĻ": 36337,
+ "ðŁĴĽðŁĴļ": 37994,
+ "ðŁĴĽðŁĴĽ": 32420,
+ "ðŁĴľ": 6832,
+ "ðŁĴľ": 4882,
+ "ðŁĴľðŁĴľ": 17280,
+ "ðŁĴľðŁĴľ": 28211,
+ "ðŁĴľðŁĴľðŁĴľ": 31004,
+ "ðŁĴĿ": 36761,
+ "ðŁĴĿ": 22002,
+ "ðŁĴŀ": 14862,
+ "ðŁĴŀ": 8988,
+ "ðŁĴŀðŁĴŀ": 36448,
+ "ðŁĴŁ": 49394,
+ "ðŁĴŁ": 28828,
+ "ðŁĴŃ": 33848,
+ "ðŁĵ": 1497,
+ "ðŁĵ¢": 46560,
+ "ðŁĵ¢": 20901,
+ "ðŁĵ£": 48841,
+ "ðŁĵ£": 21282,
+ "ðŁĵ°:": 28952,
+ "ðŁĵ°": 14985,
+ "ðŁĵ±": 36104,
+ "ðŁĵ±": 20824,
+ "ðŁĵ²": 19363,
+ "ðŁĵ·": 6966,
+ "ðŁĵ·:": 8294,
+ "ðŁĵ·": 5551,
+ "ðŁĵ·@": 40032,
+ "ðŁĵ¸": 8401,
+ "ðŁĵ¸:": 10379,
+ "ðŁĵ¸": 6074,
+ "ðŁĵ¸@": 39660,
+ "ðŁĵ¹": 49251,
+ "ðŁĵº": 21792,
+ "ðŁĵº:": 29728,
+ "ðŁĵº": 10450,
+ "ðŁĵ»": 32711,
+ "ðŁĵ»": 15882,
+ "ðŁĵ½": 45361,
+ "ðŁĵħ": 21277,
+ "ðŁĵĨ": 23471,
+ "ðŁĵĪ": 23359,
+ "ðŁĵĬ": 22244,
+ "ðŁĵĭ": 46351,
+ "ðŁĵĮ": 22289,
+ "ðŁĵį": 25043,
+ "ðŁĵį:": 36845,
+ "ðŁĵį": 8903,
+ "ðŁĵĸ": 49003,
+ "ðŁĵĸ": 23043,
+ "ðŁĵļ": 25433,
+ "ðŁĵļ": 15566,
+ "ðŁĵĿ": 31888,
+ "ðŁĵĿ:": 48398,
+ "ðŁĵĿ": 15853,
+ "ðŁĵŀ": 24022,
+ "ðŁĶ": 1428,
+ "ðŁĶ¥": 3191,
+ "ðŁĶ¥#": 44354,
+ "ðŁĶ¥": 3016,
+ "ðŁĶ¥ðŁĶ¥": 5692,
+ "ðŁĶ¥ðŁĶ¥": 11771,
+ "ðŁĶ¥ðŁĶ¥ðŁĶ¥": 11004,
+ "ðŁĶ¥ðŁĶ¥ðŁĶ¥ðŁĶ¥": 23408,
+ "ðŁĶ¥ðŁĶ¥ðŁĶ¥ðŁĶ¥": 30989,
+ "ðŁĶ¥ðŁĶ¥ðŁĶ¥ðŁĶ¥ðŁĶ¥": 48401,
+ "ðŁĶ¥ðŁĶĹ": 35130,
+ "ðŁĶª": 47078,
+ "ðŁĶª": 34545,
+ "ðŁĶ«": 38116,
+ "ðŁĶ«": 20583,
+ "ðŁĶ¬": 44227,
+ "ðŁĶ®": 38077,
+ "ðŁĶ´": 12408,
+ "ðŁĶ´": 10854,
+ "ðŁĶ´âļªï¸ı": 46879,
+ "ðŁĶ´âļªï¸ı": 40055,
+ "ðŁĶµ": 17531,
+ "ðŁĶµ": 17193,
+ "ðŁĶµâļªï¸ı": 42412,
+ "ðŁĶ¶": 42880,
+ "ðŁĶ¶": 36222,
+ "ðŁĶ·": 37740,
+ "ðŁĶ¸": 24200,
+ "ðŁĶ¹": 19995,
+ "ðŁĶº": 45561,
+ "ðŁĶģ": 41299,
+ "ðŁĶĬ": 32580,
+ "ðŁĶĬ": 20502,
+ "ðŁĶİ": 44935,
+ "ðŁĶij": 35127,
+ "ðŁĶĴ": 44972,
+ "ðŁĶĶ": 45753,
+ "ðŁĶĹ": 47475,
+ "ðŁĶĹ": 14561,
+ "ðŁĶĺ": 38995,
+ "ðŁĶľ": 36011,
+ "ðŁĶĿ": 44387,
+ "ðŁĶĿ": 29506,
+ "ðŁķ": 7692,
+ "ðŁķº": 33958,
+ "ðŁķĬ": 42624,
+ "ðŁķĬ": 37760,
+ "ðŁĸ": 6269,
+ "ðŁĸ¤": 17603,
+ "ðŁĸ¤": 10860,
+ "ðŁĸ¥": 47990,
+ "ðŁĹ": 7045,
+ "ðŁĹ£": 33232,
+ "ðŁĹ£": 18583,
+ "ðŁĹ£ï¸ı": 37476,
+ "ðŁĹĵ": 34335,
+ "ðŁĹĵ": 28773,
+ "ðŁĹĵï¸ı": 39847,
+ "ðŁĺ": 668,
+ "ðŁĺ¡": 21968,
+ "ðŁĺ¡": 17452,
+ "ðŁĺ¡ðŁĺ¡": 37223,
+ "ðŁĺ¢": 14308,
+ "ðŁĺ¢": 9925,
+ "ðŁĺ¢ðŁĺ¢": 32923,
+ "ðŁĺ¢ðŁĺ¢": 47921,
+ "ðŁĺ£": 32718,
+ "ðŁĺ¤": 26872,
+ "ðŁĺ¤": 20740,
+ "ðŁĺ¥": 38383,
+ "ðŁĺ¥": 23951,
+ "ðŁĺ¨": 38080,
+ "ðŁĺ©": 9051,
+ "ðŁĺ©": 9494,
+ "ðŁĺ©ðŁĺ©": 22820,
+ "ðŁĺ©ðŁĺ©": 38031,
+ "ðŁĺ©ðŁĺ©ðŁĺ©": 49063,
+ "ðŁĺª": 38181,
+ "ðŁĺª": 22243,
+ "ðŁĺ«": 25141,
+ "ðŁĺ«": 22340,
+ "ðŁĺ¬": 23704,
+ "ðŁĺ¬": 14549,
+ "ðŁĺ®": 40163,
+ "ðŁĺ®": 21616,
+ "ðŁĺ¯": 37858,
+ "ðŁĺ°": 34728,
+ "ðŁĺ±": 10938,
+ "ðŁĺ±": 9055,
+ "ðŁĺ±ðŁĺ±": 22061,
+ "ðŁĺ±ðŁĺ±": 40767,
+ "ðŁĺ±ðŁĺ±ðŁĺ±": 40909,
+ "ðŁĺ²": 40460,
+ "ðŁĺ²": 24620,
+ "ðŁĺ³": 12047,
+ "ðŁĺ³": 8223,
+ "ðŁĺ³ðŁĺ³": 32592,
+ "ðŁĺ´": 23527,
+ "ðŁĺ´": 16415,
+ "ðŁĺ´ðŁĺ´": 49307,
+ "ðŁĺµ": 39368,
+ "ðŁĺ¶": 35207,
+ "ðŁĺ·": 37943,
+ "ðŁĺ·": 25759,
+ "ðŁĺ¸": 36912,
+ "ðŁĺ¹": 26477,
+ "ðŁĺ¹": 26573,
+ "ðŁĺ¹ðŁĺ¹": 46287,
+ "ðŁĺº": 40613,
+ "ðŁĺ»": 15453,
+ "ðŁĺ»": 12911,
+ "ðŁĺ»ðŁĺ»": 34414,
+ "ðŁĺ¼": 44245,
+ "ðŁĺ½": 45156,
+ "ðŁĺĢ": 12832,
+ "ðŁĺĢ": 7334,
+ "ðŁĺĢðŁĺĢ": 34503,
+ "ðŁĺģ": 6967,
+ "ðŁĺģ": 4821,
+ "ðŁĺģðŁĺģ": 37900,
+ "ðŁĺģðŁĺģ": 19213,
+ "ðŁĺģðŁĺģðŁĺģ": 29083,
+ "ðŁĺĤ": 1424,
+ "ðŁĺĤ)": 42643,
+ "ðŁĺĤ.": 42550,
+ "ðŁĺĤ": 1558,
+ "ðŁĺĤâĿ¤ï¸ı": 36412,
+ "ðŁĺĤðŁijĮ": 42000,
+ "ðŁĺĤðŁĺĤ": 2286,
+ "ðŁĺĤðŁĺĤ": 4112,
+ "ðŁĺĤðŁĺĤðŁĺĤ": 22233,
+ "ðŁĺĤðŁĺĤðŁĺĤ": 4887,
+ "ðŁĺĤðŁĺĤðŁĺĤðŁĺĤ": 9936,
+ "ðŁĺĤðŁĺĤðŁĺĤðŁĺĤ": 11522,
+ "ðŁĺĤðŁĺĤðŁĺĤðŁĺĤðŁĺĤ": 19295,
+ "ðŁĺĤðŁĺĤðŁĺĤðŁĺĤðŁĺĤðŁĺĤ": 33415,
+ "ðŁĺĤðŁĺĤðŁĺĤðŁĺĤðŁĺĤðŁĺĤðŁĺĤ": 48973,
+ "ðŁĺĤðŁĺĤðŁĺĤðŁĺĤðŁĺĤðŁĺĤðŁĺĤðŁĺĤ": 28504,
+ "ðŁĺĤðŁĺį": 43128,
+ "ðŁĺĤðŁĺŃ": 28965,
+ "ðŁĺĤðŁĺŃ": 25802,
+ "ðŁĺĥ": 14079,
+ "ðŁĺĥ": 8520,
+ "ðŁĺĥðŁĺĥ": 38358,
+ "ðŁĺĦ": 12141,
+ "ðŁĺĦ": 7624,
+ "ðŁĺĦðŁĺĦ": 32312,
+ "ðŁĺħ": 15245,
+ "ðŁĺħ": 9188,
+ "ðŁĺħðŁĺħ": 39078,
+ "ðŁĺĨ": 16541,
+ "ðŁĺĨ": 10943,
+ "ðŁĺĨðŁĺĨ": 39503,
+ "ðŁĺĩ": 21694,
+ "ðŁĺĩ": 13091,
+ "ðŁĺĪ": 14377,
+ "ðŁĺĪ": 9756,
+ "ðŁĺĪðŁĺĪ": 44473,
+ "ðŁĺī": 9740,
+ "ðŁĺī": 4955,
+ "ðŁĺīðŁĺī": 40430,
+ "ðŁĺĬ": 4692,
+ "ðŁĺĬ": 3020,
+ "ðŁĺĬâĿ¤ï¸ı": 43606,
+ "ðŁĺĬðŁĺĬ": 12838,
+ "ðŁĺĬðŁĺĬ": 20842,
+ "ðŁĺĬðŁĺĬðŁĺĬ": 28685,
+ "ðŁĺĬðŁĺĬðŁĺĬðŁĺĬ": 35519,
+ "ðŁĺĭ": 12391,
+ "ðŁĺĭ": 7203,
+ "ðŁĺĭðŁĺĭ": 33304,
+ "ðŁĺĮ": 19221,
+ "ðŁĺĮ": 12163,
+ "ðŁĺį": 1796,
+ "ðŁĺį#": 42357,
+ "ðŁĺį.": 48579,
+ "ðŁĺį": 1754,
+ "ðŁĺįâĿ¤": 29122,
+ "ðŁĺįâĿ¤ï¸ı": 21945,
+ "ðŁĺįðŁijĮ": 41005,
+ "ðŁĺįðŁĴķ": 35946,
+ "ðŁĺįðŁĶ¥": 46648,
+ "ðŁĺįðŁĺĤ": 48715,
+ "ðŁĺįðŁĺį": 3663,
+ "ðŁĺįðŁĺį": 6471,
+ "ðŁĺįðŁĺįðŁĺį": 30614,
+ "ðŁĺįðŁĺįðŁĺį": 7703,
+ "ðŁĺįðŁĺįðŁĺįðŁĺį": 16603,
+ "ðŁĺįðŁĺįðŁĺįðŁĺį": 18925,
+ "ðŁĺįðŁĺįðŁĺįðŁĺįðŁĺį": 32078,
+ "ðŁĺįðŁĺįðŁĺįðŁĺįðŁĺįðŁĺįðŁĺįðŁĺį": 48683,
+ "ðŁĺįðŁĺĺ": 29646,
+ "ðŁĺįðŁĺĺ": 19849,
+ "ðŁĺįðŁĺŃ": 39555,
+ "ðŁĺİ": 7426,
+ "ðŁĺİ": 4345,
+ "ðŁĺİðŁĺİ": 24048,
+ "ðŁĺİðŁĺİðŁĺİ": 39742,
+ "ðŁĺı": 11624,
+ "ðŁĺı": 6909,
+ "ðŁĺıðŁĺı": 38151,
+ "ðŁĺIJ": 38586,
+ "ðŁĺIJ": 19618,
+ "ðŁĺij": 32469,
+ "ðŁĺij": 18937,
+ "ðŁĺĴ": 20792,
+ "ðŁĺĴ": 11702,
+ "ðŁĺĵ": 28733,
+ "ðŁĺĶ": 19532,
+ "ðŁĺĶ": 11432,
+ "ðŁĺķ": 45741,
+ "ðŁĺķ": 20602,
+ "ðŁĺĸ": 35006,
+ "ðŁĺĺ": 4240,
+ "ðŁĺĺ": 3352,
+ "ðŁĺĺâĿ¤": 48409,
+ "ðŁĺĺâĿ¤ï¸ı": 39150,
+ "ðŁĺĺðŁĺį": 38176,
+ "ðŁĺĺðŁĺĺ": 15663,
+ "ðŁĺĺðŁĺĺ": 10507,
+ "ðŁĺĺðŁĺĺðŁĺĺ": 20208,
+ "ðŁĺĺðŁĺĺðŁĺĺðŁĺĺ": 44892,
+ "ðŁĺĻ": 36201,
+ "ðŁĺĻ": 29209,
+ "ðŁĺļ": 24897,
+ "ðŁĺļ": 19102,
+ "ðŁĺĽ": 24550,
+ "ðŁĺĽ": 15745,
+ "ðŁĺľ": 13226,
+ "ðŁĺľ": 7830,
+ "ðŁĺľðŁĺľ": 43065,
+ "ðŁĺĿ": 20064,
+ "ðŁĺĿ": 12970,
+ "ðŁĺŀ": 40458,
+ "ðŁĺŀ": 21103,
+ "ðŁĺŁ": 46947,
+ "ðŁĺł": 34094,
+ "ðŁĺŃ": 2962,
+ "ðŁĺŃ": 3915,
+ "ðŁĺŃâĿ¤ï¸ı": 29567,
+ "ðŁĺŃðŁĴķ": 46306,
+ "ðŁĺŃðŁĺĤ": 38505,
+ "ðŁĺŃðŁĺį": 36893,
+ "ðŁĺŃðŁĺŃ": 5300,
+ "ðŁĺŃðŁĺŃ": 11834,
+ "ðŁĺŃðŁĺŃðŁĺŃ": 44089,
+ "ðŁĺŃðŁĺŃðŁĺŃ": 13116,
+ "ðŁĺŃðŁĺŃðŁĺŃðŁĺŃ": 19793,
+ "ðŁĺŃðŁĺŃðŁĺŃðŁĺŃ": 27322,
+ "ðŁĺŃðŁĺŃðŁĺŃðŁĺŃðŁĺŃ": 43366,
+ "ðŁĻ": 1478,
+ "ðŁĻĢ": 43092,
+ "ðŁĻĤ": 32006,
+ "ðŁĻĤ": 14860,
+ "ðŁĻĥ": 27222,
+ "ðŁĻĥ": 15652,
+ "ðŁĻĦ": 20648,
+ "ðŁĻĦ": 13049,
+ "ðŁĻħ": 42702,
+ "ðŁĻĨ": 30050,
+ "ðŁĻĨ": 35730,
+ "ðŁĻĪ": 12661,
+ "ðŁĻĪ": 9516,
+ "ðŁĻĪðŁĻĪ": 41796,
+ "ðŁĻĬ": 23684,
+ "ðŁĻĬ": 16636,
+ "ðŁĻĭ": 19193,
+ "ðŁĻĭ": 30274,
+ "ðŁĻĮ": 4366,
+ "ðŁĻĮ": 4855,
+ "ðŁĻĮðŁı»": 26756,
+ "ðŁĻĮðŁı»": 15799,
+ "ðŁĻĮðŁı¼": 26584,
+ "ðŁĻĮðŁı¼": 15364,
+ "ðŁĻĮðŁı½": 36660,
+ "ðŁĻĮðŁı½": 22962,
+ "ðŁĻĮðŁı¾": 38023,
+ "ðŁĻĮðŁı¾": 26466,
+ "ðŁĻĮðŁĻĮ": 21202,
+ "ðŁĻĮðŁĻĮ": 30430,
+ "ðŁĻĮðŁĻĮðŁĻĮ": 37127,
+ "ðŁĻı": 4260,
+ "ðŁĻı": 5503,
+ "ðŁĻıðŁı»": 25100,
+ "ðŁĻıðŁı»": 16650,
+ "ðŁĻıðŁı¼": 31163,
+ "ðŁĻıðŁı¼": 18952,
+ "ðŁĻıðŁı½": 34103,
+ "ðŁĻıðŁı½": 21540,
+ "ðŁĻıðŁı¾": 34277,
+ "ðŁĻıðŁı¾": 21979,
+ "ðŁĻıðŁĻı": 18227,
+ "ðŁĻıðŁĻı": 26510,
+ "ðŁĻıðŁĻıðŁĻı": 31702,
+ "ðŁļ": 2730,
+ "ðŁļ¨": 12198,
+ "ðŁļ¨": 6056,
+ "ðŁļ¨ðŁļ¨": 36487,
+ "ðŁļ¨ðŁļ¨": 21440,
+ "ðŁļ¨ðŁļ¨ðŁļ¨": 41515,
+ "ðŁļ©": 44514,
+ "ðŁļ«": 35291,
+ "ðŁļ²": 37085,
+ "ðŁļ´": 30825,
+ "ðŁļ¶": 46060,
+ "ðŁļĢ": 22400,
+ "ðŁļĢ": 13542,
+ "ðŁļĢðŁļĢ": 49033,
+ "ðŁļĤ": 38949,
+ "ðŁļĮ": 46891,
+ "ðŁļĹ": 33054,
+ "ðŁļĹ": 22783,
+ "ðŁļĺ": 35825,
+ "ðŁļĻ": 48487,
+ "ðŁĽ": 11306,
+ "ñ": 173,
+ "ñ": 429,
+ "ò": 174,
+ "ò": 430,
+ "ó": 175,
+ "ó": 431,
+ "ô": 176,
+ "ô": 432,
+ "õ": 177,
+ "õ": 433,
+ "ö": 178,
+ "ö": 434,
+ "÷": 179,
+ "÷": 435,
+ "ø": 180,
+ "ø": 436,
+ "ù": 181,
+ "ù": 437,
+ "ú": 182,
+ "ú": 438,
+ "û": 183,
+ "û": 439,
+ "ü": 184,
+ "ü": 440,
+ "ý": 185,
+ "ý": 441,
+ "þ": 186,
+ "þ": 442,
+ "ÿ": 187,
+ "ÿ": 443,
+ "Ā": 188,
+ "Ā": 444,
+ "ā": 189,
+ "ā": 445,
+ "Ă": 190,
+ "Ă": 446,
+ "ă": 191,
+ "ă": 447,
+ "Ą": 192,
+ "Ą": 448,
+ "ą": 193,
+ "ą": 449,
+ "Ć": 194,
+ "Ć": 450,
+ "ć": 195,
+ "ć": 451,
+ "Ĉ": 196,
+ "Ĉ": 452,
+ "ĉ": 197,
+ "ĉ": 453,
+ "Ċ": 198,
+ "Ċ": 454,
+ "ċ": 199,
+ "ċ": 455,
+ "Č": 200,
+ "Č": 456,
+ "č": 201,
+ "č": 457,
+ "Ď": 202,
+ "Ď": 458,
+ "ď": 203,
+ "ď": 459,
+ "Đ": 204,
+ "Đ": 460,
+ "đ": 205,
+ "đ": 461,
+ "Ē": 206,
+ "Ē": 462,
+ "ē": 207,
+ "ē": 463,
+ "Ĕ": 208,
+ "Ĕ": 464,
+ "ĕ": 209,
+ "ĕ": 465,
+ "Ė": 210,
+ "Ė": 466,
+ "ė": 211,
+ "ė": 467,
+ "Ę": 212,
+ "Ę": 468,
+ "ę": 213,
+ "ę": 469,
+ "Ě": 214,
+ "Ě": 470,
+ "ě": 215,
+ "ě": 471,
+ "Ĝ": 216,
+ "Ĝ": 472,
+ "ĝ": 217,
+ "ĝ": 473,
+ "Ğ": 218,
+ "Ğ": 474,
+ "ğ": 219,
+ "ğ": 475,
+ "Ġ": 220,
+ "Ġ": 476,
+ "ġ": 221,
+ "ġ": 477,
+ "Ģ": 222,
+ "Ģ": 478,
+ "Ģï¸ı": 9668,
+ "Ģï¸ı": 5511,
+ "ģ": 223,
+ "ģ": 479,
+ "ģà¸": 15016,
+ "Ĥ": 224,
+ "Ĥ": 480,
+ "Ĥâĸ": 29036,
+ "ĤâĸĤâĸ": 30832,
+ "ĥ": 225,
+ "ĥ": 481,
+ "Ħ": 226,
+ "Ħ": 482,
+ "Ħà¸": 20537,
+ "Ħë": 34462,
+ "Ħëĭ": 25170,
+ "ħ": 227,
+ "ħ": 483,
+ "ħï¸ı": 33950,
+ "Ĩ": 228,
+ "Ĩ": 484,
+ "ĩ": 229,
+ "ĩ": 485,
+ "Ī": 230,
+ "Ī": 486,
+ "ī": 231,
+ "ī": 487,
+ "īï¸ı": 37463,
+ "Ĭ": 232,
+ "Ĭ": 488,
+ "Ĭãģ": 30294,
+ "ĭ": 233,
+ "ĭ": 489,
+ "ĭãģ": 36218,
+ "ĭãĤ": 45737,
+ "Į": 234,
+ "Į": 490,
+ "ĮãĤĬãģ": 45969,
+ "ĮãĤĬãģŁãģĦ": 47021,
+ "Įë": 17003,
+ "į": 235,
+ "į": 491,
+ "İ": 236,
+ "İ": 492,
+ "ı": 237,
+ "ı": 493,
+ "IJ": 238,
+ "IJ": 494,
+ "ij": 239,
+ "ij": 495,
+ "Ĵ": 240,
+ "Ĵ": 496,
+ "ĵ": 241,
+ "ĵ": 497,
+ "Ķ": 242,
+ "Ķ": 498,
+ "Ķë": 37978,
+ "Ķï¸ı": 24395,
+ "Ķï¸ı": 7443,
+ "ķ": 243,
+ "ķ": 499,
+ "ķãĤ": 26609,
+ "ķï¸ı": 44853,
+ "ĸ": 244,
+ "ĸ": 500,
+ "ĸï¸ı": 28877,
+ "Ĺ": 245,
+ "Ĺ": 501,
+ "ĺ": 246,
+ "ĺ": 502,
+ "Ļ": 247,
+ "Ļ": 503,
+ "ļ": 248,
+ "ļ": 504,
+ "Ľ": 249,
+ "Ľ": 505,
+ "ľ": 250,
+ "ľ": 506,
+ "ľë": 39810,
+ "Ŀ": 251,
+ "Ŀ": 507,
+ "ŀ": 252,
+ "ŀ": 508,
+ "Ł": 253,
+ "Ł": 509,
+ "ŁãģĦ": 46023,
+ "ł": 254,
+ "ł": 510,
+ "łï¸ı": 27899,
+ "łï¸ı": 12715,
+ "łĪ": 43364,
+ "Ń": 255,
+ "Ń": 511
+}
diff --git a/ComfyUI/comfy/sdxl_clip.py b/ComfyUI/comfy/sdxl_clip.py
new file mode 100644
index 0000000000000000000000000000000000000000..c8cef14e4d6f81eb8ec8f4b8825c8afaa1d5caf3
--- /dev/null
+++ b/ComfyUI/comfy/sdxl_clip.py
@@ -0,0 +1,95 @@
+from comfy import sd1_clip
+import torch
+import os
+
+class SDXLClipG(sd1_clip.SDClipModel):
+ def __init__(self, device="cpu", max_length=77, freeze=True, layer="penultimate", layer_idx=None, dtype=None, model_options={}):
+ if layer == "penultimate":
+ layer="hidden"
+ layer_idx=-2
+
+ textmodel_json_config = os.path.join(os.path.dirname(os.path.realpath(__file__)), "clip_config_bigg.json")
+ model_options = {**model_options, "model_name": "clip_g"}
+ super().__init__(device=device, freeze=freeze, layer=layer, layer_idx=layer_idx, textmodel_json_config=textmodel_json_config, dtype=dtype,
+ special_tokens={"start": 49406, "end": 49407, "pad": 0}, layer_norm_hidden_state=False, return_projected_pooled=True, model_options=model_options)
+
+ def load_sd(self, sd):
+ return super().load_sd(sd)
+
+class SDXLClipGTokenizer(sd1_clip.SDTokenizer):
+ def __init__(self, tokenizer_path=None, embedding_directory=None, tokenizer_data={}):
+ super().__init__(tokenizer_path, pad_with_end=False, embedding_directory=embedding_directory, embedding_size=1280, embedding_key='clip_g', tokenizer_data=tokenizer_data)
+
+
+class SDXLTokenizer:
+ def __init__(self, embedding_directory=None, tokenizer_data={}):
+ self.clip_l = sd1_clip.SDTokenizer(embedding_directory=embedding_directory, tokenizer_data=tokenizer_data)
+ self.clip_g = SDXLClipGTokenizer(embedding_directory=embedding_directory, tokenizer_data=tokenizer_data)
+
+ def tokenize_with_weights(self, text:str, return_word_ids=False, **kwargs):
+ out = {}
+ out["g"] = self.clip_g.tokenize_with_weights(text, return_word_ids, **kwargs)
+ out["l"] = self.clip_l.tokenize_with_weights(text, return_word_ids, **kwargs)
+ return out
+
+ def untokenize(self, token_weight_pair):
+ return self.clip_g.untokenize(token_weight_pair)
+
+ def state_dict(self):
+ return {}
+
+class SDXLClipModel(torch.nn.Module):
+ def __init__(self, device="cpu", dtype=None, model_options={}):
+ super().__init__()
+ self.clip_l = sd1_clip.SDClipModel(layer="hidden", layer_idx=-2, device=device, dtype=dtype, layer_norm_hidden_state=False, model_options=model_options)
+ self.clip_g = SDXLClipG(device=device, dtype=dtype, model_options=model_options)
+ self.dtypes = set([dtype])
+
+ def set_clip_options(self, options):
+ self.clip_l.set_clip_options(options)
+ self.clip_g.set_clip_options(options)
+
+ def reset_clip_options(self):
+ self.clip_g.reset_clip_options()
+ self.clip_l.reset_clip_options()
+
+ def encode_token_weights(self, token_weight_pairs):
+ token_weight_pairs_g = token_weight_pairs["g"]
+ token_weight_pairs_l = token_weight_pairs["l"]
+ g_out, g_pooled = self.clip_g.encode_token_weights(token_weight_pairs_g)
+ l_out, l_pooled = self.clip_l.encode_token_weights(token_weight_pairs_l)
+ cut_to = min(l_out.shape[1], g_out.shape[1])
+ return torch.cat([l_out[:,:cut_to], g_out[:,:cut_to]], dim=-1), g_pooled
+
+ def load_sd(self, sd):
+ if "text_model.encoder.layers.30.mlp.fc1.weight" in sd:
+ return self.clip_g.load_sd(sd)
+ else:
+ return self.clip_l.load_sd(sd)
+
+class SDXLRefinerClipModel(sd1_clip.SD1ClipModel):
+ def __init__(self, device="cpu", dtype=None, model_options={}):
+ super().__init__(device=device, dtype=dtype, clip_name="g", clip_model=SDXLClipG, model_options=model_options)
+
+
+class StableCascadeClipGTokenizer(sd1_clip.SDTokenizer):
+ def __init__(self, tokenizer_path=None, embedding_directory=None, tokenizer_data={}):
+ super().__init__(tokenizer_path, pad_with_end=True, embedding_directory=embedding_directory, embedding_size=1280, embedding_key='clip_g', tokenizer_data=tokenizer_data)
+
+class StableCascadeTokenizer(sd1_clip.SD1Tokenizer):
+ def __init__(self, embedding_directory=None, tokenizer_data={}):
+ super().__init__(embedding_directory=embedding_directory, tokenizer_data=tokenizer_data, clip_name="g", tokenizer=StableCascadeClipGTokenizer)
+
+class StableCascadeClipG(sd1_clip.SDClipModel):
+ def __init__(self, device="cpu", max_length=77, freeze=True, layer="hidden", layer_idx=-1, dtype=None, model_options={}):
+ textmodel_json_config = os.path.join(os.path.dirname(os.path.realpath(__file__)), "clip_config_bigg.json")
+ model_options = {**model_options, "model_name": "clip_g"}
+ super().__init__(device=device, freeze=freeze, layer=layer, layer_idx=layer_idx, textmodel_json_config=textmodel_json_config, dtype=dtype,
+ special_tokens={"start": 49406, "end": 49407, "pad": 49407}, layer_norm_hidden_state=False, enable_attention_masks=True, return_projected_pooled=True, model_options=model_options)
+
+ def load_sd(self, sd):
+ return super().load_sd(sd)
+
+class StableCascadeClipModel(sd1_clip.SD1ClipModel):
+ def __init__(self, device="cpu", dtype=None, model_options={}):
+ super().__init__(device=device, dtype=dtype, clip_name="g", clip_model=StableCascadeClipG, model_options=model_options)