|
10 | 10 | from torch_tensorrt.dynamo.conversion.converter_utils import ( |
11 | 11 | cast_trt_tensor, |
12 | 12 | get_trt_tensor, |
| 13 | + prepend_ones, |
13 | 14 | ) |
14 | 15 |
|
15 | 16 | _LOGGER: logging.Logger = logging.getLogger(__name__) |
@@ -193,18 +194,17 @@ def scaled_dot_product_attention( |
193 | 194 | if attn_mask is not None: |
194 | 195 | if attn_mask.dtype == trt.DataType.BOOL: |
195 | 196 | mask_tensor = attn_mask |
| 197 | + elif attn_mask.dtype != query.dtype: |
| 198 | + mask_tensor = cast_trt_tensor( |
| 199 | + ctx, |
| 200 | + attn_mask, |
| 201 | + query.dtype, |
| 202 | + name + "_cast_attn_mask", |
| 203 | + target, |
| 204 | + source_ir, |
| 205 | + ) |
196 | 206 | else: |
197 | | - if attn_mask.dtype != query.dtype: |
198 | | - mask_tensor = cast_trt_tensor( |
199 | | - ctx, |
200 | | - attn_mask, |
201 | | - query.dtype, |
202 | | - name + "_cast_attn_mask", |
203 | | - target, |
204 | | - source_ir, |
205 | | - ) |
206 | | - else: |
207 | | - mask_tensor = attn_mask |
| 207 | + mask_tensor = attn_mask |
208 | 208 |
|
209 | 209 | scaled_query = impl.elementwise.mul( |
210 | 210 | ctx, target, source_ir, f"{name}_scaled_query", query, scale_factor |
@@ -329,41 +329,101 @@ def scaled_dot_product_efficient_attention( |
329 | 329 | source_ir, |
330 | 330 | ) |
331 | 331 |
|
| 332 | + if ( |
| 333 | + isinstance(scaled_query.shape[1], int) |
| 334 | + and scaled_query.shape[1] < 0 |
| 335 | + and isinstance(key.shape[1], int) |
| 336 | + and key.shape[1] > 0 |
| 337 | + ): |
| 338 | + shape_layer = ctx.net.add_shape(key) |
| 339 | + shape_layer.name = name + "_key_shape" |
| 340 | + shuffle = ctx.net.add_shuffle(scaled_query) |
| 341 | + shuffle.set_input(1, shape_layer.get_output(0)) |
| 342 | + shuffle.name = name + "_fix_head_dim" |
| 343 | + scaled_query = shuffle.get_output(0) |
| 344 | + |
| 345 | + mask_tensor = None |
332 | 346 | if attn_bias is not None: |
333 | | - attn_weight = impl.matmul.matrix_multiply( |
334 | | - ctx, |
335 | | - target, |
336 | | - source_ir, |
337 | | - name + "_mm", |
338 | | - scaled_query, |
339 | | - key, |
340 | | - other_matrix_op=trt.MatrixOperation.TRANSPOSE, |
341 | | - ) |
342 | | - attn_weight = impl.elementwise.add( |
343 | | - ctx, target, source_ir, name + "_attn_bias_add", attn_weight, attn_bias |
344 | | - ) |
345 | | - attn_weight = impl.normalization.softmax( |
346 | | - ctx, target, source_ir, name + "_softmax", attn_weight, -1, False |
347 | | - ) |
348 | | - out = impl.matmul.matrix_multiply( |
| 347 | + if attn_bias.dtype == trt.DataType.BOOL: |
| 348 | + mask_tensor = attn_bias |
| 349 | + elif attn_bias.dtype != query.dtype: |
| 350 | + mask_tensor = cast_trt_tensor( |
| 351 | + ctx, |
| 352 | + attn_bias, |
| 353 | + query.dtype, |
| 354 | + name + "_cast_attn_bias", |
| 355 | + target, |
| 356 | + source_ir, |
| 357 | + ) |
| 358 | + else: |
| 359 | + mask_tensor = attn_bias |
| 360 | + |
| 361 | + # TensorRT IAttention does not allow setting both causal=True and mask. |
| 362 | + # If both are requested, fold causal into mask and disable causal flag. |
| 363 | + use_causal = is_causal |
| 364 | + if mask_tensor is not None and is_causal: |
| 365 | + L = impl.shape.shape(ctx, target, source_ir, name + "_L", query, -2) |
| 366 | + S = impl.shape.shape(ctx, target, source_ir, name + "_S", key, -2) |
| 367 | + causal_mask = tril( |
349 | 368 | ctx, |
350 | 369 | target, |
351 | 370 | source_ir, |
352 | | - name + "_out", |
353 | | - attn_weight, |
354 | | - value, |
| 371 | + name + "_tril", |
| 372 | + L, |
| 373 | + S, |
355 | 374 | ) |
356 | | - return out, None, None, None |
357 | | - else: |
358 | | - attention_layer = ctx.net.add_attention( |
359 | | - scaled_query, key, value, trt.AttentionNormalizationOp.SOFTMAX, is_causal |
360 | | - ) |
361 | | - assert attention_layer is not None, "attention layer is None" |
| 375 | + diff = len(query.shape) - len(causal_mask.shape) |
| 376 | + causal_mask = prepend_ones(ctx, causal_mask, name + "_prepend_ones", diff) |
| 377 | + |
| 378 | + if mask_tensor.dtype == trt.DataType.BOOL: |
| 379 | + mask_tensor = impl.elementwise.logical_and( |
| 380 | + ctx, |
| 381 | + target, |
| 382 | + source_ir, |
| 383 | + name + "_causal_attn_bias_and", |
| 384 | + causal_mask, |
| 385 | + mask_tensor, |
| 386 | + ) |
| 387 | + else: |
| 388 | + # Convert causal bool mask to additive bias mask: |
| 389 | + # True -> 0.0 (keep), False -> -inf (block) |
| 390 | + zero_bias = get_trt_tensor( |
| 391 | + ctx, 0.0, name + "_causal_additive_bias_zero", query.dtype |
| 392 | + ) |
| 393 | + neg_inf_bias = get_trt_tensor( |
| 394 | + ctx, float("-inf"), name + "_causal_additive_bias_neg_inf", query.dtype |
| 395 | + ) |
| 396 | + causal_additive_bias = impl.condition.where( |
| 397 | + ctx, |
| 398 | + target, |
| 399 | + source_ir, |
| 400 | + name + "_causal_additive_bias", |
| 401 | + zero_bias, |
| 402 | + neg_inf_bias, |
| 403 | + causal_mask, |
| 404 | + ) |
| 405 | + mask_tensor = impl.elementwise.add( |
| 406 | + ctx, |
| 407 | + target, |
| 408 | + source_ir, |
| 409 | + name + "_attn_bias_add_causal", |
| 410 | + mask_tensor, |
| 411 | + causal_additive_bias, |
| 412 | + ) |
| 413 | + use_causal = False |
362 | 414 |
|
363 | | - attention_layer.decomposable = True |
| 415 | + attention_layer = ctx.net.add_attention( |
| 416 | + scaled_query, key, value, trt.AttentionNormalizationOp.SOFTMAX, use_causal |
| 417 | + ) |
| 418 | + assert attention_layer is not None, "attention layer is None" |
364 | 419 |
|
365 | | - attention_output = attention_layer.get_output(0) |
366 | | - return attention_output, None, None, None |
| 420 | + if mask_tensor is not None: |
| 421 | + attention_layer.mask = mask_tensor |
| 422 | + |
| 423 | + attention_layer.decomposable = True |
| 424 | + |
| 425 | + attention_output = attention_layer.get_output(0) |
| 426 | + return attention_output, None, None, None |
367 | 427 |
|
368 | 428 |
|
369 | 429 | def scaled_dot_product_cudnn_attention( |
|
0 commit comments