Skip to content

Commit 6c25c29

Browse files
committed
debugging the fp16 attn
1 parent 49b73f0 commit 6c25c29

2 files changed

Lines changed: 43 additions & 29 deletions

File tree

nunchaku/models/attention_processor.py

Lines changed: 32 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -85,15 +85,17 @@ def __call__(
8585
pad_size = self.pad_size
8686

8787
batch_size, _, channels = hidden_states.shape
88-
assert channels == self.heads * self.head_dim
88+
assert channels == attn.heads * attn.head_dim
8989
if encoder_hidden_states is None:
90+
# single transformer block
91+
assert attn.added_kv_proj_dim is None
9092
num_tokens = hidden_states.shape[1]
9193
num_tokens_pad = math.ceil(num_tokens / pad_size) * pad_size
9294
query = torch.empty(
9395
batch_size,
94-
self.heads,
96+
attn.heads,
9597
num_tokens_pad,
96-
self.head_dim,
98+
attn.head_dim,
9799
dtype=torch.float16,
98100
device=hidden_states.device,
99101
)
@@ -103,25 +105,26 @@ def __call__(
103105
assert torch.is_tensor(image_rotary_emb)
104106
fused_qkv_norm_rottary(
105107
hidden_states,
106-
self.to_qkv,
107-
self.norm_q,
108-
self.norm_k,
108+
attn.to_qkv,
109+
attn.norm_q,
110+
attn.norm_k,
109111
image_rotary_emb,
110112
output=(query, key, value),
111113
num_tokens=num_tokens,
112114
)
113-
114115
else:
116+
# joint transformer block
117+
assert attn.added_kv_proj_dim is not None
115118
num_txt_tokens = encoder_hidden_states.shape[1]
116119
num_img_tokens = hidden_states.shape[1]
117120
num_txt_tokens_pad = math.ceil(num_txt_tokens / pad_size) * pad_size
118121
num_img_tokens_pad = math.ceil(num_img_tokens / pad_size) * pad_size
119122
num_tokens_pad = num_txt_tokens_pad + num_img_tokens_pad
120123
query = torch.empty(
121124
batch_size,
122-
self.heads,
125+
attn.heads,
123126
num_tokens_pad,
124-
self.head_dim,
127+
attn.head_dim,
125128
dtype=torch.float16,
126129
device=hidden_states.device,
127130
)
@@ -131,43 +134,45 @@ def __call__(
131134
assert isinstance(image_rotary_emb, tuple)
132135
fused_qkv_norm_rottary(
133136
hidden_states,
134-
self.to_qkv,
135-
self.norm_q,
136-
self.norm_k,
137+
attn.to_qkv,
138+
attn.norm_q,
139+
attn.norm_k,
137140
image_rotary_emb[0],
138141
output=(query[:, :num_img_tokens_pad], key[:, :num_img_tokens_pad], value[:, :num_img_tokens_pad]),
139142
num_tokens=num_img_tokens,
140143
)
141144
fused_qkv_norm_rottary(
142145
encoder_hidden_states,
143-
self.add_qkv_proj,
144-
self.norm_added_q,
145-
self.norm_added_k,
146+
attn.add_qkv_proj,
147+
attn.norm_added_q,
148+
attn.norm_added_k,
146149
image_rotary_emb[1],
147150
output=(query[:, num_img_tokens_pad:], key[:, num_img_tokens_pad:], value[:, num_img_tokens_pad:]),
148151
num_tokens=num_txt_tokens,
149152
)
150153
attention_output = torch.empty(
151154
batch_size,
152155
num_tokens_pad,
153-
self.heads * self.head_dim,
156+
attn.heads * attn.head_dim,
154157
dtype=hidden_states.dtype,
155158
device=hidden_states.device,
156159
)
157-
attention_fp16(query, key, value, attention_output, self.head_dim ** (-0.5))
160+
attention_fp16(query, key, value, attention_output, attn.head_dim ** (-0.5))
161+
hidden_states = attention_output.view(batch_size, num_tokens_pad, attn.heads, attn.head_dim)
158162

159-
if encoder_hidden_states is not None:
163+
if encoder_hidden_states is None:
164+
# for single transformer block, we split the proj_out into two linear layers
165+
hidden_states = hidden_states[:, :num_tokens]
166+
hidden_states = attn.to_out(hidden_states)
167+
return hidden_states
168+
else:
160169
encoder_hidden_states, hidden_states = (
161-
hidden_states[:, : encoder_hidden_states.shape[1]],
162-
hidden_states[:, encoder_hidden_states.shape[1] :],
170+
hidden_states[:, :num_txt_tokens],
171+
hidden_states[:, num_txt_tokens_pad : num_txt_tokens_pad + num_img_tokens],
163172
)
164173
# linear proj
165-
hidden_states = self.to_out[0](hidden_states)
174+
hidden_states = attn.to_out[0](hidden_states)
166175
# dropout
167-
hidden_states = self.to_out[1](hidden_states)
168-
encoder_hidden_states = self.to_add_out(encoder_hidden_states)
176+
hidden_states = attn.to_out[1](hidden_states)
177+
encoder_hidden_states = attn.to_add_out(encoder_hidden_states)
169178
return hidden_states, encoder_hidden_states
170-
else:
171-
# for single transformer block, we split the proj_out into two linear layers
172-
hidden_states = self.to_out(hidden_states)
173-
return hidden_states

nunchaku/models/transformers/transformer_flux_v2.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626

2727

2828
class NunchakuFluxAttention(nn.Module):
29-
def __init__(self, flux_attention: FluxAttention, processor: str = "flashattn2", **kwargs):
29+
def __init__(self, flux_attention: FluxAttention, processor: str = "nunchaku-fp16", **kwargs):
3030
super(NunchakuFluxAttention, self).__init__()
3131

3232
self.head_dim = flux_attention.head_dim
@@ -65,7 +65,16 @@ def __init__(self, flux_attention: FluxAttention, processor: str = "flashattn2",
6565
self.add_qkv_proj = SVDQW4A4Linear.from_linear(add_qkv_proj, **kwargs)
6666
self.to_add_out = SVDQW4A4Linear.from_linear(flux_attention.to_add_out, **kwargs)
6767

68-
self.processor = NunchakuFA2Processor()
68+
self.processor = None
69+
self.set_processor(processor)
70+
71+
def set_processor(self, processor: str):
72+
if processor == "flashattn2":
73+
self.processor = NunchakuFA2Processor()
74+
elif processor == "nunchaku-fp16":
75+
self.processor = NunchakuFP16AttnProcessor()
76+
else:
77+
raise ValueError(f"Processor {processor} is not supported")
6978

7079
def forward(
7180
self,

0 commit comments

Comments
 (0)