Skip to content

optimize_a_cc_me_absorb#4

Open
jychen21 wants to merge 1 commit into
madsys-dev:mainfrom
jychen21:optimize_a_cc_me_absorb
Open

optimize_a_cc_me_absorb#4
jychen21 wants to merge 1 commit into
madsys-dev:mainfrom
jychen21:optimize_a_cc_me_absorb

Conversation

@jychen21

Copy link
Copy Markdown

We found that below two operations are memory inefficient:

q_nope = torch.matmul(q_nope, q_absorb);
attn_output = torch.matmul(attn_output, out_absorb.mT)

e.g.
q_nope: [B, M, 1, 128]
q_absorb: [1, M, 128, 512]

In this shape, we found that it will trigger elementwise data copy of B times, so we simply permute the q_nope from [B, M, 1, 128] to [1, M, B, 128], to reduce redundant memory movement and also make [1, 128] @ [128, 512] (GEMV) to [B, 128] @ [128, 512] (GEMM).

Below are the test details:

Accuracy
image

Performance (A100)
python benchmark.py A_CC_ME 1024 --bsz 32

  • before:
    image
    image
  • after:
    image
    image

@wx-csy

wx-csy commented Aug 29, 2024

Copy link
Copy Markdown
Contributor

Good point! Actually, we found that using einsum instead if matmul can achieve the similar results. Maybe torch is already capable to infer the optimal calculation plan with einsum. Could you please change to use einsum for better readability?

).to(q_nope.dtype)
attn_output = torch.einsum('bhql,blc->bhqc', attn_weights, compressed_kv)
attn_output = torch.matmul(attn_output, out_absorb.mT) # torch.einsum('bhqc,hdc->bhqd', attn_output, out_absorb)
attn_output = attn_output = torch.matmul(attn_output.permute(2, 1, 0, 3), out_absorb.mT).permute(2, 1, 0, 3) # torch.einsum('bhqc,hdc->bhqd', attn_output, out_absorb)

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.

can be changed to attn_output = torch.einsum('bhqc,hdc->bhqd', attn_output, out_absorb)

q_pe = apply_rotary_pos_emb(q_pe, cos, sin, q_position_ids)

q_nope = torch.matmul(q_nope, q_absorb)
q_nope = torch.matmul(q_nope.transpose(0, 2), q_absorb).transpose(0, 2)

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.

can be changed to q_nope = torch.einsum('bhqd,hdc->bhqc', q_nope, q_absorb)

q_absorb = kv_b_proj[:, :self.qk_nope_head_dim,:]
out_absorb = kv_b_proj[:, self.qk_nope_head_dim:, :]
q_absorb = kv_b_proj[:, :self.qk_nope_head_dim,:].unsqueeze(0)
out_absorb = kv_b_proj[:, self.qk_nope_head_dim:, :].unsqueeze(0)

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.

no need to unsqueeze here if einsum is used in line 164

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.

2 participants