Repository navigation
Replies: 2 comments 2 replies
|
This is expected behavior, not a bug: ZeRO-3 (and
So your I put together a minimal repro to confirm this and verify two fixes (script below, run on 2 GPUs): Fix 1 — broadcast buffers yourself, since DeepSpeed won't: import deepspeed.comm as dist
for buf in model.buffers():
dist.broadcast(buf, src=0)Fix 2 (probably the better one for your case) — since Repro script, in case it's useful to reproduce on your end or extend: # SPDX-License-Identifier: Apache-2.0
# DeepSpeed Team
import os
import torch
import torch.multiprocessing as mp
import torch.nn as nn
import deepspeed
import deepspeed.comm as dist
from deepspeed.accelerator import get_accelerator
WORLD_SIZE = 2
ZERO3_CONFIG = {"train_micro_batch_size_per_gpu": 1, "zero_optimization": {"stage": 3}}
class VisionTokenizer(nn.Module):
def __init__(self):
super().__init__()
self.conv = nn.Conv3d(3, 8, kernel_size=3, padding=1)
self.bn = nn.BatchNorm3d(8)
def forward(self, x):
return self.bn(self.conv(x))
def init_dist(rank, world_size, master_port):
os.environ["MASTER_ADDR"] = "127.0.0.1"
os.environ["MASTER_PORT"] = str(master_port)
os.environ["LOCAL_RANK"] = str(rank)
os.environ["RANK"] = str(rank)
os.environ["LOCAL_SIZE"] = str(world_size)
os.environ["WORLD_SIZE"] = str(world_size)
get_accelerator().set_device(rank)
deepspeed.init_distributed(dist_backend=get_accelerator().communication_backend_name(),
init_method="env://", rank=rank, world_size=world_size)
def build_model_under_zero_init():
with deepspeed.zero.Init(config_dict_or_path=ZERO3_CONFIG):
model = VisionTokenizer()
return model.to(get_accelerator().current_device_name())
def simulate_bad_checkpoint_load(model, rank):
# mimics only rank 0's loader actually copying pretrained buffer values in
if rank == 0:
with torch.no_grad():
model.bn.running_mean.fill_(5.0)
model.bn.running_var.fill_(2.0)
def get_shared_input():
x = torch.randn(1, 3, 4, 8, 8, device=get_accelerator().current_device_name())
dist.broadcast(x, 0)
return x
def run_forward_with_gather(model, x):
model.eval()
with deepspeed.zero.GatheredParameters(model.parameters(), modifier_rank=None):
with torch.no_grad():
return model(x)
def report_diffs(tag, rank, world_size, out):
gathered = [torch.zeros_like(out) for _ in range(world_size)]
dist.all_gather(gathered, out.contiguous())
if rank == 0:
diffs = [(gathered[0] - gathered[i]).abs().max().item() for i in range(world_size)]
print(f"{tag} max|out_rank0 - out_rankN| per rank: {diffs}")
dist.barrier()
def case_bug(rank, world_size, _port):
init_dist(rank, world_size, 29511)
model = build_model_under_zero_init()
simulate_bad_checkpoint_load(model, rank)
out = run_forward_with_gather(model, get_shared_input())
report_diffs("[BUG REPRO]", rank, world_size, out)
def case_fix1_broadcast_buffers(rank, world_size, _port):
init_dist(rank, world_size, 29512)
model = build_model_under_zero_init()
simulate_bad_checkpoint_load(model, rank)
for buf in model.buffers():
dist.broadcast(buf, 0)
out = run_forward_with_gather(model, get_shared_input())
report_diffs("[FIX 1 - broadcast buffers]", rank, world_size, out)
def case_fix2_exclude_from_zero(rank, world_size, _port):
init_dist(rank, world_size, 29513)
torch.manual_seed(1234)
model = VisionTokenizer().to(get_accelerator().current_device_name()) # NOT under zero.Init()
with torch.no_grad():
model.bn.running_mean.fill_(5.0)
model.bn.running_var.fill_(2.0)
model.eval()
with torch.no_grad():
out = model(get_shared_input())
report_diffs("[FIX 2 - kept outside zero.Init]", rank, world_size, out)
def run(fn, world_size, master_port):
mp.spawn(fn, args=(world_size, master_port), nprocs=world_size, join=True)
if __name__ == "__main__":
run(case_bug, WORLD_SIZE, 29511)
run(case_fix1_broadcast_buffers, WORLD_SIZE, 29512)
run(case_fix2_exclude_from_zero, WORLD_SIZE, 29513) |
Uh oh!
There was an error while loading. Please reload this page.
Hellow, i launch my model by
accelerate launchwith zero3 and found all parameters are partitioned. For my context, i applyprocessor.vision_tokenizeronly for inference which is conducted by following code:However, i found
inputsvaries from different ranks (with samepixel_values). After some checks, i found the buffers ofnn.BatchNorm3dare different (runner_vars/means). Only the buffers of rank 0 is correct.So my questions are:
processor.vision_tokenizer, which is invariant to the transformer for training.All reactions