-
Notifications
You must be signed in to change notification settings - Fork 236
[feat]: add tp by mixin,support flux2-dev,wan2.2 #1226
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
dfc4c7f
0987165
0f47ac9
60b3abd
bbf89ba
82ad1f4
1364a5e
4a9d413
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| { | ||
| "model_cls": "flux2_dev", | ||
| "task": "t2i", | ||
| "infer_steps": 50, | ||
| "sample_guide_scale": 4.0, | ||
| "vae_scale_factor": 16, | ||
| "feature_caching": "None", | ||
| "enable_cfg": false, | ||
| "patch_size": 2, | ||
| "tokenizer_max_length": 512, | ||
| "rope_type": "flashinfer_rope", | ||
| "text_encoder_out_layers": [10, 20, 30], | ||
| "parallel": { | ||
| "tensor_p_size": 4 | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| { | ||
| "infer_steps": 40, | ||
| "target_video_length": 81, | ||
| "text_len": 512, | ||
| "target_height": 720, | ||
| "target_width": 1280, | ||
| "self_attn_1_type": "flash_attn3", | ||
| "cross_attn_1_type": "flash_attn3", | ||
| "cross_attn_2_type": "flash_attn3", | ||
| "sample_guide_scale": [ | ||
| 4.0, | ||
| 3.0 | ||
| ], | ||
| "sample_shift": 12.0, | ||
| "enable_cfg": true, | ||
| "cpu_offload": false, | ||
| "t5_cpu_offload": false, | ||
| "vae_cpu_offload": false, | ||
| "boundary": 0.875, | ||
| "use_tiling_vae": true, | ||
| "parallel": { | ||
| "tensor_p_size": 4 | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -28,6 +28,7 @@ | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from lightx2v.utils.custom_compiler import compiled_method | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from lightx2v.utils.envs import * | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from lightx2v.utils.utils import * | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| from lightx2v_platform.base.global_var import AI_DEVICE | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| class WanModel(BaseTransformerModel): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
@@ -52,6 +53,104 @@ def __init__(self, model_path, config, device, model_type="wan2.1", lora_path=No | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self._init_weights() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self._init_infer() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # ------------------------------------------------------------------ TP -- | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def _rank_device(self): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if dist.is_initialized(): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return torch.device(f"{AI_DEVICE}:{dist.get_rank()}") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return torch.device(AI_DEVICE) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def _get_split_type(self, key): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if not key.endswith(".weight"): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return None | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| col_infixes = ( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ".self_attn.q.", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ".self_attn.k.", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ".self_attn.v.", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ".self_attn.norm_q.", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ".self_attn.norm_k.", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ".cross_attn.q.", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ".cross_attn.k.", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ".cross_attn.v.", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ".cross_attn.norm_q.", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ".cross_attn.norm_k.", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ".cross_attn.k_img.", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ".cross_attn.v_img.", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| row_infixes = (".self_attn.o.", ".cross_attn.o.", ".ffn.2.") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if any(s in key for s in col_infixes): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return "col" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if any(s in key for s in row_infixes): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return "row" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if ".ffn.0." in key: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return "col" | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return None | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def _split_bias_for_tp(self, bias, split_type, tp_size): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if split_type == "col": | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return list(torch.chunk(bias, tp_size, dim=0)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| raise ValueError(f"Unsupported bias split_type: {split_type}") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def _split_weight_for_tp(self, key, weight, tp_size): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| split_type = self._get_split_type(key) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if split_type == "col": | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return list(torch.chunk(weight, tp_size, dim=0)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if split_type == "row": | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return list(torch.chunk(weight, tp_size, dim=1)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| raise ValueError(f"Unknown split_type for {key}") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def _load_weights_from_rank0(self, weight_dict, is_weight_loader): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if not self.use_tp: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return super()._load_weights_from_rank0(weight_dict, is_weight_loader) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| src_rank = 0 | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| target_device = self._rank_device() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if is_weight_loader: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| processed, meta, processed_bias = {}, {}, set() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for key, tensor in weight_dict.items(): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| split_type = self._get_split_type(key) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if key.endswith(".weight") and split_type is not None: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| shards = self._split_weight_for_tp(key, tensor, self.tp_size) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for r, shard in enumerate(shards): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| processed[f"{key}__tp_{r}"] = shard.contiguous() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| meta[key] = {"shape": shards[0].shape, "dtype": shards[0].dtype, "is_tp": True} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| bias_key = key.replace(".weight", ".bias") | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if bias_key in weight_dict and split_type == "col": | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| bias_shards = self._split_bias_for_tp(weight_dict[bias_key], split_type, self.tp_size) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for r, shard in enumerate(bias_shards): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| processed[f"{bias_key}__tp_{r}"] = shard.contiguous() | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| meta[bias_key] = {"shape": bias_shards[0].shape, "dtype": bias_shards[0].dtype, "is_tp": True} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| processed_bias.add(bias_key) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| elif key not in processed_bias: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| processed[key] = tensor | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| meta[key] = {"shape": tensor.shape, "dtype": tensor.dtype, "is_tp": False} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| obj_list = [meta] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| else: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| obj_list = [None] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| dist.broadcast_object_list(obj_list, src=src_rank) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| synced_meta = obj_list[0] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| distributed = {k: torch.empty(m["shape"], dtype=m["dtype"], device=target_device) for k, m in synced_meta.items()} | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for key in sorted(synced_meta.keys()): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| m = synced_meta[key] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if m["is_tp"]: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for r in range(self.tp_size): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| buf = processed[f"{key}__tp_{r}"].to(target_device) if is_weight_loader else torch.empty(m["shape"], dtype=m["dtype"], device=target_device) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| dist.broadcast(buf, src=src_rank, group=self.tp_group) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if r == self.tp_rank: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| distributed[key].copy_(buf) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| del buf | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| else: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if is_weight_loader: | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| distributed[key].copy_(processed[key].to(target_device)) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| dist.broadcast(distributed[key], src=src_rank, group=self.tp_group) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| return distributed | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+136
to
+150
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Specifying
Suggested change
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| # ------------------------------------------------------------------ TP -- | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| def _init_infer_class(self): | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self.pre_infer_class = WanPreInfer | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| self.post_infer_class = WanPostInfer | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using
dist.get_rank()as the device ordinal assumes a single-node multi-GPU setup. In multi-node distributed environments,dist.get_rank()returns the global rank (which can exceed the number of GPUs on a single node), causinginvalid device ordinalruntime errors. Using theLOCAL_RANKenvironment variable ensures correct local GPU mapping on multi-node clusters.