Skip to content

Commit 8e0550d

Browse files
authored
add specialized interfaces (#309)
1 parent b97bb36 commit 8e0550d

1 file changed

Lines changed: 86 additions & 1 deletion

File tree

tutel/custom/custom_kernel.cpp

Lines changed: 86 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1500,6 +1500,8 @@ torch::Tensor warp_copy_to_device(const std::vector<torch::Tensor> &data) {
15001500
return out;
15011501
}
15021502

1503+
namespace specialized {
1504+
15031505
torch::Tensor warp_glu_expert_bf16xf8_block_scal_16x16_fnuz(
15041506
const torch::Tensor &x,
15051507
const torch::Tensor &expert_ids,
@@ -1540,6 +1542,87 @@ torch::Tensor warp_glu_expert_bf16xf8_block_scal_16x16_fnuz(
15401542
return yb;
15411543
}
15421544

1545+
std::tuple<torch::Tensor, torch::Tensor, torch::Tensor> warp_multi_head_latent_rope_bf16_v2(
1546+
const torch::Tensor &qkv_act,
1547+
const torch::Tensor &cos_sin,
1548+
const torch::Tensor &positions,
1549+
const torch::Tensor &q_a_norm,
1550+
const torch::Tensor &kv_a_norm,
1551+
const torch::Tensor &q_b_proj,
1552+
const torch::Tensor &k_b_proj,
1553+
int64_t n_local_heads
1554+
) {
1555+
auto x = qkv_act;
1556+
CHECK_CUDA(x);
1557+
CHECK_EQ(x.dtype(), torch::kBFloat16);
1558+
CHECK_EQ(x.dim(), 3);
1559+
CHECK_EQ(x.size(-1), 2112);
1560+
CHECK_EQ(cos_sin.dtype(), torch::kInt64);
1561+
CHECK_EQ(positions.dtype(), torch::kInt64);
1562+
1563+
int batch = qkv_act.size(0), seqlen = qkv_act.size(1);
1564+
int samples = batch * seqlen;
1565+
1566+
auto q = warp_rmsnorm_bf16(x, q_a_norm, 1e-6f);
1567+
auto v_output = warp_rmsnorm_bf16(x, kv_a_norm, 1e-6f, 1536); // [B, S, 512]
1568+
auto k_output = antares::ops::call("rope_kt_bf16", {v_output.view({-1, 8, 64}).view(torch::kInt32), cos_sin, x.view({-1, 33, 64}).view(torch::kInt32), positions}, {}).view(torch::kBFloat16).view({batch, seqlen, 576});
1569+
1570+
auto &w_q_b_proj = q_b_proj;
1571+
CHECK_EQ(w_q_b_proj.dtype(), torch::kBFloat16);
1572+
CHECK_EQ(w_q_b_proj.dim(), 2);
1573+
CHECK_EQ(k_b_proj.dtype(), torch::kBFloat16);
1574+
CHECK_EQ(k_b_proj.dim(), 3);
1575+
CHECK_CONTIGUOUS(k_b_proj.transpose(1, 2));
1576+
1577+
auto q_output = torch::empty({batch, seqlen, n_local_heads, 512 + 64}, torch::TensorOptions().dtype(q.dtype()).device(q.device()));
1578+
torch::Tensor qh = (IS_NVIDIA_GPU || samples >= 4) ? torch::matmul(q, w_q_b_proj.t()).view({samples, n_local_heads, -1}) : \
1579+
antares::ops::call("rope_gmv_bf16", {q.view({samples, -1}).view(torch::kInt32), w_q_b_proj.view(torch::kInt32)}, {}).view({samples, n_local_heads, -1}); // (BS, 1536) @ (3072, 1536)
1580+
auto buffer = q_output.flatten(0, 1).transpose(0, 1).narrow(-1, 0, 512);
1581+
torch::matmul_out(buffer, qh.transpose(0, 1).narrow(-1, 0, 128), k_b_proj);
1582+
1583+
antares::ops::call("rope_qt_bf16_put", {cos_sin, qh.view({qh.size(0), -1, 3, 64}).view(torch::kInt32), positions, q_output.view({qh.size(0), -1, 9, 64}).view(torch::kInt32)}, {});
1584+
return {q_output, k_output, v_output};
1585+
}
1586+
1587+
torch::Tensor warp_gemm_nt_bf16xfp8_block_scal(const torch::Tensor &x, const torch::Tensor &w, const torch::Tensor &scal, int64_t policy = 0) {
1588+
CHECK_CUDA(x);
1589+
CHECK_EQ(x.dim(), 3);
1590+
CHECK_EQ(x.dtype(), torch::kBFloat16);
1591+
CHECK_EQ(w.dim(), 2);
1592+
1593+
int samples = x.size(0) * x.size(1);
1594+
if (w.dtype() == torch::kBFloat16)
1595+
return torch::matmul(x.view({samples, x.size(2)}), w.t()).view({x.size(0), x.size(1), w.size(0)});
1596+
1597+
if (scal.dim() == 1) {
1598+
CHECK_EQ(w.size(0), scal.size(0));
1599+
return antares::ops::call("gemv_nt_bf16xfp8_row", {x.view({samples, x.size(2)}).view(torch::kInt32), w.view(torch::kInt16), scal}, {}).view({x.size(0), x.size(1), w.size(0)});
1600+
}
1601+
1602+
CHECK_EQ(scal.dim(), 2);
1603+
if (samples < 4)
1604+
return antares::ops::call("gemv_nt_bf16xfp8_block", {x.view({samples, x.size(2)}).view(torch::kInt32), w.view(torch::kInt16), scal}, {}).view({x.size(0), x.size(1), w.size(0)});
1605+
1606+
torch::Tensor w_ = w;
1607+
1608+
if (policy == 0) {
1609+
static std::unordered_map<void*, torch::Tensor> cached;
1610+
1611+
auto dptr = scal.data_ptr();
1612+
auto it = cached.find(dptr);
1613+
if (it == cached.end()) {
1614+
cached[dptr] = antares::ops::call("to_bfloat16_3d", {w.unsqueeze(0), scal.unsqueeze(0)}, {}).squeeze(0);
1615+
it = cached.find(dptr);
1616+
}
1617+
w_ = it->second;
1618+
} else {
1619+
w_ = antares::ops::call("to_bfloat16_3d", {w.unsqueeze(0), scal.unsqueeze(0)}, {}).squeeze(0);
1620+
}
1621+
return torch::matmul(x.view({samples, x.size(2)}), w_.t()).view({x.size(0), x.size(1), w.size(0)});
1622+
}
1623+
1624+
}
1625+
15431626
#endif
15441627

15451628

@@ -1576,7 +1659,9 @@ TORCH_LIBRARY(tutel_ops, m) {
15761659
m.def("scatter_sample_ids", warp_scatter_sample_ids);
15771660
m.def("copy_to_device", warp_copy_to_device);
15781661

1579-
m.def("glu_expert_bf16xf8_block_scal_16x16_fnuz", warp_glu_expert_bf16xf8_block_scal_16x16_fnuz);
1662+
m.def("multi_head_latent_rope_bf16_v2", specialized::warp_multi_head_latent_rope_bf16_v2);
1663+
m.def("glu_expert_bf16xf8_block_scal_16x16_fnuz", specialized::warp_glu_expert_bf16xf8_block_scal_16x16_fnuz);
1664+
m.def("gemm_nt_bf16xfp8_block_scal", specialized::warp_gemm_nt_bf16xfp8_block_scal);
15801665
#endif
15811666
}
15821667
#endif

0 commit comments

Comments
 (0)