Scatter mm embeddings with row index_copy_ instead of masked_scatter_ to cut transient GPU memory (#37070)
This commit is contained in:
@@ -364,6 +364,27 @@ class MultiModalityDataPaddingPatternMultimodalTokens(MultiModalityDataPaddingPa
|
||||
return ret_input_ids
|
||||
|
||||
|
||||
# masked_scatter_ materializes the expanded [num_tokens, hidden] bool mask plus
|
||||
# an int64 prefix-sum over it (~9 B per num_tokens x hidden element); the
|
||||
# cumsum-derived row indices keep the transients O(num_tokens) and sync-free.
|
||||
def _scatter_mm_embedding(
|
||||
dest: torch.Tensor, mask: torch.Tensor, src: torch.Tensor
|
||||
) -> None:
|
||||
# mask: [num_tokens, 1] bool; src: [num_mm_tokens, width] in sequence order.
|
||||
src = src.to(dest.device, dest.dtype)
|
||||
num_src_rows = src.size(0)
|
||||
flat_mask = mask.view(-1)
|
||||
ranks = torch.cumsum(flat_mask, dim=0) - 1
|
||||
# False rows collapse into the discard slot num_src_rows; a mask/src
|
||||
# row-count mismatch device-asserts in scatter_/index_copy_ (poison init).
|
||||
ranks = ranks.masked_fill(~flat_mask, num_src_rows)
|
||||
rows = torch.full(
|
||||
(num_src_rows + 1,), dest.size(0), dtype=torch.long, device=dest.device
|
||||
)
|
||||
rows.scatter_(0, ranks, torch.arange(flat_mask.numel(), device=dest.device))
|
||||
dest.index_copy_(0, rows[:num_src_rows], src)
|
||||
|
||||
|
||||
def embed_mm_inputs(
|
||||
mm_inputs_list: List[MultimodalInputs],
|
||||
extend_prefix_lens: List[int],
|
||||
@@ -485,18 +506,16 @@ def embed_mm_inputs(
|
||||
other_info["input_deepstack_embeds"] = input_deepstack_embeds
|
||||
|
||||
# 4. scatter embeddings into input embedding
|
||||
# masked_scatter_ avoids the cudaStreamSynchronize that torch.where triggers.
|
||||
def _scatter(dest, mask, src):
|
||||
dest.masked_scatter_(mask.expand_as(dest), src.to(dest.device, dest.dtype))
|
||||
|
||||
for i, modality, embedding, mask in zip(
|
||||
range(len(embeddings)), modalities, embeddings, masks
|
||||
):
|
||||
if embedding is None or mask is None:
|
||||
continue
|
||||
_scatter(input_embeds, mask, embedding)
|
||||
_scatter_mm_embedding(dest=input_embeds, mask=mask, src=embedding)
|
||||
if use_deepstack.get(modality, None):
|
||||
_scatter(input_deepstack_embeds, mask, deepstack_embeddings[i])
|
||||
_scatter_mm_embedding(
|
||||
dest=input_deepstack_embeds, mask=mask, src=deepstack_embeddings[i]
|
||||
)
|
||||
|
||||
return input_embeds, other_info
|
||||
|
||||
|
||||
Reference in New Issue
Block a user