Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 57 additions & 1 deletion deepspeed/module_inject/replace_module.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,63 @@
import deepspeed


def replace_transformer_layer_with_config(orig_layer_impl, model, transformer_config):
""" Replace bert-style transformer layers with DeepSpeed's transformer layer
Arguments:
orig_layer_impl (torch.nn.Module): the original transformer layer implementation to look for,
e.g., transformers.modeling_bert.BertLayer.
model (torch.nn.Module): user's nn.module representing their model
transformer_config (dict): deepspeed transformer config containing hidden size, attention heads, etc.

Returns:
Updated nn.module with replaced transformer layers
"""
def replace_fn(child):
new_module = deepspeed.DeepSpeedTransformerLayer(transformer_config)

# copy relevant state from child -> new module
qw = child.attention.self.query.weight
qb = child.attention.self.query.bias
kw = child.attention.self.key.weight
kb = child.attention.self.key.bias
vw = child.attention.self.value.weight
vb = child.attention.self.value.bias

qkvw = torch.cat((qw, kw, vw), 0)
qkvb = torch.cat((qb, kb, vb), 0)

#qw.data,kw.data,vw.data = torch.chunk(qkvw, 3, axis=0)
#qb.data,kb.data,vb.data = torch.chunk(qkvb, 3, axis=0)

new_module.attn_qkvw.data = qkvw
new_module.attn_qkvb.data = qkvb
new_module.attn_ow.data = child.attention.output.dense.weight
new_module.attn_ob.data = child.attention.output.dense.bias
if transformer_config.pre_layer_norm:
attention_layernorm = child.PostAttentionLayerNorm
else:
attention_layernorm = child.attention.output.LayerNorm
new_module.attn_nw.data = attention_layernorm.weight
new_module.attn_nb.data = attention_layernorm.bias
if transformer_config.pre_layer_norm:
intermediate_ff = child.intermediate.dense_act
else:
intermediate_ff = child.intermediate.dense
new_module.inter_w.data = intermediate_ff.weight
new_module.inter_b.data = intermediate_ff.bias
new_module.output_w.data = child.output.dense.weight
new_module.output_b.data = child.output.dense.bias
if transformer_config.pre_layer_norm:
transformer_layernorm = child.PreAttentionLayerNorm
else:
transformer_layernorm = child.output.LayerNorm
new_module.norm_w.data = transformer_layernorm.weight
new_module.norm_b.data = transformer_layernorm.bias
return new_module

return replace_module(model=model, orig_class=orig_layer_impl, replace_fn=replace_fn)


def replace_transformer_layer(orig_layer_impl,
model,
micro_batch_size,
Expand Down Expand Up @@ -186,7 +243,6 @@ def _replace_module(model, policies):
orig = repr(child)
setattr(model, name, policies[child.__class__](child))
new = getattr(model, name)
print(f'{orig} -> {new}')
else:
_replace_module(child, policies)

Expand Down
28 changes: 25 additions & 3 deletions deepspeed/ops/transformer/transformer.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ class DeepSpeedTransformerConfig(TransformerConfig):
to turn it off in order to be able to reproduce the same result through the regular kernel execution.

huggingface: Enbale if using the HuggingFace interface style for sending out the forward results.

training: Enable for training rather than inference.
"""
def __init__(self,
batch_size=-1,
Expand All @@ -111,7 +113,8 @@ def __init__(self,
adjust_init_range=True,
attn_dropout_checkpoint=False,
stochastic_mode=False,
huggingface=False):
huggingface=False,
training=True):
super(DeepSpeedTransformerConfig,
self).__init__(
batch_size,
Expand All @@ -131,7 +134,7 @@ def __init__(self,
self.gelu_checkpoint = gelu_checkpoint # True: if higher batch size is required
self.adjust_init_range = adjust_init_range
self.test_gemm = False
self.training = True
self.training = training
self.is_grad_enabled = True
self.attn_dropout_checkpoint = attn_dropout_checkpoint
self.stochastic_mode = stochastic_mode
Expand Down Expand Up @@ -248,7 +251,7 @@ def forward(ctx,
norm_w.register_hook(lambda x, self=self: grads.append([x, "norm_W"]))
norm_b.register_hook(lambda x, self=self: grads.append([x, "norm_B"]))

if config.is_grad_enabled:
if config.is_grad_enabled and config.training:
Comment thread
tjruwase marked this conversation as resolved.
if (config.pre_layer_norm and config.normalize_invertible):
ctx.save_for_backward(input_mask,
attn_qkvw,
Expand Down Expand Up @@ -405,6 +408,25 @@ def backward(ctx, grad_output):
norm_w,
norm_b)

# This appears to be an effective way to release context memory
Comment thread
tjruwase marked this conversation as resolved.
ctx.qkv_tf = None
ctx.soft_inp = None
ctx.ctx_bufB = None
ctx.gelu_inp = None
ctx.ff2_inp = None
ctx.attn_o_inp = None
ctx.ff1_inp = None
ctx.add_res = None
ctx.inp_norm = None
ctx.config = None
ctx.attn_layer_norm_mean = None
ctx.layer_norm_mean = None
ctx.attn_prob_dropout_mask = None
ctx.attn_output_dropout_mask = None
ctx.layer_output_dropout_mask = None
ctx.attn_layer_norm_var = None
ctx.layer_norm_var = None

return (grad_input,
None,
None,
Expand Down
23 changes: 9 additions & 14 deletions deepspeed/runtime/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -530,21 +530,16 @@ def see_memory_usage(message):
# Print message except when distributed but not rank 0
logger.info(message)
logger.info(
"Memory Allocated %s GigaBytes ",
torch.cuda.memory_allocated() / (1024 * 1024 * 1024),
)
logger.info(
"Max Memory Allocated %s GigaBytes",
torch.cuda.max_memory_allocated() / (1024 * 1024 * 1024),
)
f"MA {round(torch.cuda.memory_allocated() / (1024 * 1024 * 1024),2 )} GB \
Max_MA {round(torch.cuda.max_memory_allocated() / (1024 * 1024 * 1024),2)} GB \
CA {round(torch.cuda.memory_cached() / (1024 * 1024 * 1024),2)} GB \
Max_CA {round(torch.cuda.max_memory_cached() / (1024 * 1024 * 1024))} GB ")

import psutil
vm_stats = psutil.virtual_memory()
used_GB = round((vm_stats.used / (1024**3)), 2)
logger.info(
"Cache Allocated %s GigaBytes",
torch.cuda.memory_cached() / (1024 * 1024 * 1024),
)
logger.info(
"Max cache Allocated %s GigaBytes",
torch.cuda.max_memory_cached() / (1024 * 1024 * 1024),
)
f'CPU Virtual Memory: used = {used_GB} GB, percent = {vm_stats.percent}%')


def call_to_str(base, *args, **kwargs):
Expand Down