Spaces:
Running on Zero
Running on Zero
| import torch | |
| def apply_framepack_token_weights( | |
| x: torch.Tensor, | |
| num_context_frames: int, | |
| f: int, | |
| h: int, | |
| w: int, | |
| context_position: str = "prefix", | |
| use_framepack_memory: bool = False, | |
| context_temporal_decay: float = 1.0, | |
| context_attention_weight: float = 1.0, | |
| ): | |
| if x is None or x.ndim != 3: | |
| return x | |
| if not use_framepack_memory or int(num_context_frames) <= 0: | |
| return x | |
| b, n, d = x.shape | |
| f = int(f) | |
| if f <= 0 or n != f * int(h) * int(w): | |
| return x | |
| hw = int(h) * int(w) | |
| x4 = x.reshape(b, f, hw, d) | |
| k = min(int(num_context_frames), f) | |
| decay = float(context_temporal_decay) | |
| gain = float(context_attention_weight) | |
| if context_position == "suffix": | |
| ctx_start = f - k | |
| ctx_end = f | |
| # Suffix: first context frame is nearest boundary to target. | |
| distances = torch.arange(k, device=x.device, dtype=x.dtype) | |
| else: | |
| ctx_start = 0 | |
| ctx_end = k | |
| # Prefix: last context frame is nearest boundary to target. | |
| distances = torch.arange(k - 1, -1, -1, device=x.device, dtype=x.dtype) | |
| weights = gain * torch.pow(torch.tensor(decay, device=x.device, dtype=x.dtype), distances) | |
| x4[:, ctx_start:ctx_end, :, :] = x4[:, ctx_start:ctx_end, :, :] * weights.view(1, k, 1, 1) | |
| return x4.reshape(b, n, d) | |