Skip to content

Commit 3e53a12

Browse files
committed
feat: concept deepseek v2 mla attn
1 parent bba6a25 commit 3e53a12

17 files changed

Lines changed: 325 additions & 14 deletions

File tree

csrc/engine/infer_engine.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,16 @@ InferEngine::InferEngine(
1515
const cache::CacheConfig *cache_config,
1616
bool enable_graph_compiling,
1717
backends::AttentionBackend attention_backend,
18-
std::optional<infinicore::DataType> kv_cache_dtype) // Changed parameter
19-
: communication_group_(distributed_config, device_type), attention_backend_(attention_backend) {
18+
std::optional<infinicore::DataType> kv_cache_dtype,
19+
bool use_mla)
20+
: communication_group_(distributed_config, device_type), attention_backend_(attention_backend), use_mla_(use_mla) {
2021
if (cache_config != nullptr) {
2122
cache_config_ = cache_config->unique_copy();
2223
}
2324

2425
// Load model config if model_path is provided, model_path must be valid, and config.json exists
2526
this->model_config_ = infinilm::config::ConfigFactory::createConfig(config_str);
26-
auto infinilm_config = std::make_shared<infinilm::global_state::InfinilmConfig>(attention_backend, this->model_config_);
27+
auto infinilm_config = std::make_shared<infinilm::global_state::InfinilmConfig>(attention_backend, this->model_config_, use_mla);
2728

2829
// Only support offline int8 kv cache quantization in this version
2930
if (kv_cache_dtype.has_value()) {

csrc/engine/infer_engine.hpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ class InferEngine {
2828
const cache::CacheConfig *cache_config = nullptr,
2929
bool enable_graph_compiling = false,
3030
backends::AttentionBackend attention_backend = backends::AttentionBackend::Default,
31-
std::optional<infinicore::DataType> kv_cache_dtype = std::nullopt);
31+
std::optional<infinicore::DataType> kv_cache_dtype = std::nullopt,
32+
bool use_mla = false);
3233

3334
// Load a parameter to all workers (each can extract its shard inside RankWorker)
3435
void load_param(const std::string &name, const infinicore::Tensor &param);
@@ -68,6 +69,7 @@ class InferEngine {
6869
std::shared_ptr<infinilm::config::ModelConfig> model_config_;
6970
backends::AttentionBackend attention_backend_ = backends::AttentionBackend::Default;
7071
bool weights_finalized_ = false;
72+
bool use_mla_{false};
7173
};
7274

7375
} // namespace infinilm::engine

csrc/global_state/infinilm_config.hpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,15 @@ struct InfinilmConfig {
1414
public:
1515
InfinilmConfig() = default;
1616
InfinilmConfig(const infinilm::backends::AttentionBackend &backend,
17-
const std::shared_ptr<infinilm::config::ModelConfig> &model_config)
17+
const std::shared_ptr<infinilm::config::ModelConfig> &model_config,
18+
bool use_mla = false)
1819
: attention_backend(backend),
20+
use_mla(use_mla),
1921
model_config(model_config) {}
2022

2123
public:
2224
infinilm::backends::AttentionBackend attention_backend;
25+
bool use_mla{false};
2326
std::shared_ptr<infinilm::config::ModelConfig> model_config;
2427
};
2528

