"block_attention_residuals_backward. Install a package containing both training APIs "
"and build block_attention_residuals plus block_attention_residuals_grad. "
"See hyper_parallel/components/functional/README.md."
)
return block_attention_residuals_op
def _block_attention_residuals_fused(prefix: torch.Tensor, history: torch.Tensor,
projection: torch.Tensor, norm_weight: torch.Tensor,
norm_eps: float) -> torch.Tensor:
"""Prepare differentiable inputs and invoke the fused block attention residuals API."""
block_attention_residuals_op = _load_block_attention_residuals()
# Native forward accepts [H], but its training backward requires [1,H].
if projection.ndim == 1:
projection = projection.unsqueeze(0)
inputs = (prefix, history, projection, norm_weight)
common_dtype = prefix.dtype
for tensor in inputs[1:]:
common_dtype = torch.promote_types(common_dtype, tensor.dtype)
# The native API requires one dtype; casts must preserve all four gradient edges.
prepared = tuple(tensor.to(dtype=common_dtype).contiguous() for tensor in inputs)
result = block_attention_residuals_op(*prepared, valid_block_num=-1, norm_eps=norm_eps)
return result.to(torch.promote_types(prefix.dtype, history.dtype))
def block_attention_residuals(prefix: torch.Tensor, history: torch.Tensor,
projection: torch.Tensor, norm_weight: torch.Tensor, *, norm_eps: float,
backend: str = "eager") -> torch.Tensor:
"""Mix previous blocks and the current residual through depth attention.