Files
2026-07-13 13:18:33 +08:00

342 lines
19 KiB
Python

# SPDX-License-Identifier: Apache-2.0
# DeepSpeed Team
"""
SUPA Transformer Inference op builder.
"""
try:
import torch
import torch_supa_ext.deepspeed # noqa: F401 — registers torch.ops.deepspeed
except ImportError:
pass
from .builder import SUPAOpBuilder
class SUPAInference:
"""Python wrapper around the SUPA compiled inference kernels.
Each static method delegates to the corresponding torch.ops.deepspeed
function, mirroring the interface that DeepSpeed's op_binding layer
expects from inference_module.
"""
@staticmethod
def _op(name):
"""Return torch.ops.deepspeed.<name>, raising clearly if not registered."""
import torch # ensure torch is available at runtime
if not hasattr(torch.ops, 'deepspeed') or not hasattr(torch.ops.deepspeed, name):
raise RuntimeError(f"torch.ops.deepspeed.{name} is not available. "
"Ensure torch_supa_ext is built with the transformer inference extension.")
return getattr(torch.ops.deepspeed, name)
# ── workspace management ────────────────────────────────────────────────
@staticmethod
def allocate_workspace_fp16(hidden_dim, heads, sequence_length, num_layers, batch_size, mp_size, bigscience_bloom,
seed, max_out_tokens, min_out_tokens):
return SUPAInference._op('allocate_workspace_fp16')(hidden_dim, heads, sequence_length, num_layers, batch_size,
mp_size, bigscience_bloom, seed, max_out_tokens,
min_out_tokens)
@staticmethod
def allocate_workspace_bf16(hidden_dim, heads, sequence_length, num_layers, batch_size, mp_size, bigscience_bloom,
seed, max_out_tokens, min_out_tokens):
return SUPAInference._op('allocate_workspace_bf16')(hidden_dim, heads, sequence_length, num_layers, batch_size,
mp_size, bigscience_bloom, seed, max_out_tokens,
min_out_tokens)
@staticmethod
def allocate_workspace_fp32(hidden_dim, heads, sequence_length, num_layers, batch_size, mp_size, bigscience_bloom,
seed, max_out_tokens, min_out_tokens):
return SUPAInference._op('allocate_workspace_fp32')(hidden_dim, heads, sequence_length, num_layers, batch_size,
mp_size, bigscience_bloom, seed, max_out_tokens,
min_out_tokens)
@staticmethod
def release_workspace():
return SUPAInference._op('release_workspace')()
@staticmethod
def retake_workspace():
return SUPAInference._op('retake_workspace')()
@staticmethod
def reset_cache():
return SUPAInference._op('reset_cache')()
# ── normalisation ────────────────────────────────────────────────────────
@staticmethod
def layer_norm(inputs, gamma, beta, epsilon):
return SUPAInference._op('layer_norm')(inputs, gamma, beta, epsilon)
@staticmethod
def rms_norm(inputs, gamma, epsilon):
return SUPAInference._op('rms_norm')(inputs, gamma, epsilon)
@staticmethod
def pre_rms_norm(inputs, residual, gamma, epsilon):
return SUPAInference._op('pre_rms_norm')(inputs, residual, gamma, epsilon)
# ── softmax ──────────────────────────────────────────────────────────────
@staticmethod
def softmax_fp16(scores, mask, alibi, triangular, recompute, local_attention, window_size, async_op, layer_scale,
head_offset, mp_size):
return SUPAInference._op('softmax_fp16')(scores, mask, alibi, triangular, recompute, local_attention,
window_size, async_op, layer_scale, head_offset, mp_size)
@staticmethod
def softmax_bf16(scores, mask, alibi, triangular, recompute, local_attention, window_size, async_op, layer_scale,
head_offset, mp_size):
return SUPAInference._op('softmax_bf16')(scores, mask, alibi, triangular, recompute, local_attention,
window_size, async_op, layer_scale, head_offset, mp_size)
@staticmethod
def softmax_fp32(scores, mask, alibi, triangular, recompute, local_attention, window_size, async_op, layer_scale,
head_offset, mp_size):
return SUPAInference._op('softmax_fp32')(scores, mask, alibi, triangular, recompute, local_attention,
window_size, async_op, layer_scale, head_offset, mp_size)
@staticmethod
def softmax_context_fp16(query_key_value, attn_mask, rotary_dim, rotate_half, rotate_every_two, heads, num_kv,
norm_factor, triangular_masking, local_attention, window_size, no_masking, layer_id,
num_layers, alibi, rope_theta, is_prompt, token_idx, position_ids):
return SUPAInference._op('softmax_context_fp16')(query_key_value, attn_mask, rotary_dim, rotate_half,
rotate_every_two, heads, num_kv, norm_factor,
triangular_masking, local_attention, window_size, no_masking,
layer_id, num_layers, alibi, rope_theta, is_prompt, token_idx,
position_ids)
@staticmethod
def softmax_context_bf16(query_key_value, attn_mask, rotary_dim, rotate_half, rotate_every_two, heads, num_kv,
norm_factor, triangular_masking, local_attention, window_size, no_masking, layer_id,
num_layers, alibi, rope_theta, is_prompt, token_idx, position_ids):
return SUPAInference._op('softmax_context_bf16')(query_key_value, attn_mask, rotary_dim, rotate_half,
rotate_every_two, heads, num_kv, norm_factor,
triangular_masking, local_attention, window_size, no_masking,
layer_id, num_layers, alibi, rope_theta, is_prompt, token_idx,
position_ids)
@staticmethod
def softmax_context_fp32(query_key_value, attn_mask, rotary_dim, rotate_half, rotate_every_two, heads, num_kv,
norm_factor, triangular_masking, local_attention, window_size, no_masking, layer_id,
num_layers, alibi, rope_theta, is_prompt, token_idx, position_ids):
return SUPAInference._op('softmax_context_fp32')(query_key_value, attn_mask, rotary_dim, rotate_half,
rotate_every_two, heads, num_kv, norm_factor,
triangular_masking, local_attention, window_size, no_masking,
layer_id, num_layers, alibi, rope_theta, is_prompt, token_idx,
position_ids)
# ── bias ops ─────────────────────────────────────────────────────────────
@staticmethod
def bias_add_fp16(input, bias):
return SUPAInference._op('bias_add_fp16')(input, bias)
@staticmethod
def bias_add_bf16(input, bias):
return SUPAInference._op('bias_add_bf16')(input, bias)
@staticmethod
def bias_add_fp32(input, bias):
return SUPAInference._op('bias_add_fp32')(input, bias)
@staticmethod
def bias_gelu_fp16(input, bias):
return SUPAInference._op('bias_gelu_fp16')(input, bias)
@staticmethod
def bias_gelu_bf16(input, bias):
return SUPAInference._op('bias_gelu_bf16')(input, bias)
@staticmethod
def bias_gelu_fp32(input, bias):
return SUPAInference._op('bias_gelu_fp32')(input, bias)
@staticmethod
def bias_relu_fp16(input, bias):
return SUPAInference._op('bias_relu_fp16')(input, bias)
@staticmethod
def bias_relu_bf16(input, bias):
return SUPAInference._op('bias_relu_bf16')(input, bias)
@staticmethod
def bias_relu_fp32(input, bias):
return SUPAInference._op('bias_relu_fp32')(input, bias)
@staticmethod
def bias_residual_fp16(input, residual, bias):
return SUPAInference._op('bias_residual_fp16')(input, residual, bias)
@staticmethod
def bias_residual_fp32(input, residual, bias):
return SUPAInference._op('bias_residual_fp32')(input, residual, bias)
@staticmethod
def residual_add_bias_fp16(hidden_state, residual, attention_output, attention_bias, final_bias, mp_size,
mlp_after_attn, add_bias, pre_layer_norm):
return SUPAInference._op('residual_add_bias_fp16')(hidden_state, residual, attention_output, attention_bias,
final_bias, mp_size, mlp_after_attn, add_bias,
pre_layer_norm)
@staticmethod
def residual_add_bias_bf16(hidden_state, residual, attention_output, attention_bias, final_bias, mp_size,
mlp_after_attn, add_bias, pre_layer_norm):
return SUPAInference._op('residual_add_bias_bf16')(hidden_state, residual, attention_output, attention_bias,
final_bias, mp_size, mlp_after_attn, add_bias,
pre_layer_norm)
@staticmethod
def residual_add_bias_fp32(hidden_state, residual, attention_output, attention_bias, final_bias, mp_size,
mlp_after_attn, add_bias, pre_layer_norm):
return SUPAInference._op('residual_add_bias_fp32')(hidden_state, residual, attention_output, attention_bias,
final_bias, mp_size, mlp_after_attn, add_bias,
pre_layer_norm)
# ── QKV GEMM ─────────────────────────────────────────────────────────────
@staticmethod
def qkv_gemm_fp16(inputs, weight, q_scale, bias, gamma, beta, eps, add_bias, q_int8, transpose):
return SUPAInference._op('qkv_gemm_fp16')(inputs, weight, q_scale, bias, gamma, beta, eps, add_bias, q_int8,
transpose)
@staticmethod
def qkv_gemm_bf16(inputs, weight, q_scale, bias, gamma, beta, eps, add_bias, q_int8, transpose):
return SUPAInference._op('qkv_gemm_bf16')(inputs, weight, q_scale, bias, gamma, beta, eps, add_bias, q_int8,
transpose)
@staticmethod
def qkv_gemm_fp32(inputs, weight, q_scale, bias, gamma, beta, eps, add_bias, q_int8, transpose):
return SUPAInference._op('qkv_gemm_fp32')(inputs, weight, q_scale, bias, gamma, beta, eps, add_bias, q_int8,
transpose)
@staticmethod
def rms_qkv_gemm_fp16(inputs, weight, q_scale, gamma, eps, q_int8, transpose):
return SUPAInference._op('rms_qkv_gemm_fp16')(inputs, weight, q_scale, gamma, eps, q_int8, transpose)
@staticmethod
def rms_qkv_gemm_bf16(inputs, weight, q_scale, gamma, eps, q_int8, transpose):
return SUPAInference._op('rms_qkv_gemm_bf16')(inputs, weight, q_scale, gamma, eps, q_int8, transpose)
# ── MLP GEMM ─────────────────────────────────────────────────────────────
@staticmethod
def mlp_gemm_fp16(input, residual, input_bias, weight_interm, weight_out, bias, gamma, beta, eps, pre_layer_norm,
mlp_after_attn, interm_scale, out_scale, q_int8, act_func_type, transpose):
return SUPAInference._op('mlp_gemm_fp16')(input, residual, input_bias, weight_interm, weight_out, bias, gamma,
beta, eps, pre_layer_norm, mlp_after_attn, interm_scale, out_scale,
q_int8, act_func_type, transpose)
@staticmethod
def mlp_gemm_bf16(input, residual, input_bias, weight_interm, weight_out, bias, gamma, beta, eps, pre_layer_norm,
mlp_after_attn, interm_scale, out_scale, q_int8, act_func_type, transpose):
return SUPAInference._op('mlp_gemm_bf16')(input, residual, input_bias, weight_interm, weight_out, bias, gamma,
beta, eps, pre_layer_norm, mlp_after_attn, interm_scale, out_scale,
q_int8, act_func_type, transpose)
@staticmethod
def mlp_gemm_fp32(input, residual, input_bias, weight_interm, weight_out, bias, gamma, beta, eps, pre_layer_norm,
mlp_after_attn, interm_scale, out_scale, q_int8, act_func_type, transpose):
return SUPAInference._op('mlp_gemm_fp32')(input, residual, input_bias, weight_interm, weight_out, bias, gamma,
beta, eps, pre_layer_norm, mlp_after_attn, interm_scale, out_scale,
q_int8, act_func_type, transpose)
@staticmethod
def rms_mlp_gemm_fp16(input, residual, weight_interm, weight_out, gamma, eps, interm_scale, out_scale, q_int8,
act_func_type, transpose):
return SUPAInference._op('rms_mlp_gemm_fp16')(input, residual, weight_interm, weight_out, gamma, eps,
interm_scale, out_scale, q_int8, act_func_type, transpose)
@staticmethod
def rms_mlp_gemm_bf16(input, residual, weight_interm, weight_out, gamma, eps, interm_scale, out_scale, q_int8,
act_func_type, transpose):
return SUPAInference._op('rms_mlp_gemm_bf16')(input, residual, weight_interm, weight_out, gamma, eps,
interm_scale, out_scale, q_int8, act_func_type, transpose)
# ── vector / linear ops ──────────────────────────────────────────────────
@staticmethod
def vector_matmul_fp16(input, weight, async_op, q_scale, q_int8, transposed_mode):
return SUPAInference._op('vector_matmul_fp16')(input, weight, async_op, q_scale, q_int8, transposed_mode)
@staticmethod
def vector_matmul_bf16(input, weight, async_op, q_scale, q_int8, transposed_mode):
return SUPAInference._op('vector_matmul_bf16')(input, weight, async_op, q_scale, q_int8, transposed_mode)
@staticmethod
def vector_matmul_fp32(input, weight, async_op, q_scale, q_int8, transposed_mode):
return SUPAInference._op('vector_matmul_fp32')(input, weight, async_op, q_scale, q_int8, transposed_mode)
@staticmethod
def linear_layer_fp16(input, weight, bias, add_bias, do_flash_attn, num_heads, transposed_mode, rope_theta):
return SUPAInference._op('linear_layer_fp16')(input, weight, bias, add_bias, do_flash_attn, num_heads,
transposed_mode, rope_theta)
@staticmethod
def linear_layer_bf16(input, weight, bias, add_bias, do_flash_attn, num_heads, transposed_mode, rope_theta):
return SUPAInference._op('linear_layer_bf16')(input, weight, bias, add_bias, do_flash_attn, num_heads,
transposed_mode, rope_theta)
@staticmethod
def linear_layer_fp32(input, weight, bias, add_bias, do_flash_attn, num_heads, transposed_mode, rope_theta):
return SUPAInference._op('linear_layer_fp32')(input, weight, bias, add_bias, do_flash_attn, num_heads,
transposed_mode, rope_theta)
@staticmethod
def _vector_add(a, b, gamma):
return SUPAInference._op('_vector_add')(a, b, gamma)
# ── transform / rotary ops ───────────────────────────────────────────────
@staticmethod
def pad_transform_fp16(query, key, value, heads, add_padding):
return SUPAInference._op('pad_transform_fp16')(query, key, value, heads, add_padding)
@staticmethod
def apply_rotary_pos_emb(mixed_query, key_layer, rotary_dim, offset, num_heads, rotate_half, rope_theta):
return SUPAInference._op('apply_rotary_pos_emb')(mixed_query, key_layer, rotary_dim, offset, num_heads,
rotate_half, rope_theta)
# ── einsum / MoE ─────────────────────────────────────────────────────────
@staticmethod
def einsum_sec_sm_ecm_fp16(Q, W):
return SUPAInference._op('einsum_sec_sm_ecm_fp16')(Q, W)
@staticmethod
def einsum_sec_sm_ecm_fp32(Q, W):
return SUPAInference._op('einsum_sec_sm_ecm_fp32')(Q, W)
@staticmethod
def moe_res_matmul(moe_res, coef, output):
return SUPAInference._op('moe_res_matmul')(moe_res, coef, output)
# ── activation ops ───────────────────────────────────────────────────────
@staticmethod
def gated_activation(activation_func_type, vals, bias):
return SUPAInference._op('gated_activation')(activation_func_type, vals, bias)
class InferenceBuilder(SUPAOpBuilder):
BUILD_VAR = "DS_BUILD_TRANSFORMER_INFERENCE"
NAME = "transformer_inference"
def __init__(self):
super().__init__(name=self.NAME)
def absolute_name(self):
return f'deepspeed.ops.transformer.inference.{self.NAME}_op'
def sources(self):
return []
def load(self, verbose=True):
return SUPAInference
def is_compatible(self, verbose=False):
return hasattr(torch.ops, 'deepspeed') and hasattr(torch.ops.deepspeed, 'allocate_workspace_fp16')