csrc/layers/attention/backends/static_attn.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ infinicore::Tensor StaticAttentionImpl::forward(const AttentionLayer &layer,
7979

8080
// Compute attention
8181
size_t ngroup = num_heads_ / num_kv_heads_;
82-
auto Q = q_reshaped->view({batch_size * num_kv_heads_, ngroup * seq_len, head_dim_});
82+
auto Q = q_reshaped->contiguous()->view({batch_size * num_kv_heads_, ngroup * seq_len, head_dim_});
8383
auto K = k_total->view({batch_size * num_kv_heads_, total_seq_len, head_dim_});
8484
auto V = v_total->view({batch_size * num_kv_heads_, total_seq_len, head_dim_});
8585

csrc/models/deepseek_v2/deepseek_v2_decoder_layer.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
#include "deepseek_v2_decoder_layer.hpp"
22

3+
#include "../../global_state/global_state.hpp"
4+
35
namespace infinilm::models::deepseek_v2 {
46

57
DeepseekV2DecoderLayer::DeepseekV2DecoderLayer(std::shared_ptr<infinilm::config::ModelConfig> model_config,
@@ -10,7 +12,11 @@ DeepseekV2DecoderLayer::DeepseekV2DecoderLayer(std::shared_ptr<infinilm::config:
1012
const double rms_norm_eps = model_config->get<double>("rms_norm_eps");
1113
INFINICORE_NN_MODULE_INIT(input_layernorm, hidden_size, rms_norm_eps, dtype, device);
1214
INFINICORE_NN_MODULE_INIT(post_attention_layernorm, hidden_size, rms_norm_eps, dtype, device);
13-
INFINICORE_NN_MODULE_INIT(self_attn, model_config, layer_idx, device);
15+
if (infinilm::global_state::get_infinilm_config().use_mla) {
16+
self_attn_ = std::make_shared<DeepseekV2SelfAttention>(this->register_module<DeepseekV2MLAAttention>("self_attn", model_config, layer_idx, device));
17+
} else {
18+
self_attn_ = std::make_shared<DeepseekV2SelfAttention>(this->register_module<DeepseekV2Attention>("self_attn", model_config, layer_idx, device));
19+
}
1420

1521
const size_t first_k_dense_replace = model_config->get_or<size_t>("first_k_dense_replace", 0);
1622
const size_t moe_layer_freq = model_config->get_or<size_t>("moe_layer_freq", 1);
@@ -29,7 +35,8 @@ DeepseekV2DecoderLayer::forward(const infinicore::Tensor &positions,
2935
infinicore::Tensor &hidden_states,
3036
infinicore::Tensor &residual) const {
3137
input_layernorm_->forward_inplace(hidden_states, residual);
32-
hidden_states = self_attn_->forward(positions, hidden_states);
38+
hidden_states = std::visit(
39+
[&](auto &attn_ptr) { return attn_ptr->forward(positions, hidden_states); }, *self_attn_);
3340
post_attention_layernorm_->forward_inplace(hidden_states, residual);
3441
hidden_states = use_moe_ ? moe_mlp_->forward(hidden_states) : dense_mlp_->forward(hidden_states);
3542
return {hidden_states, residual};

csrc/models/deepseek_v2/deepseek_v2_decoder_layer.hpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
#include "../../config/model_config.hpp"
44
#include "deepseek_v2_attention.hpp"
5+
#include "deepseek_v2_mla_attention.hpp"
56
#include "deepseek_v2_moe.hpp"
67
#include "infinicore/device.hpp"
78
#include "infinicore/nn/module.hpp"
@@ -10,9 +11,12 @@
1011

1112
#include <memory>
1213
#include <tuple>
14+
#include <variant>
1315

1416
namespace infinilm::models::deepseek_v2 {
1517

18+
using DeepseekV2SelfAttention = std::variant<std::shared_ptr<DeepseekV2Attention>, std::shared_ptr<DeepseekV2MLAAttention>>;
19+
1620
class DeepseekV2DecoderLayer : public infinicore::nn::Module {
1721
public:
1822
DeepseekV2DecoderLayer(std::shared_ptr<infinilm::config::ModelConfig> model_config,
@@ -26,7 +30,7 @@ class DeepseekV2DecoderLayer : public infinicore::nn::Module {
2630
private:
2731
INFINICORE_NN_MODULE(infinicore::nn::RMSNorm, input_layernorm);
2832
INFINICORE_NN_MODULE(infinicore::nn::RMSNorm, post_attention_layernorm);
29-
INFINICORE_NN_MODULE(DeepseekV2Attention, self_attn);
33+
INFINICORE_NN_MODULE(DeepseekV2SelfAttention, self_attn);
3034
INFINICORE_NN_MODULE(DeepseekV2MLP, dense_mlp);
3135
INFINICORE_NN_MODULE(DeepseekV2MoE, moe_mlp);
3236
bool use_moe_{false};
Lines changed: 200 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
#include "deepseek_v2_mla_attention.hpp"
2+
3+
#include "../../global_state/global_state.hpp"
4+
#include "../../utils.hpp"
5+
#include "infinicore/ops.hpp"
6+
#include "infinicore/ops/cat.hpp"
7+
#include "infinicore/ops/pad.hpp"
8+
9+
#include <cmath>
10+
#include <stdexcept>
11+
12+
namespace infinilm::models::deepseek_v2 {
13+
namespace {
14+
15+
float yarn_get_mscale(float scale, float mscale) {
16+
if (scale <= 1.0f) {
17+
return 1.0f;
18+
}
19+
return 0.1f * mscale * std::log(scale) + 1.0f;
20+
}
21+
22+
} // namespace
23+
24+
DeepseekV2MLAAttention::DeepseekV2MLAAttention(std::shared_ptr<infinilm::config::ModelConfig> model_config,
25+
size_t layer_idx,
26+
const infinicore::Device &device) {
27+
layer_idx_ = layer_idx;
28+
hidden_size_ = model_config->get<size_t>("hidden_size");
29+
qk_nope_head_dim_ = model_config->get<size_t>("qk_nope_head_dim");
30+
qk_rope_head_dim_ = model_config->get<size_t>("qk_rope_head_dim");
31+
q_head_dim_ = qk_nope_head_dim_ + qk_rope_head_dim_;
32+
v_head_dim_ = model_config->get<size_t>("v_head_dim");
33+
kv_lora_rank_ = model_config->get<size_t>("kv_lora_rank");
34+
mla_head_dim_ = kv_lora_rank_ + qk_rope_head_dim_;
35+
36+
if (model_config->get_or<size_t>("q_lora_rank", 0) != 0) {
37+
throw std::runtime_error("DeepseekV2MLAAttention: q_lora_rank is not supported yet");
38+
}
39+
40+
const auto &dtype{model_config->get_dtype()};
41+
const size_t total_num_heads = model_config->get<size_t>("num_attention_heads");
42+
const bool attention_bias = model_config->get_or<bool>("attention_bias", false);
43+
const double rms_norm_eps = model_config->get<double>("rms_norm_eps");
44+
45+
const auto &rank_info = infinilm::global_state::get_tensor_model_parallel_rank_info();
46+
const int tp_rank = rank_info.tp_rank;
47+
const int tp_size = rank_info.tp_size;
48+
if ((total_num_heads < static_cast<size_t>(tp_size)) || (total_num_heads % static_cast<size_t>(tp_size) != 0)) {
49+
throw std::runtime_error("DeepseekV2MLAAttention: num_attention_heads must be divisible by tp_size");
50+
}
51+
num_attention_heads_ = total_num_heads / static_cast<size_t>(tp_size);
52+
attention_backend_ = infinilm::global_state::get_infinilm_config().attention_backend;
53+
54+
auto quantization_method = model_config->get_quantization_method();
55+
INFINICORE_NN_MODULE_INIT(q_proj, hidden_size_, total_num_heads * q_head_dim_, quantization_method, false, dtype, device, tp_rank, tp_size);
56+
INFINICORE_NN_MODULE_INIT(kv_a_proj_with_mqa, hidden_size_, kv_lora_rank_ + qk_rope_head_dim_, attention_bias, dtype, device);
57+
INFINICORE_NN_MODULE_INIT(kv_a_layernorm, kv_lora_rank_, rms_norm_eps, dtype, device);
58+
INFINICORE_NN_MODULE_INIT(kv_b_proj, kv_lora_rank_, total_num_heads * (qk_nope_head_dim_ + v_head_dim_), quantization_method, false, dtype, device, tp_rank, tp_size);
59+
INFINICORE_NN_MODULE_INIT(o_proj, total_num_heads * v_head_dim_, hidden_size_, quantization_method, attention_bias, dtype, device, tp_rank, tp_size, rank_info.comm);
60+
61+
const size_t max_position_embeddings = model_config->get<size_t>("max_position_embeddings");
62+
const double rope_theta = model_config->get<double>("rope_theta");
63+
rotary_emb_ = std::make_shared<infinicore::nn::RoPE>(
64+
qk_rope_head_dim_, qk_rope_head_dim_, max_position_embeddings, rope_theta,
65+
infinicore::nn::RoPE::Algo::GPT_J, dtype, device, nullptr);
66+
67+
softmax_scale_ = 1.0f / std::sqrt(static_cast<float>(q_head_dim_));
68+
auto &config_json = model_config->get_config_json();
69+
if (config_json.contains("rope_scaling") && config_json["rope_scaling"].is_object()) {
70+
const auto &rope_scaling = config_json["rope_scaling"];
71+
const float mscale_all_dim = rope_scaling.value("mscale_all_dim", 0.0f);
72+
if (mscale_all_dim != 0.0f) {
73+
const float scaling_factor = rope_scaling.value("factor", 1.0f);
74+
const float mscale = yarn_get_mscale(scaling_factor, mscale_all_dim);
75+
softmax_scale_ *= mscale * mscale;
76+
}
77+
}
78+
79+
latent_attn_ = std::make_shared<infinilm::layers::attention::AttentionLayer>(
80+
num_attention_heads_, mla_head_dim_, softmax_scale_, 1, layer_idx_,
81+
kv_cache_k_scale_, kv_cache_v_scale_, attention_backend_);
82+
infinilm::layers::attention::init_kv_cache_quant_params(
83+
[this](const std::string &n, infinicore::nn::Parameter p) { this->register_parameter(n, std::move(p)); },
84+
device, kv_cache_k_scale_, kv_cache_v_scale_);
85+
}
86+
87+
infinicore::Tensor DeepseekV2MLAAttention::position_ids_for_rope_(const infinicore::Tensor &position_ids) const {
88+
auto pos_shape = position_ids->shape();
89+
if (pos_shape.size() == 2) {
90+
return position_ids->narrow({{0, 0, 1}})->contiguous()->view({pos_shape[1]});
91+
}
92+
if (pos_shape.size() == 1) {
93+
return position_ids->contiguous();
94+
}
95+
throw std::runtime_error("DeepseekV2MLAAttention: unexpected position_ids shape");
96+
}
97+
98+
infinicore::Tensor DeepseekV2MLAAttention::kv_b_weight_3d_() const {
99+
return kv_b_proj_->weight()->view({num_attention_heads_, qk_nope_head_dim_ + v_head_dim_, kv_lora_rank_});
100+
}
101+
102+
infinicore::Tensor DeepseekV2MLAAttention::project_q_nope_to_latent_(const infinicore::Tensor &q_nope) const {
103+
const size_t ntokens = q_nope->shape()[0];
104+
auto q_nope_by_head = q_nope->permute({1, 0, 2})->contiguous();
105+
auto w_uk_t = kv_b_weight_3d_()->narrow({{1, 0, qk_nope_head_dim_}})->contiguous();
106+
auto q_latent = infinicore::op::matmul(q_nope_by_head, w_uk_t);
107+
return q_latent->permute({1, 0, 2})->contiguous()->view({ntokens, num_attention_heads_, kv_lora_rank_});
108+
}
109+
110+
infinicore::Tensor DeepseekV2MLAAttention::project_latent_to_value_(const infinicore::Tensor &attn_output,
111+
size_t batch_size,
112+
size_t seq_len) const {
113+
const size_t ntokens = batch_size * seq_len;
114+
auto latent = attn_output->view({ntokens, num_attention_heads_, mla_head_dim_})
115+
->narrow({{2, 0, kv_lora_rank_}})
116+
->contiguous();
117+
auto latent_by_head = latent->permute({1, 0, 2})->contiguous();
118+
auto w_uv = kv_b_weight_3d_()
119+
->narrow({{1, qk_nope_head_dim_, v_head_dim_}})
120+
->permute({0, 2, 1})
121+
->contiguous();
122+
auto value = infinicore::op::matmul(latent_by_head, w_uv)
123+
->permute({1, 0, 2})
124+
->contiguous()
125+
->view({batch_size, seq_len, num_attention_heads_ * v_head_dim_});
126+
return o_proj_->forward(value);
127+
}
128+
129+
infinicore::Tensor DeepseekV2MLAAttention::forward(const infinicore::Tensor &positions,
130+
const infinicore::Tensor &hidden_states) const {
131+
if (::infinilm::backends::AttentionBackend::STATIC_ATTN == attention_backend_) {
132+
return forward_static_(positions, hidden_states);
133+
}
134+
return forward_paged_(positions, hidden_states);
135+
}
136+
137+
infinicore::Tensor DeepseekV2MLAAttention::forward_static_(const infinicore::Tensor &position_ids,
138+
const infinicore::Tensor &hidden_states) const {
139+
auto shape = hidden_states->shape();
140+
const size_t batch_size = shape[0];
141+
const size_t seq_len = shape[1];
142+
const size_t ntokens = batch_size * seq_len;
143+
auto hidden_states_mutable = hidden_states;
144+
145+
auto q = q_proj_->forward(hidden_states_mutable)->view({ntokens, num_attention_heads_, q_head_dim_});
146+
auto q_nope = q->narrow({{2, 0, qk_nope_head_dim_}})->contiguous();
147+
auto q_pe = q->narrow({{2, qk_nope_head_dim_, qk_rope_head_dim_}})->contiguous();
148+
149+
auto compressed = kv_a_proj_with_mqa_->forward(hidden_states_mutable)->view({ntokens, kv_lora_rank_ + qk_rope_head_dim_});
150+
auto compressed_kv = compressed->narrow({{1, 0, kv_lora_rank_}})->contiguous();
151+
auto k_pe = compressed->narrow({{1, kv_lora_rank_, qk_rope_head_dim_}})->contiguous();
152+
153+
auto kv_norm = kv_a_layernorm_->forward(compressed_kv);
154+
auto pos_ids = position_ids_for_rope_(position_ids);
155+
q_pe = rotary_emb_->forward(q_pe, pos_ids, true);
156+
auto k_pe_rope = rotary_emb_->forward(k_pe->view({ntokens, 1, qk_rope_head_dim_}), pos_ids, true);
157+
158+
auto q_latent = project_q_nope_to_latent_(q_nope);
159+
auto query_states = infinicore::op::cat({q_latent, q_pe}, 2)->view({batch_size, seq_len, num_attention_heads_, mla_head_dim_});
160+
auto key_states = infinicore::op::cat({kv_norm->view({ntokens, 1, kv_lora_rank_}), k_pe_rope}, 2)
161+
->view({batch_size, seq_len, 1, mla_head_dim_});
162+
auto value_states = infinicore::op::pad(kv_norm->view({batch_size, seq_len, 1, kv_lora_rank_}),
163+
{0, static_cast<int>(qk_rope_head_dim_)}, "constant", 0.0);
164+
165+
auto attn_output = latent_attn_->forward(query_states, key_states, value_states);
166+
return project_latent_to_value_(attn_output, batch_size, seq_len);
167+
}
168+
169+
infinicore::Tensor DeepseekV2MLAAttention::forward_paged_(const infinicore::Tensor &position_ids,
170+
const infinicore::Tensor &hidden_states) const {
171+
auto shape = hidden_states->shape();
172+
const size_t batch_size = shape[0];
173+
const size_t seq_len = shape[1];
174+
ASSERT_EQ(batch_size, 1);
175+
auto hidden_states_mutable = hidden_states;
176+
177+
auto q = q_proj_->forward(hidden_states_mutable)->view({seq_len, num_attention_heads_, q_head_dim_});
178+
auto q_nope = q->narrow({{2, 0, qk_nope_head_dim_}})->contiguous();
179+
auto q_pe = q->narrow({{2, qk_nope_head_dim_, qk_rope_head_dim_}})->contiguous();
180+
181+
auto compressed = kv_a_proj_with_mqa_->forward(hidden_states_mutable)->view({seq_len, kv_lora_rank_ + qk_rope_head_dim_});
182+
auto compressed_kv = compressed->narrow({{1, 0, kv_lora_rank_}})->contiguous();
183+
auto k_pe = compressed->narrow({{1, kv_lora_rank_, qk_rope_head_dim_}})->contiguous();
184+
185+
auto kv_norm = kv_a_layernorm_->forward(compressed_kv);
186+
auto pos_ids = position_ids_for_rope_(position_ids);
187+
q_pe = rotary_emb_->forward(q_pe, pos_ids, true);
188+
auto k_pe_rope = rotary_emb_->forward(k_pe->view({seq_len, 1, qk_rope_head_dim_}), pos_ids, true);
189+
190+
auto q_latent = project_q_nope_to_latent_(q_nope);
191+
auto query_states = infinicore::op::cat({q_latent, q_pe}, 2);
192+
auto key_states = infinicore::op::cat({kv_norm->view({seq_len, 1, kv_lora_rank_}), k_pe_rope}, 2);
193+
auto value_states = infinicore::op::pad(kv_norm->view({seq_len, 1, kv_lora_rank_}),
194+
{0, static_cast<int>(qk_rope_head_dim_)}, "constant", 0.0);
195+
196+
auto attn_output = latent_attn_->forward(query_states, key_states, value_states);
197+
return project_latent_to_value_(attn_output, batch_size, seq_len);
198+
}
199+
200+
} // namespace infinilm::models::deepseek_v2
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
#pragma once
2+
3+
#include "../../backends/attention_backends.hpp"
4+
#include "../../config/model_config.hpp"
5+
#include "../../layers/attention/attention.hpp"
6+
#include "../../layers/linear/linear.hpp"
7+
#include "infinicore/nn/module.hpp"
8+
#include "infinicore/nn/rmsnorm.hpp"
9+
#include "infinicore/nn/rope.hpp"
10+
#include "infinicore/tensor.hpp"
11+
12+
#include <memory>
13+
14+
namespace infinilm::models::deepseek_v2 {
15+
16+
class DeepseekV2MLAAttention : public infinicore::nn::Module {
17+
public:
18+
DeepseekV2MLAAttention(std::shared_ptr<infinilm::config::ModelConfig> model_config,
19+
size_t layer_idx,
20+
const infinicore::Device &device);
21+
22+
infinicore::Tensor forward(const infinicore::Tensor &positions,
23+
const infinicore::Tensor &hidden_states) const;
24+
25+
private:
26+
infinicore::Tensor forward_static_(const infinicore::Tensor &positions,
27+
const infinicore::Tensor &hidden_states) const;
28+
infinicore::Tensor forward_paged_(const infinicore::Tensor &positions,
29+
const infinicore::Tensor &hidden_states) const;
30+
infinicore::Tensor position_ids_for_rope_(const infinicore::Tensor &position_ids) const;
31+
infinicore::Tensor kv_b_weight_3d_() const;
32+
infinicore::Tensor project_q_nope_to_latent_(const infinicore::Tensor &q_nope) const;
33+
infinicore::Tensor project_latent_to_value_(const infinicore::Tensor &attn_output,
34+
size_t batch_size,
35+
size_t seq_len) const;
36+
37+
size_t layer_idx_{0};
38+
size_t hidden_size_{0};
39+
size_t num_attention_heads_{0};
40+
size_t qk_nope_head_dim_{0};
41+
size_t qk_rope_head_dim_{0};
42+
size_t q_head_dim_{0};
43+
size_t v_head_dim_{0};
44+
size_t kv_lora_rank_{0};
45+
size_t mla_head_dim_{0};
46+
float softmax_scale_{1.0f};
47+
infinilm::backends::AttentionBackend attention_backend_;
48+
49+
INFINICORE_NN_MODULE(infinilm::layers::linear::ColumnParallelLinear, q_proj);
50+
INFINICORE_NN_MODULE(infinilm::layers::linear::ReplicatedLinear, kv_a_proj_with_mqa);
51+
INFINICORE_NN_MODULE(infinicore::nn::RMSNorm, kv_a_layernorm);
52+
INFINICORE_NN_MODULE(infinilm::layers::linear::ColumnParallelLinear, kv_b_proj);
53+
INFINICORE_NN_MODULE(infinilm::layers::linear::RowParallelLinear, o_proj);
54+
55+
std::shared_ptr<infinicore::nn::RoPE> rotary_emb_;
56+
std::shared_ptr<infinilm::layers::attention::AttentionLayer> latent_attn_;
57+
infinicore::nn::Parameter kv_cache_k_scale_;
58+
infinicore::nn::Parameter kv_cache_v_scale_;
59+
};
60+
61+
} // namespace infinilm::models::deepseek_v2

0 commit comments

Comments
 (0)