Skip to content

[feat]: add tp by mixin,support flux2-dev,wan2.2#1226

Open
Watebear wants to merge 5 commits into
mainfrom
tp
Open

[feat]: add tp by mixin,support flux2-dev,wan2.2#1226
Watebear wants to merge 5 commits into
mainfrom
tp

Conversation

@Watebear

@Watebear Watebear commented Jul 5, 2026

Copy link
Copy Markdown
Collaborator

No description provided.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces tensor-parallel (TP) support for Flux2 and Wan2.2 models, including TP configuration files, weight/bias splitting utilities, and a TPRunnerMixin to handle rank-0 I/O broadcasting. The review feedback highlights several critical issues: using dist.get_rank() for device ordinals assumes a single-node setup and should be replaced with LOCAL_RANK to support multi-node clusters; specifying group=self.tp_group in dist.broadcast during weight loading will cause crashes when DP > 1 and should be broadcast globally; and the distributed inference script for Flux2 incorrectly references a non-existent configuration file instead of the newly added flux2_dev_tp.json.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines +32 to +38
def _rank_device(self):
ai_device = global_var.AI_DEVICE
if ai_device is None:
return torch.device("cpu")
if dist.is_initialized():
return torch.device(f"{ai_device}:{dist.get_rank()}")
return torch.device(ai_device)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

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), causing invalid device ordinal runtime errors. Using the LOCAL_RANK environment variable ensures correct local GPU mapping on multi-node clusters.

Suggested change
def _rank_device(self):
ai_device = global_var.AI_DEVICE
if ai_device is None:
return torch.device("cpu")
if dist.is_initialized():
return torch.device(f"{ai_device}:{dist.get_rank()}")
return torch.device(ai_device)
def _rank_device(self):
import os
ai_device = global_var.AI_DEVICE
if ai_device is None:
return torch.device("cpu")
if dist.is_initialized():
local_rank = int(os.environ.get("LOCAL_RANK", 0))
return torch.device(f"{ai_device}:{local_rank}")
return torch.device(ai_device)

Comment on lines +57 to +60
def _rank_device(self):
if dist.is_initialized():
return torch.device(f"{AI_DEVICE}:{dist.get_rank()}")
return torch.device(AI_DEVICE)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

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), causing invalid device ordinal runtime errors. Using the LOCAL_RANK environment variable ensures correct local GPU mapping on multi-node clusters.

Suggested change
def _rank_device(self):
if dist.is_initialized():
return torch.device(f"{AI_DEVICE}:{dist.get_rank()}")
return torch.device(AI_DEVICE)
def _rank_device(self):
import os
if dist.is_initialized():
local_rank = int(os.environ.get("LOCAL_RANK", 0))
return torch.device(f"{AI_DEVICE}:{local_rank}")
return torch.device(AI_DEVICE)

Comment on lines +98 to +101
def _rank_device(self):
if dist.is_initialized():
return torch.device(f"{AI_DEVICE}:{dist.get_rank()}")
return torch.device(AI_DEVICE)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

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), causing invalid device ordinal runtime errors. Using the LOCAL_RANK environment variable ensures correct local GPU mapping on multi-node clusters.

Suggested change
def _rank_device(self):
if dist.is_initialized():
return torch.device(f"{AI_DEVICE}:{dist.get_rank()}")
return torch.device(AI_DEVICE)
def _rank_device(self):
import os
if dist.is_initialized():
local_rank = int(os.environ.get("LOCAL_RANK", 0))
return torch.device(f"{AI_DEVICE}:{local_rank}")
return torch.device(AI_DEVICE)

Comment on lines +136 to +150
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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

Specifying group=self.tp_group in dist.broadcast will cause a crash or hang when DP > 1 (multiple TP groups) because global rank 0 (the source rank) is not a member of other TP groups. Since only global rank 0 loads the weights, the broadcast must happen across the default global group (world), matching dist.broadcast_object_list and flux2/model.py.

Suggested change
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
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)
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)
return distributed

Comment thread scripts/flux2/infer_flux2_dev_dist.sh Outdated
--model_path $model_path \
--prompt "Realistic macro photograph of a hermit crab using a soda can as its shell, partially emerging from the can, captured with sharp detail and natural colors, on a sunlit beach with soft shadows and a shallow depth of field, with blurred ocean waves in the background. The can has the text `BFL Diffusers` on it and it has a color gradient that start with #FF5733 at the top and transitions to #33FF57 at the bottom." \
--save_result_path "${lightx2v_path}/save_results/flux2_dev.png" \
--config_json "${lightx2v_path}/configs/flux2/flux2_dev_dist.json"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The script references flux2_dev_dist.json which is not added in this PR, whereas flux2_dev_tp.json is added and contains the matching "tensor_p_size": 4 configuration. Update the script to use flux2_dev_tp.json.

Suggested change
--config_json "${lightx2v_path}/configs/flux2/flux2_dev_dist.json"
--config_json "${lightx2v_path}/configs/flux2/flux2_dev_tp.json"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant