Download models/kandinsky5/kandinsky/magcache_utils.py from 1ripon1/ColabWan: direct link, hf CLI and curl.
- Browser
- Download file 13.7 kB
-
https://huggingface.co/spaces/1ripon1/ColabWan/resolve/main/models/kandinsky5/kandinsky/magcache_utils.py
- Command line
-
hf download hf://spaces/1ripon1/ColabWan/models/kandinsky5/kandinsky/magcache_utils.py
-
curl -L -o magcache_utils.py https://huggingface.co/spaces/1ripon1/ColabWan/resolve/main/models/kandinsky5/kandinsky/magcache_utils.py
13.7 kB
| # This is an adaptation of Magcache from https://github.com/Zehong-Ma/MagCache/ | |
| import numpy as np | |
| import torch | |
| from types import MethodType | |
| def nearest_interp(src_array, target_length): | |
| src_length = len(src_array) | |
| if target_length == 1: | |
| return np.array([src_array[-1]]) | |
| scale = (src_length - 1) / (target_length - 1) | |
| mapped_indices = np.round(np.arange(target_length) * scale).astype(int) | |
| return src_array[mapped_indices] | |
| def _prepare_mag_ratios(mag_ratios, num_steps): | |
| if mag_ratios is None: | |
| return None | |
| mag_ratios = np.array([1.0] * 2 + list(mag_ratios)) | |
| if len(mag_ratios) != num_steps * 2: | |
| mag_ratio_con = nearest_interp(mag_ratios[0::2], num_steps) | |
| mag_ratio_ucon = nearest_interp(mag_ratios[1::2], num_steps) | |
| mag_ratios = np.concatenate( | |
| [mag_ratio_con.reshape(-1, 1), mag_ratio_ucon.reshape(-1, 1)], axis=1 | |
| ).reshape(-1) | |
| return mag_ratios | |
| def compute_magcache_threshold( | |
| mag_ratios, | |
| num_steps, | |
| speed_factor, | |
| start_step=0, | |
| no_cfg=False, | |
| magcache_K=2, | |
| retention_ratio=0.2, | |
| ): | |
| if mag_ratios is None or num_steps <= 0 or speed_factor is None or speed_factor <= 0: | |
| return None | |
| mag_ratios = _prepare_mag_ratios(mag_ratios, num_steps) | |
| if mag_ratios is None: | |
| return None | |
| total_calls = num_steps if no_cfg else num_steps * 2 | |
| target_calls = max(1, int(total_calls / max(speed_factor, 1e-6))) | |
| retention_cnt = int(num_steps * 2 * retention_ratio) | |
| best_threshold = 0.01 | |
| best_diff = float("inf") | |
| best_signed_diff = 0 | |
| threshold = 0.01 | |
| while threshold <= 0.6: | |
| nb_calls = 0 | |
| accumulated_err = [0.0, 0.0] | |
| accumulated_steps = [0, 0] | |
| accumulated_ratio = [1.0, 1.0] | |
| for i in range(total_calls): | |
| cnt = i * 2 if no_cfg else i | |
| step_no = cnt // 2 | |
| skip_forward = False | |
| if cnt >= retention_cnt and (start_step is None or step_no > start_step): | |
| stream = cnt % 2 | |
| cur_mag_ratio = mag_ratios[cnt] | |
| accumulated_ratio[stream] *= cur_mag_ratio | |
| accumulated_steps[stream] += 1 | |
| cur_skip_err = np.abs(1 - accumulated_ratio[stream]) | |
| accumulated_err[stream] += cur_skip_err | |
| if accumulated_err[stream] < threshold and accumulated_steps[stream] <= magcache_K: | |
| skip_forward = True | |
| else: | |
| accumulated_err[stream] = 0.0 | |
| accumulated_steps[stream] = 0 | |
| accumulated_ratio[stream] = 1.0 | |
| if not skip_forward: | |
| nb_calls += 1 | |
| signed_diff = target_calls - nb_calls | |
| diff = abs(signed_diff) | |
| if diff < best_diff: | |
| best_threshold = threshold | |
| best_diff = diff | |
| best_signed_diff = signed_diff | |
| elif diff > best_diff: | |
| break | |
| threshold += 0.01 | |
| nb_calls = target_calls - best_signed_diff | |
| achieved_speed = total_calls / max(1, nb_calls) | |
| print( | |
| f"Mag Cache, best threshold found:{best_threshold:0.2f} " | |
| f"with gain x{achieved_speed:0.2f} for a target of x{speed_factor}" | |
| ) | |
| return best_threshold | |
| def set_magcache_params( | |
| dit, | |
| mag_ratios, | |
| num_steps, | |
| no_cfg, | |
| start_step=None, | |
| magcache_thresh=None, | |
| magcache_K=None, | |
| retention_ratio=None, | |
| ): | |
| print('using Magcache') | |
| dit.forward = MethodType(magcache_forward, dit) | |
| dit.cnt = 0 | |
| dit.num_steps = num_steps * 2 | |
| dit.magcache_thresh = 0.12 if magcache_thresh is None else magcache_thresh | |
| dit.K = 2 if magcache_K is None else magcache_K | |
| dit.accumulated_err = [0.0, 0.0] | |
| dit.accumulated_steps = [0, 0] | |
| dit.accumulated_ratio = [1.0, 1.0] | |
| dit.consecutive_skips = [0, 0] | |
| dit.magcache_start_step = 0 if start_step is None else int(start_step) | |
| dit.retention_ratio = 0.2 if retention_ratio is None else retention_ratio | |
| dit.magcache_retention_cnt = int(dit.num_steps * dit.retention_ratio) | |
| dit.residual_cache = [None, None] | |
| dit.mag_ratios = _prepare_mag_ratios(mag_ratios, num_steps) | |
| dit.no_cfg = no_cfg | |
| def _magcache_should_skip(dit, cnt): | |
| stream = cnt % 2 | |
| skip_forward = False | |
| residual_visual_embed = None | |
| step_no = cnt // 2 | |
| if cnt >= dit.magcache_retention_cnt and step_no > dit.magcache_start_step: | |
| cur_mag_ratio = dit.mag_ratios[cnt] | |
| dit.accumulated_ratio[stream] *= cur_mag_ratio | |
| dit.accumulated_steps[stream] += 1 | |
| cur_skip_err = np.abs(1 - dit.accumulated_ratio[stream]) | |
| dit.accumulated_err[stream] += cur_skip_err | |
| if dit.accumulated_err[stream] < dit.magcache_thresh and dit.accumulated_steps[stream] <= dit.K: | |
| if getattr(dit, "consecutive_skips", [0, 0])[stream] < dit.K: | |
| skip_forward = True | |
| residual_visual_embed = dit.residual_cache[stream] | |
| else: | |
| dit.accumulated_err[stream] = 0.0 | |
| dit.accumulated_steps[stream] = 0 | |
| dit.accumulated_ratio[stream] = 1.0 | |
| else: | |
| dit.accumulated_err[stream] = 0.0 | |
| dit.accumulated_steps[stream] = 0 | |
| dit.accumulated_ratio[stream] = 1.0 | |
| return skip_forward, residual_visual_embed, stream | |
| def _magcache_forward_single( | |
| self, | |
| x, | |
| text_embed, | |
| pooled_text_embed, | |
| time, | |
| visual_rope_pos, | |
| text_rope_pos, | |
| scale_factor=(1.0, 1.0, 1.0), | |
| sparse_params=None, | |
| attention_mask=None | |
| ): | |
| text_embed, time_embed, text_rope, visual_embed = self.before_text_transformer_blocks( | |
| text_embed, time, pooled_text_embed, x, text_rope_pos) | |
| x = None | |
| pooled_text_embed = None | |
| for text_transformer_block in self.text_transformer_blocks: | |
| text_embed = text_transformer_block(text_embed, time_embed, text_rope, attention_mask) | |
| if self._check_interrupt(): | |
| return None | |
| text_rope = None | |
| visual_embed, visual_shape, to_fractal, visual_rope = self.before_visual_transformer_blocks( | |
| visual_embed, visual_rope_pos, scale_factor, sparse_params) | |
| visual_rope_pos = None | |
| skip_forward, residual_visual_embed, stream = _magcache_should_skip(self, self.cnt) | |
| if skip_forward and residual_visual_embed is None: | |
| skip_forward = False | |
| if skip_forward: | |
| cache = getattr(self, "cache", None) | |
| if cache is not None and hasattr(cache, "skipped_steps") and stream == 0: | |
| cache.skipped_steps += 1 | |
| visual_embed = visual_embed + residual_visual_embed | |
| if hasattr(self, "consecutive_skips"): | |
| self.consecutive_skips[stream] += 1 | |
| else: | |
| if hasattr(self, "consecutive_skips"): | |
| self.consecutive_skips[stream] = 0 | |
| ori_visual_embed = visual_embed.clone() | |
| for visual_transformer_block in self.visual_transformer_blocks: | |
| visual_embed = visual_transformer_block(visual_embed, text_embed, time_embed, | |
| visual_rope, sparse_params, attention_mask) | |
| if self._check_interrupt(): | |
| return None | |
| torch.sub(visual_embed, ori_visual_embed, out=ori_visual_embed) | |
| residual_visual_embed = ori_visual_embed | |
| self.residual_cache[stream] = residual_visual_embed | |
| visual_rope = None | |
| x = self.after_blocks(visual_embed, visual_shape, to_fractal, text_embed, time_embed) | |
| if self.no_cfg: | |
| self.cnt += 2 | |
| else: | |
| self.cnt += 1 | |
| if self.cnt >= self.num_steps: | |
| self.cnt = 0 | |
| self.accumulated_ratio = [1.0, 1.0] | |
| self.accumulated_err = [0.0, 0.0] | |
| self.accumulated_steps = [0, 0] | |
| if hasattr(self, "consecutive_skips"): | |
| self.consecutive_skips = [0, 0] | |
| return x | |
| def _magcache_forward_joint( | |
| self, | |
| x_list, | |
| text_embed_list, | |
| pooled_text_embed_list, | |
| time_list, | |
| visual_rope_pos_list, | |
| text_rope_pos_list, | |
| scale_factor_list, | |
| sparse_params_list, | |
| attention_mask_list, | |
| ): | |
| count = len(x_list) | |
| text_embed_list = self._normalize_list(text_embed_list, count) | |
| pooled_text_embed_list = self._normalize_list(pooled_text_embed_list, count) | |
| time_list = self._normalize_list(time_list, count) | |
| visual_rope_pos_list = self._normalize_list(visual_rope_pos_list, count) | |
| text_rope_pos_list = self._normalize_list(text_rope_pos_list, count) | |
| scale_factor_list = self._normalize_list(scale_factor_list, count) | |
| sparse_params_list = self._normalize_list(sparse_params_list, count) | |
| attention_mask_list = self._normalize_list(attention_mask_list, count) | |
| text_embed_out = [None] * count | |
| time_embed_out = [None] * count | |
| text_rope_out = [None] * count | |
| visual_embed_out = [None] * count | |
| for idx in range(count): | |
| text_embed_out[idx], time_embed_out[idx], text_rope_out[idx], visual_embed_out[idx] = ( | |
| self.before_text_transformer_blocks( | |
| text_embed_list[idx], | |
| time_list[idx], | |
| pooled_text_embed_list[idx], | |
| x_list[idx], | |
| text_rope_pos_list[idx], | |
| ) | |
| ) | |
| x_list[idx] = None | |
| pooled_text_embed_list[idx] = None | |
| for text_transformer_block in self.text_transformer_blocks: | |
| for idx in range(count): | |
| text_embed_out[idx] = text_transformer_block( | |
| text_embed_out[idx], time_embed_out[idx], text_rope_out[idx], attention_mask_list[idx] | |
| ) | |
| if self._check_interrupt(): | |
| return None | |
| for idx in range(count): | |
| text_rope_out[idx] = None | |
| visual_shape_list = [None] * count | |
| to_fractal_list = [None] * count | |
| visual_rope_out = [None] * count | |
| for idx in range(count): | |
| visual_embed_out[idx], visual_shape_list[idx], to_fractal_list[idx], visual_rope_out[idx] = ( | |
| self.before_visual_transformer_blocks( | |
| visual_embed_out[idx], | |
| visual_rope_pos_list[idx], | |
| scale_factor_list[idx], | |
| sparse_params_list[idx], | |
| ) | |
| ) | |
| visual_rope_pos_list[idx] = None | |
| stream_ids = [0] * count | |
| skip_forward = [False] * count | |
| residual_visual_embed = [None] * count | |
| ori_visual_embed = [None] * count | |
| cnt = self.cnt | |
| for idx in range(count): | |
| stream_ids[idx] = cnt % 2 | |
| skip_forward[idx], residual_visual_embed[idx], _ = _magcache_should_skip(self, cnt) | |
| if skip_forward[idx] and residual_visual_embed[idx] is None: | |
| skip_forward[idx] = False | |
| if not skip_forward[idx] and hasattr(self, "consecutive_skips"): | |
| self.consecutive_skips[stream_ids[idx]] = 0 | |
| if skip_forward[idx]: | |
| if idx == 0: | |
| cache = getattr(self, "cache", None) | |
| if cache is not None and hasattr(cache, "skipped_steps"): | |
| cache.skipped_steps += 1 | |
| visual_embed_out[idx] = visual_embed_out[idx] + residual_visual_embed[idx] | |
| if hasattr(self, "consecutive_skips"): | |
| self.consecutive_skips[stream_ids[idx]] += 1 | |
| else: | |
| ori_visual_embed[idx] = visual_embed_out[idx].clone() | |
| cnt += 2 if self.no_cfg else 1 | |
| for visual_transformer_block in self.visual_transformer_blocks: | |
| for idx in range(count): | |
| if skip_forward[idx]: | |
| continue | |
| visual_embed_out[idx] = visual_transformer_block( | |
| visual_embed_out[idx], | |
| text_embed_out[idx], | |
| time_embed_out[idx], | |
| visual_rope_out[idx], | |
| sparse_params_list[idx], | |
| attention_mask_list[idx], | |
| ) | |
| if self._check_interrupt(): | |
| return None | |
| for idx in range(count): | |
| visual_rope_out[idx] = None | |
| for idx in range(count): | |
| if skip_forward[idx]: | |
| residual = residual_visual_embed[idx] | |
| else: | |
| torch.sub(visual_embed_out[idx], ori_visual_embed[idx], out=ori_visual_embed[idx]) | |
| residual = ori_visual_embed[idx] | |
| self.residual_cache[stream_ids[idx]] = residual | |
| outputs = [] | |
| for idx in range(count): | |
| outputs.append( | |
| self.after_blocks( | |
| visual_embed_out[idx], | |
| visual_shape_list[idx], | |
| to_fractal_list[idx], | |
| text_embed_out[idx], | |
| time_embed_out[idx], | |
| ) | |
| ) | |
| self.cnt = cnt | |
| if self.cnt >= self.num_steps: | |
| self.cnt = 0 | |
| self.accumulated_ratio = [1.0, 1.0] | |
| self.accumulated_err = [0.0, 0.0] | |
| self.accumulated_steps = [0, 0] | |
| if hasattr(self, "consecutive_skips"): | |
| self.consecutive_skips = [0, 0] | |
| return outputs | |
| def magcache_forward( | |
| self, | |
| x, | |
| text_embed, | |
| pooled_text_embed, | |
| time, | |
| visual_rope_pos, | |
| text_rope_pos, | |
| scale_factor=(1.0, 1.0, 1.0), | |
| sparse_params=None, | |
| attention_mask=None, | |
| ): | |
| if isinstance(x, (list, tuple)): | |
| return _magcache_forward_joint( | |
| self, | |
| list(x), | |
| text_embed, | |
| pooled_text_embed, | |
| time, | |
| visual_rope_pos, | |
| text_rope_pos, | |
| scale_factor, | |
| sparse_params, | |
| attention_mask, | |
| ) | |
| return _magcache_forward_single( | |
| self, | |
| x, | |
| text_embed, | |
| pooled_text_embed, | |
| time, | |
| visual_rope_pos, | |
| text_rope_pos, | |
| scale_factor=scale_factor, | |
| sparse_params=sparse_params, | |
| attention_mask=attention_mask, | |
| ) | |