xingzhaohu's picture
Add files using upload-large-folder tool
e0a61be verified
Raw
History Blame Contribute Delete
2.7 kB
# Copyright (c) OpenMMLab. All rights reserved.
import torch.distributed as dist
from ..comm import all_to_all
from ..setup import get_sp_group, get_sp_world_size
def pre_process_for_sequence_parallel_attn(query_states,
key_states,
value_states,
scatter_dim=2,
gather_dim=1):
sequence_parallel_world_size = get_sp_world_size()
n_head = query_states.shape[2]
assert n_head % sequence_parallel_world_size == 0, \
('The number of attention heads should be divisible by '
f'sequence_parallel_world_size. But got n_head = {n_head} and '
f'sequence_parallel_world_size = {sequence_parallel_world_size}.')
# (b, s // sp_world_size, nd, dim) -> (b, s, nd // sp_world_size, dim)
sequence_parallel_group = get_sp_group()
query_states = all_to_all(
query_states,
sequence_parallel_group,
scatter_dim=scatter_dim,
gather_dim=gather_dim)
key_states = all_to_all(
key_states,
sequence_parallel_group,
scatter_dim=scatter_dim,
gather_dim=gather_dim)
value_states = all_to_all(
value_states,
sequence_parallel_group,
scatter_dim=scatter_dim,
gather_dim=gather_dim)
return query_states, key_states, value_states
def post_process_for_sequence_parallel_attn(attn_output,
scatter_dim=1,
gather_dim=2):
# (b, s, nd // sp_world_size, dim) -> (b, s // sp_world_size, nd, dim)
sequence_parallel_group = get_sp_group()
output = all_to_all(
attn_output,
sequence_parallel_group,
scatter_dim=scatter_dim,
gather_dim=gather_dim)
return output
def sequence_parallel_wrapper(local_attn):
def sequence_parallel_attn(query_states, key_states, value_states, *args,
**kwargs):
training = kwargs.pop('training', True)
enable_sequence_parallel = (
dist.is_initialized() and get_sp_world_size() > 1 and training)
if enable_sequence_parallel:
query_states, key_states, value_states = \
pre_process_for_sequence_parallel_attn(
query_states, key_states, value_states)
out = local_attn(query_states, key_states, value_states, *args,
**kwargs)
if enable_sequence_parallel:
out = post_process_for_sequence_parallel_attn(out).contiguous()
return out
return sequence_parallel_attn