krishnateja95 commited on
Commit
de25cee
·
verified ·
1 Parent(s): 1f3247a

Upload folder using huggingface_hub

Browse files
config.json CHANGED
@@ -1,40 +1,40 @@
1
  {
2
  "architectures": [
3
- "SarvamMoEForCausalLM"
4
  ],
5
  "attention_dropout": 0.0,
6
  "attn_implementation": null,
7
  "auto_map": {
8
- "AutoConfig": "configuration_sarvam_moe.SarvamMoEConfig",
9
- "AutoModel": "modeling_sarvam_moe.SarvamMoEModel",
10
- "AutoModelForCausalLM": "modeling_sarvam_moe.SarvamMoEForCausalLM"
11
  },
 
12
  "dtype": "float32",
13
  "embedding_dropout": 0.0,
14
  "eos_token_id": 1,
15
  "first_k_dense_replace": 1,
16
- "head_dim": 64,
17
  "hidden_act": "silu",
18
  "hidden_size": 4096,
19
  "initializer_range": 0.006,
20
- "intermediate_size": 8192,
 
21
  "max_position_embeddings": 131072,
22
- "max_window_layers": 19,
23
- "model_type": "sarvam_moe",
24
- "moe_intermediate_size": 1024,
25
  "moe_router_enable_expert_bias": true,
26
- "moe_shared_expert_intermediate_size": 1024,
27
- "n_group": 1,
28
- "norm_topk_prob": true,
29
  "num_attention_heads": 64,
30
  "num_experts": 128,
31
- "num_experts_per_tok": 6,
32
- "num_hidden_layers": 19,
33
- "num_key_value_heads": 4,
34
  "num_shared_experts": 1,
35
  "output_dropout": 0.0,
36
  "output_router_logits": false,
37
  "pad_token_id": 0,
 
 
 
38
  "quantization_config": {
39
  "config_groups": {
40
  "group_0": {
@@ -86,18 +86,21 @@
86
  "version": "0.14.0"
87
  },
88
  "rms_norm_eps": 1e-06,
89
- "rope_scaling": null,
90
- "rope_theta": 8000000,
 
 
 
 
 
 
 
 
91
  "routed_scaling_factor": 2.5,
92
- "router_dtype": "fp32",
93
- "score_function": "sigmoid",
94
  "tie_word_embeddings": false,
95
- "topk_group": 1,
96
  "transformers_version": "4.56.2",
97
- "use_bias": false,
98
  "use_cache": true,
99
  "use_qk_norm": true,
100
- "use_qkv_bias": false,
101
- "use_rmsnorm": true,
102
  "vocab_size": 262144
103
  }
 
1
  {
2
  "architectures": [
3
+ "SarvamMLAForCausalLM"
4
  ],
5
  "attention_dropout": 0.0,
6
  "attn_implementation": null,
7
  "auto_map": {
8
+ "AutoConfig": "configuration_sarvam_moe.SarvamMLAConfig",
9
+ "AutoModel": "modeling_sarvam_moe.SarvamMLAModel",
10
+ "AutoModelForCausalLM": "modeling_sarvam_moe.SarvamMLAForCausalLM"
11
  },
12
+ "default_theta": 10000.0,
13
  "dtype": "float32",
14
  "embedding_dropout": 0.0,
15
  "eos_token_id": 1,
16
  "first_k_dense_replace": 1,
17
+ "head_dim": 576,
18
  "hidden_act": "silu",
19
  "hidden_size": 4096,
20
  "initializer_range": 0.006,
21
+ "intermediate_size": 16384,
22
+ "kv_lora_rank": 512,
23
  "max_position_embeddings": 131072,
24
+ "model_type": "sarvam_mla",
25
+ "moe_intermediate_size": 2048,
 
26
  "moe_router_enable_expert_bias": true,
 
 
 
27
  "num_attention_heads": 64,
28
  "num_experts": 128,
29
+ "num_experts_per_tok": 8,
30
+ "num_hidden_layers": 32,
 
31
  "num_shared_experts": 1,
32
  "output_dropout": 0.0,
33
  "output_router_logits": false,
34
  "pad_token_id": 0,
35
+ "q_head_dim": 192,
36
+ "qk_nope_head_dim": 128,
37
+ "qk_rope_head_dim": 64,
38
  "quantization_config": {
39
  "config_groups": {
40
  "group_0": {
 
86
  "version": "0.14.0"
87
  },
88
  "rms_norm_eps": 1e-06,
89
+ "rope_scaling": {
90
+ "beta_fast": 32,
91
+ "beta_slow": 1,
92
+ "factor": 40,
93
+ "mscale": 1.0,
94
+ "mscale_all_dim": 1.0,
95
+ "original_max_position_embeddings": 4096,
96
+ "type": "deepseek_yarn"
97
+ },
98
+ "rope_theta": 10000.0,
99
  "routed_scaling_factor": 2.5,
 
 
100
  "tie_word_embeddings": false,
 
101
  "transformers_version": "4.56.2",
 
102
  "use_cache": true,
103
  "use_qk_norm": true,
104
+ "v_head_dim": 128,
 
105
  "vocab_size": 262144
106
  }
configuration_sarvam_moe.py CHANGED
@@ -1,99 +1,120 @@
1
  from transformers.configuration_utils import PretrainedConfig
2
 
3
 
4
- class SarvamMoEConfig(PretrainedConfig):
5
- model_type = "sarvam_moe"
 
 
 
 
 
 
 
 
 
 
 
 
 
6
  def __init__(
7
  self,
8
- vocab_size=262144,
9
- hidden_size=4096,
10
- intermediate_size=8192,
11
- num_hidden_layers=19,
12
- num_attention_heads=16,
13
- num_key_value_heads=4,
14
- hidden_act="silu",
15
- use_qkv_bias=False,
16
- use_bias=False,
17
- rms_norm_eps=1e-06,
18
- tie_word_embeddings=False,
19
- embedding_dropout=0.0,
20
- attention_dropout=0.0,
21
- output_dropout=0.0,
22
- initializer_range=0.006,
23
- max_position_embeddings=4096,
24
- rope_theta=10000.0,
25
- use_cache=True,
26
- max_window_layers=19,
27
- rope_scaling=None,
28
- pad_token_id=0,
29
- eos_token_id=1,
30
- num_experts=128,
31
- num_shared_experts=1,
32
- num_experts_per_tok=6,
33
- n_group=1,
34
- topk_group=1,
35
- moe_intermediate_size=1024,
36
- first_k_dense_replace=1,
37
- head_dim=256,
38
- output_router_logits=False,
39
- use_qk_norm=True,
40
- moe_router_enable_expert_bias=True,
41
- routed_scaling_factor=2.5,
42
  attn_implementation: str = "eager",
43
  **kwargs,
44
  ):
45
- self.num_hidden_layers = num_hidden_layers
46
  self.vocab_size = vocab_size
47
  self.hidden_size = hidden_size
 
48
  self.intermediate_size = intermediate_size
49
  self.num_attention_heads = num_attention_heads
50
- self.num_key_value_heads = num_key_value_heads
51
- self.hidden_act = hidden_act
52
- self.use_qkv_bias = use_qkv_bias
53
- self.use_bias = use_bias
54
- self.rms_norm_eps = rms_norm_eps
55
- self.embedding_dropout = embedding_dropout
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
56
  self.attention_dropout = attention_dropout
57
  self.output_dropout = output_dropout
 
 
58
  self.initializer_range = initializer_range
59
- self.max_position_embeddings = max_position_embeddings
 
 
60
  self.rope_theta = rope_theta
61
  self.use_cache = use_cache
62
- self.max_window_layers = max_window_layers
63
- self.head_dim = head_dim or hidden_size // num_attention_heads
64
- self.rope_scaling = rope_scaling
65
  self.use_qk_norm = use_qk_norm
66
- self.moe_router_enable_expert_bias = moe_router_enable_expert_bias
67
- self.routed_scaling_factor = routed_scaling_factor
68
- self.num_experts = num_experts
69
- self.num_shared_experts = num_shared_experts
70
- self.num_experts_per_tok = num_experts_per_tok
71
- self.n_group = n_group
72
- self.topk_group = topk_group
73
- self.moe_intermediate_size = moe_intermediate_size
74
- self.first_k_dense_replace = first_k_dense_replace
75
- self.output_router_logits = output_router_logits
 
 
 
 
76
  self.attn_implementation = attn_implementation
77
  self._attn_implementation = attn_implementation
78
-
79
- self.base_model_tp_plan = {
80
- "layers.*.attention.query_key_value": "colwise",
81
- "layers.*.attention.dense": "rowwise",
82
- "layers.*.mlp.gate_proj": "colwise",
83
- "layers.*.mlp.up_proj": "colwise",
84
- "layers.*.mlp.down_proj": "rowwise",
85
- "layers.*.mlp.experts.*.gate_proj": "colwise",
86
- "layers.*.mlp.experts.*.up_proj": "colwise",
87
- "layers.*.mlp.experts.*.down_proj": "rowwise",
88
- "layers.*.mlp.shared_experts.gate_proj": "colwise",
89
- "layers.*.mlp.shared_experts.up_proj": "colwise",
90
- "layers.*.mlp.shared_experts.down_proj": "rowwise",
91
- }
92
- self.base_model_pp_plan = {
93
- "word_embeddings": (["input_ids"], ["inputs_embeds"]),
94
- "layers": (["hidden_states", "attention_mask"], ["hidden_states"]),
95
- "norm": (["hidden_states"], ["hidden_states"]),
96
- }
97
 
98
  super().__init__(
99
  pad_token_id=pad_token_id,
@@ -101,3 +122,19 @@ class SarvamMoEConfig(PretrainedConfig):
101
  tie_word_embeddings=tie_word_embeddings,
102
  **kwargs,
103
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  from transformers.configuration_utils import PretrainedConfig
2
 
3
 
4
+ class SarvamMLAConfig(PretrainedConfig):
5
+ model_type = "sarvam_mla"
6
+
7
+ base_model_pp_plan = {
8
+ "embed_tokens": (["input_ids"], ["inputs_embeds"]),
9
+ "layers": (["hidden_states", "attention_mask"], ["hidden_states"]),
10
+ "norm": (["hidden_states"], ["hidden_states"]),
11
+ }
12
+
13
+ base_model_tp_plan = {
14
+ "layers.*.self_attn.q_proj": "colwise",
15
+ "layers.*.self_attn.kv_b_proj": "colwise",
16
+ "layers.*.self_attn.o_proj": "rowwise",
17
+ }
18
+
19
  def __init__(
20
  self,
21
+ vocab_size: int = 262144,
22
+ hidden_size: int = 4096,
23
+ num_hidden_layers: int = 32,
24
+ intermediate_size: int = 16384,
25
+ moe_intermediate_size: int = 2048,
26
+ num_experts: int = 128,
27
+ num_experts_per_tok: int = 8,
28
+ num_shared_experts: int = 1,
29
+ first_k_dense_replace: int = 1,
30
+ num_attention_heads: int = 64,
31
+ qk_rope_head_dim: int = 64,
32
+ qk_nope_head_dim: int = 128,
33
+ kv_lora_rank: int = 512,
34
+ v_head_dim: int = 128,
35
+ max_position_embeddings: int = 4096,
36
+ rope_theta: float = 10000.0,
37
+ rope_scaling: dict = None,
38
+ attention_dropout: float = 0.0,
39
+ output_dropout: float = 0.0,
40
+ rms_norm_eps: float = 1e-6,
41
+ hidden_act: str = "silu",
42
+ use_cache: bool = True,
43
+ use_qk_norm: bool = True,
44
+ moe_router_enable_expert_bias: bool = True,
45
+ routed_scaling_factor: float = 2.5,
46
+ output_router_logits: bool = False,
47
+ tie_word_embeddings: bool = False,
48
+ pad_token_id: int = 0,
49
+ eos_token_id: int = 1,
50
+ embedding_dropout: float = 0.0,
51
+ initializer_range: float = 0.006,
 
 
 
52
  attn_implementation: str = "eager",
53
  **kwargs,
54
  ):
55
+ # core geometry
56
  self.vocab_size = vocab_size
57
  self.hidden_size = hidden_size
58
+ self.num_hidden_layers = num_hidden_layers
59
  self.intermediate_size = intermediate_size
60
  self.num_attention_heads = num_attention_heads
61
+ self.max_position_embeddings = max_position_embeddings
62
+
63
+ # MLA geometry
64
+ self.qk_rope_head_dim = qk_rope_head_dim
65
+ self.qk_nope_head_dim = qk_nope_head_dim
66
+ self.kv_lora_rank = kv_lora_rank
67
+ self.v_head_dim = v_head_dim
68
+ # convenient derived dim
69
+ self.q_head_dim = qk_rope_head_dim + qk_nope_head_dim
70
+ # vLLM MLA expects "head size" = Lkv + R, not hidden_size/num_heads.
71
+ self.head_dim = int(self.kv_lora_rank + self.qk_rope_head_dim)
72
+
73
+ # MoE
74
+ self.moe_intermediate_size = moe_intermediate_size
75
+ self.num_experts = num_experts
76
+ self.num_experts_per_tok = num_experts_per_tok
77
+ self.num_shared_experts = num_shared_experts
78
+ self.first_k_dense_replace = first_k_dense_replace
79
+
80
+ # Router
81
+ self.moe_router_enable_expert_bias = moe_router_enable_expert_bias
82
+ self.routed_scaling_factor = routed_scaling_factor
83
+ self.output_router_logits = output_router_logits
84
+
85
+ # dropouts / norms / init
86
  self.attention_dropout = attention_dropout
87
  self.output_dropout = output_dropout
88
+ self.embedding_dropout = embedding_dropout
89
+ self.rms_norm_eps = rms_norm_eps
90
  self.initializer_range = initializer_range
91
+ self.hidden_act = hidden_act
92
+
93
+ # rope / cache
94
  self.rope_theta = rope_theta
95
  self.use_cache = use_cache
 
 
 
96
  self.use_qk_norm = use_qk_norm
97
+ self.rope_scaling = rope_scaling
98
+ self.default_theta = 10000.0
99
+
100
+ if self.rope_scaling is None:
101
+ self.rope_scaling = {
102
+ 'beta_fast': 32,
103
+ 'beta_slow': 1,
104
+ 'factor': 40,
105
+ 'mscale': 1.0,
106
+ 'mscale_all_dim': 1.0,
107
+ 'original_max_position_embeddings': 4096,
108
+ 'rope_type': 'deepseek_yarn',
109
+ }
110
+
111
  self.attn_implementation = attn_implementation
112
  self._attn_implementation = attn_implementation
113
+
114
+ if "_attn_implementation" in kwargs:
115
+ self._attn_implementation = kwargs.pop("_attn_implementation")
116
+ if hasattr(self, "attn_implementation"):
117
+ self.attn_implementation = self._attn_implementation
 
 
 
 
 
 
 
 
 
 
 
 
 
 
118
 
119
  super().__init__(
120
  pad_token_id=pad_token_id,
 
122
  tie_word_embeddings=tie_word_embeddings,
123
  **kwargs,
124
  )
125
+
126
+ def convert_rope_params_to_dict(self, ignore_keys_at_rope_validation: set | None = None, **kwargs):
127
+ rope_scaling = kwargs.pop("rope_scaling", None)
128
+ self.rope_parameters = rope_scaling or self.rope_parameters
129
+ self.rope_parameters = self.rope_parameters if self.rope_parameters is not None else {}
130
+
131
+ # Standardize and validate the correctness of rotary position embeddings parameters
132
+ self.rope_parameters.setdefault("rope_theta", kwargs.pop("rope_theta", self.default_theta))
133
+ self.standardize_rope_params()
134
+ self.validate_rope(ignore_keys=ignore_keys_at_rope_validation)
135
+
136
+ # Convert to float because RoPE fn expect a float. Models on the hub were saved as int
137
+ for key in ["beta_fast", "beta_slow", "factor"]:
138
+ if key in self.rope_parameters:
139
+ self.rope_parameters[key] = float(self.rope_parameters[key])
140
+ return kwargs
model-00001-of-00014.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:6d5a5940fb4d1cfe41f246105efc710912897bcd78424dd21c400e36230913c2
3
+ size 4996069592
model-00002-of-00014.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:2f24c183584df371c4080debbaf653142471db515c82f5945acfa36a808d1867
3
+ size 4999722272
model-00003-of-00014.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:3313fcccd81f53976b4c70851b981c6b02b79205cf9a2e878f03cb08e539e7dc
3
+ size 4998461512
model-00004-of-00014.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:36938b4142c0eba90c686ad776dd3cbf25ca1f898d913e174f5449a1717ca832
3
+ size 4998460680
model-00005-of-00014.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:be232a8c28fa38a08cb7d6660eb0bd261c067113213e6d12de8bb6d438107f03
3
+ size 4999724400
model-00006-of-00014.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:4aa5193a7030b93c939e44a62de91f83826c8e8961af095bdd165082f7949384
3
+ size 4998465624
model-00007-of-00014.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:14968bf6934fba39cc56c480cbc280469cb0f8acaaa3ebeca81eb0ba3501c911
3
+ size 4998464744
model-00008-of-00014.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:807c891b1668e2d5fdd5ce0349a2718e9750d212908ddb514e1d21b5627ba5d5
3
+ size 4999726168
model-00009-of-00014.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:aa6a9d7b17bc3b602a5ca78a1ab4d551007ad81f2e0f5b718bfaa38f317a5590
3
+ size 4998465576
model-00010-of-00014.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:8e45d0afaa845f305af9194ff6897a7c78419c6d7abc3778d58096412883f13e
3
+ size 4998464648
model-00011-of-00014.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:d37af3afb6b58c169d5539c1ba6136aef876d7220f892a482bfc1d15875b57c3
3
+ size 4999726024
model-00012-of-00014.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:c0e9730cab05a3b4103a9d64c74855024b8b00bee33297be56e01273f98a1a0b
3
+ size 4998465528
model-00013-of-00014.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:27728722f5ab17e2d9a5cc0fe3b1c8e954fa951b58d89eff60728cce7e7559bb
3
+ size 2808751984
model-00014-of-00014.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:7b705792f86d54e5c8f859fa7de49f88fffa1391373e24a93110fb1f13ab6987
3
+ size 4294967424
model.safetensors.index.json CHANGED
The diff for this file is too large to render. See raw diff
 
modeling_sarvam_moe.py CHANGED
@@ -1,11 +1,30 @@
1
- """PyTorch Sarvam MoE model."""
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
 
3
  import math
 
4
  from typing import List, Optional, Tuple, Union
5
 
6
  import torch
7
  import torch.nn.functional as F
 
8
  from torch import nn
 
9
 
10
  from transformers.activations import ACT2FN
11
  from transformers.cache_utils import Cache, DynamicCache
@@ -13,48 +32,39 @@ from transformers.modeling_attn_mask_utils import (
13
  AttentionMaskConverter,
14
  _prepare_4d_attention_mask,
15
  _prepare_4d_causal_attention_mask,
16
- _prepare_4d_causal_attention_mask_for_sdpa,
17
  )
18
- from transformers.modeling_outputs import MoeModelOutputWithPast
19
- from transformers.modeling_utils import ALL_ATTENTION_FUNCTIONS
20
- from transformers.modeling_rope_utils import ROPE_INIT_FUNCTIONS, dynamic_rope_update
21
- from transformers.modeling_utils import PreTrainedModel
22
- from transformers.pytorch_utils import ALL_LAYERNORM_LAYERS
 
 
 
 
23
  from transformers.utils import (
24
- is_flash_attn_2_available,
25
- is_flash_attn_greater_or_equal_2_10,
26
  logging,
 
27
  )
28
- from transformers.generation.utils import GenerationMixin
29
- from dataclasses import dataclass
30
- from transformers.utils import ModelOutput
31
-
32
 
33
- if is_flash_attn_2_available():
34
- from flash_attn import flash_attn_func, flash_attn_varlen_func
35
- from flash_attn.bert_padding import index_first_axis, pad_input, unpad_input
36
 
37
- from .configuration_sarvam_moe import SarvamMoEConfig
38
-
39
- logger = logging.get_logger(__name__)
40
 
41
- _CONFIG_FOR_DOC = "SarvamMoEConfig"
 
 
42
 
 
43
 
44
- @dataclass
45
- class SarvamMoECausalLMOutputWithPast(ModelOutput):
46
- loss: Optional[torch.FloatTensor] = None
47
- logits: Optional[torch.FloatTensor] = None
48
- past_key_values: Optional[Cache] = None
49
- hidden_states: Optional[tuple[torch.FloatTensor, ...]] = None
50
- attentions: Optional[tuple[torch.FloatTensor, ...]] = None
51
- z_loss: Optional[torch.FloatTensor] = None
52
- aux_loss: Optional[torch.FloatTensor] = None
53
- router_logits: Optional[tuple[torch.FloatTensor]] = None
54
 
 
55
 
56
- class SarvamMoEModelOutputWithPast(MoeModelOutputWithPast):
57
- pass
58
 
59
 
60
  def _get_unpad_data(attention_mask):
@@ -62,23 +72,27 @@ def _get_unpad_data(attention_mask):
62
  indices = torch.nonzero(attention_mask.flatten(), as_tuple=False).flatten()
63
  max_seqlen_in_batch = seqlens_in_batch.max().item()
64
  cu_seqlens = F.pad(torch.cumsum(seqlens_in_batch, dim=0, dtype=torch.torch.int32), (1, 0))
65
- return indices, cu_seqlens, max_seqlen_in_batch
66
-
67
-
68
- def _expand_mask(mask: torch.Tensor, dtype: torch.dtype, tgt_len: Optional[int] = None):
69
- return _prepare_4d_attention_mask(mask=mask, dtype=dtype, tgt_len=tgt_len)
70
 
71
 
72
- def _make_causal_mask(
73
- input_ids_shape: torch.Size, dtype: torch.dtype, device: torch.device, past_key_values_length: int = 0
74
- ):
75
- return AttentionMaskConverter._make_causal_mask(
76
- input_ids_shape=input_ids_shape, dtype=dtype, device=device, past_key_values_length=past_key_values_length
77
- )
 
78
 
79
 
80
- class SarvamMoERMSNorm(nn.Module):
81
  def __init__(self, hidden_size, eps=1e-6):
 
 
 
82
  super().__init__()
83
  self.weight = nn.Parameter(torch.ones(hidden_size))
84
  self.variance_epsilon = eps
@@ -91,275 +105,357 @@ class SarvamMoERMSNorm(nn.Module):
91
  return self.weight * hidden_states.to(input_dtype)
92
 
93
 
94
- ALL_LAYERNORM_LAYERS.append(SarvamMoERMSNorm)
95
 
96
 
97
- class SarvamMoERotaryEmbedding(nn.Module):
98
- def __init__(self, config: SarvamMoEConfig, device=None):
99
  super().__init__()
100
- self.config = config
101
- self.max_seq_len_cached = config.max_position_embeddings
102
- self.original_max_seq_len = config.max_position_embeddings
103
- rope_scaling = getattr(config, "rope_scaling", None)
104
- if rope_scaling is None:
105
- self.rope_type = "default"
106
- inv_freq, self.attention_scaling = self.compute_default_rope_parameters(
107
- config, device
108
- )
109
- else:
110
- self.rope_type = rope_scaling.get("rope_type", rope_scaling.get("type", "default"))
111
- if self.rope_type == "default":
112
- inv_freq, self.attention_scaling = self.compute_default_rope_parameters(
113
- config, device
114
- )
115
- else:
116
- rope_init_fn = ROPE_INIT_FUNCTIONS[self.rope_type]
117
- inv_freq, self.attention_scaling = rope_init_fn(config, device)
118
  self.register_buffer("inv_freq", inv_freq, persistent=False)
119
- self.original_inv_freq = self.inv_freq
120
 
121
- @staticmethod
122
- def compute_default_rope_parameters(
123
- config: SarvamMoEConfig,
124
- device: Optional[torch.device] = None,
125
- seq_len: Optional[int] = None,
126
- ) -> Tuple[torch.Tensor, float]:
127
- """
128
- Default RoPE parameters (classic rotary embedding).
129
 
130
- Mirrors HF's default implementation: use `rope_theta`, head_dim and
131
- return (inv_freq, attention_scaling).
132
- """
133
- base = config.rope_theta
134
- dim = getattr(config, "head_dim", None) or config.hidden_size // config.num_attention_heads
135
- inv_freq = 1.0 / (
136
- base
137
- ** (
138
- torch.arange(0, dim, 2, dtype=torch.int64, device=device)
139
- .to(dtype=torch.float32)
140
- / dim
141
- )
 
 
 
 
142
  )
143
- attention_factor = 1.0
144
- return inv_freq, attention_factor
145
 
146
- @torch.no_grad()
147
- @dynamic_rope_update
148
- def forward(self, x, position_ids):
149
- inv_freq_expanded = self.inv_freq[None, :, None].float().expand(position_ids.shape[0], -1, 1).to(x.device)
150
- position_ids_expanded = position_ids[:, None, :].float()
151
 
152
- device_type = x.device.type if isinstance(x.device.type, str) and x.device.type != "mps" else "cpu"
153
- with torch.autocast(device_type=device_type, enabled=False):
154
- freqs = (inv_freq_expanded.float() @ position_ids_expanded.float()).transpose(1, 2)
155
- emb = torch.cat((freqs, freqs), dim=-1)
156
- cos = emb.cos() * self.attention_scaling
157
- sin = emb.sin() * self.attention_scaling
 
 
 
 
 
 
 
 
158
 
159
- return cos.to(dtype=x.dtype), sin.to(dtype=x.dtype)
160
 
 
 
 
 
 
161
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
162
  def rotate_half(x):
 
163
  x1 = x[..., : x.shape[-1] // 2]
164
  x2 = x[..., x.shape[-1] // 2 :]
165
  return torch.cat((-x2, x1), dim=-1)
166
 
167
 
168
- def apply_rotary_pos_emb(q, k, cos, sin, unsqueeze_dim=1):
169
- cos = cos.unsqueeze(unsqueeze_dim)
170
- sin = sin.unsqueeze(unsqueeze_dim)
171
- rotary_dim = cos.shape[-1]
172
- q_rot, q_pass = q[..., :rotary_dim], q[..., rotary_dim:]
173
- k_rot, k_pass = k[..., :rotary_dim], k[..., rotary_dim:]
174
- q_embed = (q_rot * cos) + (rotate_half(q_rot) * sin)
175
- k_embed = (k_rot * cos) + (rotate_half(k_rot) * sin)
176
- q_embed = torch.cat([q_embed, q_pass], dim=-1)
177
- k_embed = torch.cat([k_embed, k_pass], dim=-1)
 
 
 
178
  return q_embed, k_embed
179
 
180
 
181
- class SarvamMoEMLP(nn.Module):
182
- def __init__(self, config: SarvamMoEConfig, intermediate_size: int):
183
  super().__init__()
184
  self.config = config
185
- self.hidden_size = config.hidden_size
186
- self.intermediate_size = intermediate_size
 
187
  self.gate_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=False)
188
  self.up_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=False)
189
  self.down_proj = nn.Linear(self.intermediate_size, self.hidden_size, bias=False)
190
  self.act_fn = ACT2FN[config.hidden_act]
191
 
192
  def forward(self, x):
193
- return self.down_proj(self.act_fn(self.gate_proj(x)) * self.up_proj(x))
 
194
 
195
 
196
- class SarvamMoEGate(nn.Module):
197
  def __init__(self, config):
198
  super().__init__()
199
  self.config = config
200
  self.top_k = config.num_experts_per_tok
201
- self.num_experts = config.num_experts
202
- self.n_group = config.n_group
203
- self.topk_group = config.topk_group
204
- self.gating_dim = config.hidden_size
205
- self.weight = nn.Parameter(torch.empty((self.num_experts, self.gating_dim)))
206
  self.routed_scaling_factor = config.routed_scaling_factor
207
- self.score_function = config.score_function
208
- # Ideally, we should register the expert_bias as a buffer, but vllm complains about it.
209
- # self.register_buffer("expert_bias", torch.zeros((self.num_experts)))
210
- self.expert_bias = nn.Parameter(
211
- torch.zeros((self.num_experts)),
212
- requires_grad=False,
213
- )
 
 
 
214
  self.reset_parameters()
215
 
216
  def reset_parameters(self) -> None:
217
  import torch.nn.init as init
218
 
219
  init.kaiming_uniform_(self.weight, a=math.sqrt(5))
220
-
221
- def group_limited_topk(self, scores: torch.Tensor):
222
- num_tokens, _ = scores.size()
223
- group_scores = scores.view(num_tokens, self.n_group, -1).topk(2, dim=-1)[0].sum(dim=-1)
224
- group_idx = torch.topk(group_scores, k=self.topk_group, dim=-1, sorted=False)[1]
225
- group_mask = torch.zeros_like(group_scores)
226
- group_mask.scatter_(1, group_idx, 1)
227
- score_mask = (
228
- group_mask.unsqueeze(-1)
229
- .expand(num_tokens, self.n_group, self.num_experts // self.n_group)
230
- .reshape(num_tokens, -1)
231
- )
232
- masked_scores = scores.masked_fill(~score_mask.bool(), float("-inf"))
233
- probs, top_indices = torch.topk(masked_scores, k=self.top_k, dim=-1)
234
- return probs, top_indices
235
 
236
  def forward(self, hidden_states):
237
- hidden_states = hidden_states.view(-1, hidden_states.shape[-1])
238
- logits = F.linear(hidden_states.type(torch.float32), self.weight.type(torch.float32))
239
- scores = torch.sigmoid(logits.float()).type_as(logits)
240
- scores_for_routing = scores + self.expert_bias
241
- _, topk_idx = self.group_limited_topk(scores_for_routing)
242
- scores = torch.gather(scores, dim=1, index=topk_idx).type_as(logits)
243
- topk_weight = scores / (scores.sum(dim=-1, keepdim=True) + 1e-20) if self.top_k > 1 else scores
244
- topk_weight = topk_weight * self.routed_scaling_factor
245
- return topk_idx, topk_weight, logits
246
-
247
-
248
- class SarvamMoEExperts(nn.ModuleList):
249
- def __init__(self, config: SarvamMoEConfig):
250
- # one MLP per expert
251
- experts = [
252
- SarvamMoEMLP(config=config, intermediate_size=config.moe_intermediate_size)
253
- for _ in range(config.num_experts)
254
- ]
255
- super().__init__(experts)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
256
  self.config = config
257
  self.num_experts_per_tok = config.num_experts_per_tok
258
 
259
- def forward(
260
- self,
261
- hidden_states: torch.Tensor,
262
- top_k_index: torch.LongTensor,
263
- top_k_weights: torch.Tensor,
264
- ) -> torch.Tensor:
265
- """
266
- hidden_states: (tokens, hidden_size) or (batch * seq, hidden_size)
267
- top_k_index: (tokens, top_k)
268
- top_k_weights: (tokens, top_k)
269
- """
270
- tokens, hidden_dim = hidden_states.shape
271
- flat_topk_idx = top_k_index.view(-1)
272
-
273
- if self.training:
274
- # training path: same as your previous logic
275
- x = hidden_states.repeat_interleave(self.num_experts_per_tok, dim=0)
276
- y = torch.empty_like(x)
277
- for i, expert in enumerate(self):
278
- mask = flat_topk_idx == i
279
- if mask.any():
280
- y[mask] = expert(x[mask])
281
- y = (y.view(*top_k_weights.shape, -1) * top_k_weights.unsqueeze(-1)).sum(dim=1)
282
- return y.to(hidden_states.dtype)
283
-
284
- # inference path: previous moe_infer logic
285
- num_experts = len(self)
286
- cnts = top_k_index.new_zeros((tokens, num_experts))
287
- cnts.scatter_(1, top_k_index, 1)
288
- tokens_per_expert = cnts.sum(dim=0)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
289
 
290
- idxs = top_k_index.view(-1).argsort()
291
- sorted_tokens = hidden_states[idxs // top_k_index.shape[1]]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
292
 
293
- tokens_per_expert = tokens_per_expert.cpu().numpy().tolist()
294
  outputs = []
295
  start_idx = 0
296
  for i, num_tokens in enumerate(tokens_per_expert):
297
  end_idx = start_idx + num_tokens
298
  if num_tokens == 0:
299
  continue
300
- expert = self[i]
301
- tokens_for_expert = sorted_tokens[start_idx:end_idx]
302
- expert_out = expert(tokens_for_expert)
303
- outputs.append(expert_out.to(hidden_states.device))
 
 
304
  start_idx = end_idx
305
 
306
  outs = torch.cat(outputs, dim=0) if len(outputs) else sorted_tokens.new_empty(0)
 
 
 
 
 
 
 
 
 
 
307
  new_x = torch.empty_like(outs)
308
  new_x[idxs] = outs
309
-
310
  final_out = (
311
- new_x.view(*top_k_index.shape, -1)
312
- .type(top_k_weights.dtype)
313
- .mul_(top_k_weights.unsqueeze(dim=-1))
314
  .sum(dim=1)
315
  .type(new_x.dtype)
316
  )
317
  return final_out
318
 
319
 
320
- class SarvamMoESparseMoeBlock(nn.Module):
321
- def __init__(self, config: SarvamMoEConfig):
322
- super().__init__()
323
- self.config = config
324
- self.num_experts_per_tok = config.num_experts_per_tok
325
-
326
- # use the new experts container
327
- self.experts = SarvamMoEExperts(config)
328
- self.gate = SarvamMoEGate(config)
329
-
330
- if config.num_shared_experts is not None:
331
- self.shared_experts = SarvamMoEMLP(
332
- config=config,
333
- intermediate_size=config.moe_intermediate_size * config.num_shared_experts,
334
- )
335
-
336
- # _setup_experts no longer needed
337
-
338
- def forward(self, hidden_states):
339
- identity = hidden_states
340
- bsz, seq_len, h = hidden_states.shape
341
-
342
- topk_idx, topk_weight, router_logits = self.gate(hidden_states)
343
-
344
- # flatten batch+seq for experts
345
- flat_hidden = hidden_states.view(-1, h)
346
- flat_topk_idx = topk_idx.view(-1, topk_idx.shape[-1])
347
- flat_topk_weight = topk_weight.view(-1, topk_weight.shape[-1])
348
-
349
- y = self.experts(flat_hidden, flat_topk_idx, flat_topk_weight)
350
- y = y.view(bsz, seq_len, h)
351
-
352
- if self.config.num_shared_experts is not None:
353
- y = y + self.shared_experts(identity)
354
-
355
- # router logits shape: (bsz, seq_len, num_experts)
356
- router_info = (
357
- router_logits.view(bsz, seq_len, -1),
358
- topk_idx.view(bsz, seq_len, -1),
359
- )
360
- return y, router_info
361
-
362
-
363
  def repeat_kv(hidden_states: torch.Tensor, n_rep: int) -> torch.Tensor:
364
  batch, num_key_value_heads, slen, head_dim = hidden_states.shape
365
  if n_rep == 1:
@@ -368,9 +464,9 @@ def repeat_kv(hidden_states: torch.Tensor, n_rep: int) -> torch.Tensor:
368
  return hidden_states.reshape(batch, num_key_value_heads * n_rep, slen, head_dim)
369
 
370
 
371
- class SarvamMoEAttention(nn.Module):
372
- is_causal = True # vLLM / Transformers backend critical flag
373
- def __init__(self, config: SarvamMoEConfig, layer_idx: Optional[int] = None):
374
  super().__init__()
375
  self.config = config
376
  self.layer_idx = layer_idx
@@ -380,29 +476,84 @@ class SarvamMoEAttention(nn.Module):
380
  "to errors during the forward call, if caching is used. Please make sure to provide a `layer_idx` "
381
  "when creating this class."
382
  )
 
383
  self.attention_dropout = config.attention_dropout
384
  self.hidden_size = config.hidden_size
385
  self.num_heads = config.num_attention_heads
386
- self.head_dim = config.head_dim or self.hidden_size // self.num_heads
387
- partial_rotary_factor = config.partial_rotary_factor if hasattr(config, "partial_rotary_factor") else 1.0
388
- self.rope_dim = int(self.head_dim * partial_rotary_factor)
389
- self.num_key_value_heads = config.num_key_value_heads
390
- self.num_key_value_groups = self.num_heads // self.num_key_value_heads
391
  self.max_position_embeddings = config.max_position_embeddings
392
  self.rope_theta = config.rope_theta
393
- self.query_key_value = nn.Linear(
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
394
  self.hidden_size,
395
- (self.num_heads + 2 * self.num_key_value_heads) * self.head_dim,
396
- bias=config.use_qkv_bias,
 
 
 
 
 
 
397
  )
398
- if self.config.use_qk_norm:
399
- self.query_layernorm = SarvamMoERMSNorm(self.head_dim, eps=config.rms_norm_eps)
400
- self.key_layernorm = SarvamMoERMSNorm(self.head_dim, eps=config.rms_norm_eps)
401
- self.dense = nn.Linear(self.num_heads * self.head_dim, self.hidden_size, bias=config.use_bias)
402
- self.scaling = self.head_dim**-0.5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
403
 
404
  def _shape(self, tensor: torch.Tensor, seq_len: int, bsz: int):
405
- return tensor.view(bsz, seq_len, self.num_heads, self.head_dim).transpose(1, 2).contiguous()
406
 
407
  def forward(
408
  self,
@@ -412,321 +563,101 @@ class SarvamMoEAttention(nn.Module):
412
  past_key_value: Optional[Cache] = None,
413
  output_attentions: bool = False,
414
  use_cache: bool = False,
415
- position_embeddings: Optional[Tuple[torch.Tensor, torch.Tensor]] = None,
416
  **kwargs,
417
- ):
418
  bsz, q_len, _ = hidden_states.size()
419
- qkv = self.query_key_value(hidden_states)
420
- qkv = qkv.view(
421
- bsz, q_len, self.num_heads + 2 * self.num_key_value_heads, self.head_dim
422
- )
423
- query_states, key_states, value_states = qkv.split(
424
- [self.num_heads, self.num_key_value_heads, self.num_key_value_heads],
425
- dim=-2,
426
- )
427
- query_states = query_states.transpose(1, 2).contiguous()
428
- key_states = key_states.transpose(1, 2).contiguous()
429
- value_states = value_states.transpose(1, 2).contiguous()
430
- if self.config.use_qk_norm:
431
- query_states = self.query_layernorm(query_states)
432
- key_states = self.key_layernorm(key_states)
433
- cos, sin = position_embeddings
434
- query_states, key_states = apply_rotary_pos_emb(
435
- query_states, key_states, cos, sin
436
  )
 
 
 
437
  if past_key_value is not None:
438
  if self.layer_idx is None:
439
  raise ValueError(
440
- "When using cache, SarvamMoEAttention must be initialized with layer_idx."
 
 
441
  )
442
- cache_kwargs = {"sin": sin, "cos": cos}
443
- key_states, value_states = past_key_value.update(
444
- key_states, value_states, self.layer_idx, cache_kwargs
445
- )
446
- # NOTE: vLLM will set config._attn_implementation = "vllm"
447
- if self.config._attn_implementation == "vllm":
448
- attention_interface = ALL_ATTENTION_FUNCTIONS[self.config._attn_implementation]
449
- attn_output, attn_weights = attention_interface(
450
- self,
451
- query_states,
452
- key_states,
453
- value_states,
454
- attention_mask,
455
- dropout=0.0 if not self.training else self.attention_dropout,
456
- scaling=self.scaling,
457
- **kwargs,
458
- )
459
- # vLLM backend may return [B, L, hidden] or [B*L, hidden]
460
- if attn_output.dim() == 4:
461
- # [B, H, L, Dh] -> [B, L, hidden]
462
- attn_output = attn_output.transpose(1, 2).contiguous()
463
- attn_output = attn_output.view(bsz, q_len, -1)
464
- elif attn_output.dim() == 3:
465
- if attn_output.shape[0] != bsz or attn_output.shape[1] != q_len:
466
- raise ValueError(
467
- f"Unexpected vLLM attention output shape {attn_output.shape}, "
468
- f"expected (bsz={bsz}, q_len={q_len}, hidden=*)"
469
- )
470
- elif attn_output.dim() == 2:
471
- attn_output = attn_output.view(bsz, q_len, -1)
472
- else:
473
- raise ValueError(
474
- f"Unsupported vLLM attention output rank {attn_output.dim()} "
475
- f"with shape {attn_output.shape}"
476
- )
477
- attn_output = self.dense(attn_output)
478
- if not output_attentions:
479
- attn_weights = None
480
- return attn_output, attn_weights, past_key_value
481
-
482
- key_states = repeat_kv(key_states, self.num_key_value_groups)
483
- value_states = repeat_kv(value_states, self.num_key_value_groups)
484
- attn_weights = torch.matmul(query_states, key_states.transpose(2, 3)) / math.sqrt(self.head_dim)
485
- kv_seq_len = key_states.shape[-2]
486
  if attn_weights.size() != (bsz, self.num_heads, q_len, kv_seq_len):
487
  raise ValueError(
488
  f"Attention weights should be of size {(bsz, self.num_heads, q_len, kv_seq_len)}, but is"
489
  f" {attn_weights.size()}"
490
  )
 
491
  if attention_mask is not None:
492
  if attention_mask.size() != (bsz, 1, q_len, kv_seq_len):
493
  raise ValueError(
494
  f"Attention mask should be of size {(bsz, 1, q_len, kv_seq_len)}, but is {attention_mask.size()}"
495
  )
496
  attn_weights = attn_weights + attention_mask
 
497
  attn_weights = nn.functional.softmax(attn_weights, dim=-1, dtype=torch.float32).to(query_states.dtype)
498
  attn_weights = nn.functional.dropout(attn_weights, p=self.attention_dropout, training=self.training)
499
  attn_output = torch.matmul(attn_weights, value_states)
500
- if attn_output.size() != (bsz, self.num_heads, q_len, self.head_dim):
 
501
  raise ValueError(
502
- f"`attn_output` should be of size {(bsz, self.num_heads, q_len, self.head_dim)}, but is"
503
  f" {attn_output.size()}"
504
  )
505
  attn_output = attn_output.transpose(1, 2).contiguous()
506
- attn_output = attn_output.reshape(bsz, q_len, -1)
507
- attn_output = self.dense(attn_output)
508
- if not output_attentions:
509
- attn_weights = None
510
- return attn_output, attn_weights, past_key_value
511
-
512
 
513
- class SarvamMoEFlashAttention2(SarvamMoEAttention):
514
- def __init__(self, *args, **kwargs):
515
- super().__init__(*args, **kwargs)
516
- self._flash_attn_uses_top_left_mask = not is_flash_attn_greater_or_equal_2_10()
517
-
518
- def forward(
519
- self,
520
- hidden_states: torch.Tensor,
521
- attention_mask: Optional[torch.LongTensor] = None,
522
- position_ids: Optional[torch.LongTensor] = None,
523
- past_key_value: Optional[Cache] = None,
524
- output_attentions: bool = False,
525
- use_cache: bool = False,
526
- position_embeddings: Optional[Tuple[torch.Tensor, torch.Tensor]] = None,
527
- **kwargs,
528
- ) -> Tuple[torch.Tensor, Optional[torch.Tensor], Optional[Tuple[torch.Tensor]]]:
529
- output_attentions = False
530
- bsz, q_len, _ = hidden_states.size()
531
- qkv = self.query_key_value(hidden_states)
532
- qkv = qkv.view(bsz, q_len, self.num_heads + 2 * self.num_key_value_heads, self.head_dim)
533
- query_states, key_states, value_states = qkv.split(
534
- [self.num_heads, self.num_key_value_heads, self.num_key_value_heads], dim=-2
535
- )
536
- query_states = query_states.transpose(1, 2)
537
- key_states = key_states.transpose(1, 2)
538
- value_states = value_states.transpose(1, 2)
539
- if self.config.use_qk_norm:
540
- query_states = self.query_layernorm(query_states)
541
- key_states = self.key_layernorm(key_states)
542
- cos, sin = position_embeddings
543
- query_states, key_states = apply_rotary_pos_emb(query_states, key_states, cos, sin)
544
- if past_key_value is not None:
545
- cache_kwargs = {"sin": sin, "cos": cos}
546
- key_states, value_states = past_key_value.update(key_states, value_states, self.layer_idx, cache_kwargs)
547
- query_states = query_states.transpose(1, 2)
548
- key_states = key_states.transpose(1, 2)
549
- value_states = value_states.transpose(1, 2)
550
- dropout_rate = self.attention_dropout if self.training else 0.0
551
- input_dtype = query_states.dtype
552
- if input_dtype == torch.float32:
553
- if hasattr(self.config, "_pre_quantization_dtype"):
554
- target_dtype = self.config._pre_quantization_dtype
555
- elif torch.is_autocast_enabled():
556
- target_dtype = torch.get_autocast_gpu_dtype()
557
- else:
558
- target_dtype = self.query_key_value.weight.dtype
559
- logger.warning_once(
560
- f"The input hidden states seems to be silently casted in float32, this might be related to"
561
- f" the fact you have upcasted embedding or layer norm layers in float32. We will cast back the input in"
562
- f" {target_dtype}."
563
- )
564
- query_states = query_states.to(target_dtype)
565
- key_states = key_states.to(target_dtype)
566
- value_states = value_states.to(target_dtype)
567
- attn_output = self._flash_attention_forward(
568
- query_states, key_states, value_states, attention_mask, q_len, dropout=dropout_rate
569
- )
570
- attn_output = attn_output.reshape(bsz, q_len, -1).contiguous()
571
- attn_output = self.dense(attn_output)
572
  if not output_attentions:
573
  attn_weights = None
574
- return attn_output, attn_weights, past_key_value
575
-
576
- def _flash_attention_forward(
577
- self, query_states, key_states, value_states, attention_mask, query_length, dropout=0.0, softmax_scale=None
578
- ):
579
- if not self._flash_attn_uses_top_left_mask:
580
- causal = self.is_causal
581
- else:
582
- causal = self.is_causal and query_length != 1
583
- if attention_mask is not None:
584
- batch_size = query_states.shape[0]
585
- query_states, key_states, value_states, indices_q, cu_seq_lens, max_seq_lens = self._upad_input(
586
- query_states, key_states, value_states, attention_mask, query_length
587
- )
588
- cu_seqlens_q, cu_seqlens_k = cu_seq_lens
589
- max_seqlen_in_batch_q, max_seqlen_in_batch_k = max_seq_lens
590
- attn_output_unpad = flash_attn_varlen_func(
591
- query_states,
592
- key_states,
593
- value_states,
594
- cu_seqlens_q=cu_seqlens_q,
595
- cu_seqlens_k=cu_seqlens_k,
596
- max_seqlen_q=max_seqlen_in_batch_q,
597
- max_seqlen_k=max_seqlen_in_batch_k,
598
- dropout_p=dropout,
599
- softmax_scale=softmax_scale,
600
- causal=causal,
601
- )
602
- attn_output = pad_input(attn_output_unpad, indices_q, batch_size, query_length)
603
- else:
604
- attn_output = flash_attn_func(
605
- query_states, key_states, value_states, dropout, softmax_scale=softmax_scale, causal=causal
606
- )
607
- return attn_output
608
-
609
- def _upad_input(self, query_layer, key_layer, value_layer, attention_mask, query_length):
610
- indices_k, cu_seqlens_k, max_seqlen_in_batch_k = _get_unpad_data(attention_mask)
611
- batch_size, kv_seq_len, num_key_value_heads, head_dim = key_layer.shape
612
- key_layer = index_first_axis(
613
- key_layer.reshape(batch_size * kv_seq_len, num_key_value_heads, head_dim), indices_k
614
- )
615
- value_layer = index_first_axis(
616
- value_layer.reshape(batch_size * kv_seq_len, num_key_value_heads, head_dim), indices_k
617
- )
618
- if query_length == kv_seq_len:
619
- query_layer = index_first_axis(
620
- query_layer.reshape(batch_size * kv_seq_len, self.num_heads, head_dim), indices_k
621
- )
622
- cu_seqlens_q = cu_seqlens_k
623
- max_seqlen_in_batch_q = max_seqlen_in_batch_k
624
- indices_q = indices_k
625
- elif query_length == 1:
626
- max_seqlen_in_batch_q = 1
627
- cu_seqlens_q = torch.arange(
628
- batch_size + 1, dtype=torch.int32, device=query_layer.device
629
- )
630
- indices_q = cu_seqlens_q[:-1]
631
- query_layer = query_layer.squeeze(1)
632
- else:
633
- attention_mask = attention_mask[:, -query_length:]
634
- query_layer, indices_q, cu_seqlens_q, max_seqlen_in_batch_q = unpad_input(query_layer, attention_mask)
635
- return (
636
- query_layer,
637
- key_layer,
638
- value_layer,
639
- indices_q,
640
- (cu_seqlens_q, cu_seqlens_k),
641
- (max_seqlen_in_batch_q, max_seqlen_in_batch_k),
642
- )
643
-
644
-
645
- class SarvamMoESdpaAttention(SarvamMoEAttention):
646
- def forward(
647
- self,
648
- hidden_states: torch.Tensor,
649
- attention_mask: Optional[torch.Tensor] = None,
650
- position_ids: Optional[torch.LongTensor] = None,
651
- past_key_value: Optional[Cache] = None,
652
- output_attentions: Optional[bool] = False,
653
- use_cache: Optional[bool] = False,
654
- position_embeddings: Optional[Tuple[torch.Tensor, torch.Tensor]] = None,
655
- **kwargs,
656
- ) -> Tuple[torch.Tensor, Optional[torch.Tensor], Optional[Tuple[torch.Tensor]]]:
657
- if output_attentions:
658
- return super().forward(
659
- hidden_states=hidden_states,
660
- attention_mask=attention_mask,
661
- position_ids=position_ids,
662
- past_key_value=past_key_value,
663
- output_attentions=output_attentions,
664
- use_cache=use_cache,
665
- **kwargs,
666
- )
667
- bsz, q_len, _ = hidden_states.size()
668
- qkv = self.query_key_value(hidden_states)
669
- qkv = qkv.view(bsz, q_len, self.num_heads + 2 * self.num_key_value_heads, self.head_dim)
670
- query_states, key_states, value_states = qkv.split(
671
- [self.num_heads, self.num_key_value_heads, self.num_key_value_heads], dim=-2
672
- )
673
- query_states = query_states.transpose(1, 2)
674
- key_states = key_states.transpose(1, 2)
675
- value_states = value_states.transpose(1, 2)
676
- if self.config.use_qk_norm:
677
- query_states = self.query_layernorm(query_states)
678
- key_states = self.key_layernorm(key_states)
679
- cos, sin = position_embeddings
680
- query_states, key_states = apply_rotary_pos_emb(query_states, key_states, cos, sin)
681
- if past_key_value is not None:
682
- cache_kwargs = {"sin": sin, "cos": cos}
683
- key_states, value_states = past_key_value.update(key_states, value_states, self.layer_idx, cache_kwargs)
684
- key_states = repeat_kv(key_states, self.num_key_value_groups)
685
- value_states = repeat_kv(value_states, self.num_key_value_groups)
686
- if attention_mask is not None:
687
- kv_seq_len = key_states.shape[-2]
688
- if attention_mask.size() != (bsz, 1, q_len, kv_seq_len):
689
- raise ValueError(
690
- f"Attention mask should be of size {(bsz, 1, q_len, kv_seq_len)}, but is {attention_mask.size()}"
691
- )
692
- if query_states.device.type == "cuda" and attention_mask is not None:
693
- query_states = query_states.contiguous()
694
- key_states = key_states.contiguous()
695
- value_states = value_states.contiguous()
696
- attn_output = torch.nn.functional.scaled_dot_product_attention(
697
- query_states,
698
- key_states,
699
- value_states,
700
- attn_mask=attention_mask,
701
- dropout_p=self.attention_dropout if self.training else 0.0,
702
- is_causal=self.is_causal and attention_mask is None and q_len > 1,
703
- )
704
- attn_output = attn_output.transpose(1, 2).contiguous()
705
- attn_output = attn_output.reshape(bsz, q_len, -1)
706
- attn_output = self.dense(attn_output)
707
- return attn_output, None, past_key_value
708
 
709
-
710
- ATTENTION_CLASSES = {
711
- "eager": SarvamMoEAttention,
712
- "flash_attention_2": SarvamMoEFlashAttention2,
713
- "sdpa": SarvamMoESdpaAttention,
714
- "vllm": SarvamMoEAttention,
715
- }
716
 
717
 
718
- class SarvamMoEDecoderLayer(nn.Module):
719
- def __init__(self, config: SarvamMoEConfig, layer_idx: int):
720
  super().__init__()
721
  self.hidden_size = config.hidden_size
722
- self.attention = ATTENTION_CLASSES[config._attn_implementation](config=config, layer_idx=layer_idx)
723
- self.mlp = (
724
- SarvamMoESparseMoeBlock(config)
725
- if (config.num_experts is not None and layer_idx >= config.first_k_dense_replace)
726
- else SarvamMoEMLP(config=config, intermediate_size=config.intermediate_size)
 
 
727
  )
728
- self.input_layernorm = SarvamMoERMSNorm(config.hidden_size, eps=config.rms_norm_eps)
729
- self.post_attention_layernorm = SarvamMoERMSNorm(config.hidden_size, eps=config.rms_norm_eps)
 
 
730
 
731
  def forward(
732
  self,
@@ -735,49 +666,44 @@ class SarvamMoEDecoderLayer(nn.Module):
735
  position_ids: Optional[torch.LongTensor] = None,
736
  past_key_value: Optional[Tuple[torch.Tensor]] = None,
737
  output_attentions: Optional[bool] = False,
738
- output_router_logits: Optional[bool] = False,
739
  use_cache: Optional[bool] = False,
740
- position_embeddings: Optional[Tuple[torch.Tensor, torch.Tensor]] = None,
741
  **kwargs,
742
  ) -> Tuple[torch.FloatTensor, Optional[Tuple[torch.FloatTensor, torch.FloatTensor]]]:
743
  residual = hidden_states
744
  hidden_states = self.input_layernorm(hidden_states)
745
- hidden_states, self_attn_weights, present_key_value = self.attention(
 
746
  hidden_states=hidden_states,
747
  attention_mask=attention_mask,
748
  position_ids=position_ids,
749
  past_key_value=past_key_value,
750
  output_attentions=output_attentions,
751
- position_embeddings=position_embeddings,
752
  use_cache=use_cache,
753
  **kwargs,
754
  )
755
  hidden_states = residual + hidden_states
 
756
  residual = hidden_states
757
  hidden_states = self.post_attention_layernorm(hidden_states)
758
  hidden_states = self.mlp(hidden_states)
759
- if isinstance(hidden_states, tuple):
760
- hidden_states, router_logits = hidden_states
761
- else:
762
- router_logits = None
763
- hidden_states = residual + hidden_states.to(residual.device)
764
  outputs = (hidden_states,)
 
765
  if output_attentions:
766
  outputs += (self_attn_weights,)
767
  if use_cache:
768
  outputs += (present_key_value,)
769
- if output_router_logits:
770
- outputs += (router_logits,)
771
  return outputs
772
 
773
- class SarvamMoEPreTrainedModel(PreTrainedModel):
774
- config_class = SarvamMoEConfig
 
775
  base_model_prefix = "model"
776
  supports_gradient_checkpointing = True
777
- _no_split_modules = ["SarvamMoEDecoderLayer"]
778
  _skip_keys_device_placement = "past_key_values"
779
- _supports_flash_attn_2 = True
780
- _supports_sdpa = True
781
  _supports_cache_class = True
782
 
783
  def _init_weights(self, module):
@@ -792,30 +718,28 @@ class SarvamMoEPreTrainedModel(PreTrainedModel):
792
  module.weight.data[module.padding_idx].zero_()
793
 
794
 
795
-
796
- class SarvamMoEModel(SarvamMoEPreTrainedModel):
797
- _supports_attention_backend = True
798
- def __init__(self, config: SarvamMoEConfig):
799
  super().__init__(config)
800
  self.padding_idx = config.pad_token_id
801
  self.vocab_size = config.vocab_size
802
- self.word_embeddings = nn.Embedding(config.vocab_size, config.hidden_size, self.padding_idx)
803
- self.layers = []
804
- for layer_idx in range(config.num_hidden_layers):
805
- self.layers.append(SarvamMoEDecoderLayer(config, layer_idx))
806
- self.layers = nn.ModuleList(self.layers)
807
- self._use_sdpa = config._attn_implementation == "sdpa"
808
- self._use_flash_attention_2 = config._attn_implementation == "flash_attention_2"
809
- self.norm = SarvamMoERMSNorm(config.hidden_size, eps=config.rms_norm_eps)
810
- self.rotary_emb = SarvamMoERotaryEmbedding(config=config)
811
  self.gradient_checkpointing = False
 
812
  self.post_init()
813
 
814
  def get_input_embeddings(self):
815
- return self.word_embeddings
816
 
817
  def set_input_embeddings(self, value):
818
- self.word_embeddings = value
819
 
820
  def forward(
821
  self,
@@ -827,19 +751,17 @@ class SarvamMoEModel(SarvamMoEPreTrainedModel):
827
  use_cache: Optional[bool] = None,
828
  output_attentions: Optional[bool] = None,
829
  output_hidden_states: Optional[bool] = None,
830
- output_router_logits: Optional[bool] = None,
831
  return_dict: Optional[bool] = None,
832
- **kwargs,
833
- ) -> Union[Tuple, SarvamMoEModelOutputWithPast]:
834
  output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions
835
  output_hidden_states = (
836
  output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states
837
  )
838
- output_router_logits = (
839
- output_router_logits if output_router_logits is not None else self.config.output_router_logits
840
- )
841
  use_cache = use_cache if use_cache is not None else self.config.use_cache
 
842
  return_dict = return_dict if return_dict is not None else self.config.use_return_dict
 
 
843
  if input_ids is not None and inputs_embeds is not None:
844
  raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time")
845
  elif input_ids is not None:
@@ -848,111 +770,91 @@ class SarvamMoEModel(SarvamMoEPreTrainedModel):
848
  batch_size, seq_length = inputs_embeds.shape[:2]
849
  else:
850
  raise ValueError("You have to specify either input_ids or inputs_embeds")
851
- if self.gradient_checkpointing and self.training:
852
- if use_cache:
853
- logger.warning_once(
854
- "`use_cache=True` is incompatible with gradient checkpointing. Setting `use_cache=False`transformers."
855
- )
856
- use_cache = False
857
- if use_cache and past_key_values is None:
858
- past_key_values = DynamicCache()
859
- if inputs_embeds is None:
860
- inputs_embeds = self.word_embeddings(input_ids)
861
- past_seen_tokens = past_key_values.get_seq_length() if past_key_values is not None else 0
862
  if position_ids is None:
 
863
  position_ids = torch.arange(
864
- past_seen_tokens, past_seen_tokens + inputs_embeds.shape[1], device=inputs_embeds.device
 
 
 
865
  )
866
  position_ids = position_ids.unsqueeze(0)
867
- if self._use_flash_attention_2:
868
- attention_mask = attention_mask if (attention_mask is not None and 0 in attention_mask) else None
869
- elif self._use_sdpa and not output_attentions:
870
- attention_mask = _prepare_4d_causal_attention_mask_for_sdpa(
871
- attention_mask,
872
- (batch_size, seq_length),
873
- inputs_embeds,
874
- past_seen_tokens,
875
- )
876
- else:
877
- attention_mask = _prepare_4d_causal_attention_mask(
878
- attention_mask, (batch_size, seq_length), inputs_embeds, past_seen_tokens
879
- )
880
  hidden_states = inputs_embeds
881
- position_embeddings = self.rotary_emb(hidden_states, position_ids)
882
  all_hidden_states = () if output_hidden_states else None
883
  all_self_attns = () if output_attentions else None
884
- all_router_logits = () if output_router_logits else None
885
  next_decoder_cache = None
886
- layers = self.layers
887
- for decoder_layer in layers:
888
  if output_hidden_states:
889
  all_hidden_states += (hidden_states,)
890
- if self.gradient_checkpointing and self.training:
891
- layer_outputs = self._gradient_checkpointing_func(
892
- decoder_layer.__call__,
893
- hidden_states,
894
- attention_mask,
895
- position_ids,
896
- past_key_values,
897
- output_attentions,
898
- output_router_logits,
899
- use_cache,
900
- position_embeddings,
901
- **kwargs,
902
- )
903
- else:
904
- layer_outputs = decoder_layer(
905
- hidden_states,
906
- attention_mask=attention_mask,
907
- position_ids=position_ids,
908
- past_key_value=past_key_values,
909
- output_attentions=output_attentions,
910
- output_router_logits=output_router_logits,
911
- use_cache=use_cache,
912
- position_embeddings=position_embeddings,
913
- **kwargs,
914
- )
915
  hidden_states = layer_outputs[0]
916
  if use_cache:
917
  next_decoder_cache = layer_outputs[2 if output_attentions else 1]
918
  if output_attentions:
919
  all_self_attns += (layer_outputs[1],)
920
- if output_router_logits and layer_outputs[-1] is not None:
921
- all_router_logits += (layer_outputs[-1],)
922
  hidden_states = self.norm(hidden_states)
 
923
  if output_hidden_states:
924
  all_hidden_states += (hidden_states,)
 
925
  next_cache = None
926
  if use_cache:
927
- next_cache = next_decoder_cache
928
  if not return_dict:
929
- return tuple(
930
- v for v in [hidden_states, next_cache, all_hidden_states, all_self_attns, all_router_logits] if v is not None
931
- )
932
- return SarvamMoEModelOutputWithPast(
933
  last_hidden_state=hidden_states,
934
  past_key_values=next_cache,
935
  hidden_states=all_hidden_states,
936
  attentions=all_self_attns,
937
- router_logits=all_router_logits,
938
  )
939
 
940
 
941
- class SarvamMoEForCausalLM(SarvamMoEPreTrainedModel, GenerationMixin):
942
  _tied_weights_keys = ["lm_head.weight"]
943
 
944
- def __init__(self, config: SarvamMoEConfig):
945
  super().__init__(config)
946
- self.model = SarvamMoEModel(config)
947
  self.vocab_size = config.vocab_size
948
  self.lm_head = nn.Linear(config.hidden_size, config.vocab_size, bias=False)
949
  self.post_init()
950
 
951
  def get_input_embeddings(self):
952
- return self.model.word_embeddings
953
 
954
  def set_input_embeddings(self, value):
955
- self.model.word_embeddings = value
956
 
957
  def get_output_embeddings(self):
958
  return self.lm_head
@@ -977,18 +879,14 @@ class SarvamMoEForCausalLM(SarvamMoEPreTrainedModel, GenerationMixin):
977
  use_cache: Optional[bool] = None,
978
  output_attentions: Optional[bool] = None,
979
  output_hidden_states: Optional[bool] = None,
980
- output_router_logits: Optional[bool] = None,
981
  return_dict: Optional[bool] = None,
982
- **kwargs,
983
- ) -> Union[Tuple, SarvamMoEModelOutputWithPast]:
984
  output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions
985
  output_hidden_states = (
986
  output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states
987
  )
988
- output_router_logits = (
989
- output_router_logits if output_router_logits is not None else self.config.output_router_logits
990
- )
991
  return_dict = return_dict if return_dict is not None else self.config.use_return_dict
 
992
  outputs = self.model(
993
  input_ids=input_ids,
994
  attention_mask=attention_mask,
@@ -998,28 +896,98 @@ class SarvamMoEForCausalLM(SarvamMoEPreTrainedModel, GenerationMixin):
998
  use_cache=use_cache,
999
  output_attentions=output_attentions,
1000
  output_hidden_states=output_hidden_states,
1001
- output_router_logits=output_router_logits,
1002
  return_dict=return_dict,
1003
- **kwargs,
1004
  )
1005
- loss = None
1006
- aux_loss = None
1007
  hidden_states = outputs[0]
1008
  logits = self.lm_head(hidden_states)
1009
  logits = logits.float()
 
 
1010
  if labels is not None:
1011
- loss = self.loss_function(logits, labels, self.config.vocab_size, **kwargs)
 
 
 
 
 
 
 
 
 
 
1012
  if not return_dict:
1013
  output = (logits,) + outputs[1:]
1014
- if output_router_logits:
1015
- output = (aux_loss,) + output
1016
  return (loss,) + output if loss is not None else output
1017
- return SarvamMoECausalLMOutputWithPast(
 
1018
  loss=loss,
1019
  logits=logits,
1020
  past_key_values=outputs.past_key_values,
1021
  hidden_states=outputs.hidden_states,
1022
  attentions=outputs.attentions,
1023
- aux_loss=aux_loss,
1024
- router_logits=outputs.router_logits,
1025
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright 2026 Sarvam AI team. All rights reserved.
2
+ #
3
+ # This code is based on Llama and Deepseek MoE implementations
4
+ # in this library. It has been modified from its original forms to
5
+ # accommodate Sarvam's MLA (multi-latent attention) MoE architecture.
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
 
19
  import math
20
+ import warnings
21
  from typing import List, Optional, Tuple, Union
22
 
23
  import torch
24
  import torch.nn.functional as F
25
+ import torch.utils.checkpoint
26
  from torch import nn
27
+ from torch.nn import BCEWithLogitsLoss, CrossEntropyLoss, MSELoss
28
 
29
  from transformers.activations import ACT2FN
30
  from transformers.cache_utils import Cache, DynamicCache
 
32
  AttentionMaskConverter,
33
  _prepare_4d_attention_mask,
34
  _prepare_4d_causal_attention_mask,
 
35
  )
36
+ from transformers.modeling_outputs import (
37
+ BaseModelOutputWithPast,
38
+ CausalLMOutputWithPast,
39
+ )
40
+ from transformers.modeling_utils import PreTrainedModel, ALL_ATTENTION_FUNCTIONS
41
+ from transformers.pytorch_utils import (
42
+ ALL_LAYERNORM_LAYERS,
43
+ is_torch_greater_or_equal_than_1_13,
44
+ )
45
  from transformers.utils import (
46
+ add_start_docstrings,
47
+ add_start_docstrings_to_model_forward,
48
  logging,
49
+ replace_return_docstrings,
50
  )
51
+ from transformers.utils.import_utils import is_torch_fx_available
 
 
 
52
 
53
+ import torch.distributed as dist
54
+ import numpy as np
 
55
 
56
+ from .configuration_sarvam_moe import SarvamMLAConfig
 
 
57
 
58
+ if is_torch_fx_available():
59
+ if not is_torch_greater_or_equal_than_1_13:
60
+ import torch.fx
61
 
62
+ _prepare_4d_causal_attention_mask = torch.fx.wrap(_prepare_4d_causal_attention_mask)
63
 
 
 
 
 
 
 
 
 
 
 
64
 
65
+ logger = logging.get_logger(__name__)
66
 
67
+ _CONFIG_FOR_DOC = "SarvamMLAConfig"
 
68
 
69
 
70
  def _get_unpad_data(attention_mask):
 
72
  indices = torch.nonzero(attention_mask.flatten(), as_tuple=False).flatten()
73
  max_seqlen_in_batch = seqlens_in_batch.max().item()
74
  cu_seqlens = F.pad(torch.cumsum(seqlens_in_batch, dim=0, dtype=torch.torch.int32), (1, 0))
75
+ return (
76
+ indices,
77
+ cu_seqlens,
78
+ max_seqlen_in_batch,
79
+ )
80
 
81
 
82
+ def _get_usable_past_kv_length(cache: Cache, new_seq_length: int, layer_idx: int = 0) -> int:
83
+ previous_length = cache.get_seq_length(layer_idx)
84
+ # Dynamic layers return -1, static layers return an int
85
+ max_length = cache.get_max_cache_shape(layer_idx)
86
+ if max_length is not None and max_length != -1 and previous_length + new_seq_length > max_length:
87
+ return max_length - new_seq_length
88
+ return previous_length
89
 
90
 
91
+ class SarvamMLARMSNorm(nn.Module):
92
  def __init__(self, hidden_size, eps=1e-6):
93
+ """
94
+ SarvamMLARMSNorm is equivalent to T5LayerNorm
95
+ """
96
  super().__init__()
97
  self.weight = nn.Parameter(torch.ones(hidden_size))
98
  self.variance_epsilon = eps
 
105
  return self.weight * hidden_states.to(input_dtype)
106
 
107
 
108
+ ALL_LAYERNORM_LAYERS.append(SarvamMLARMSNorm)
109
 
110
 
111
+ class SarvamMLARotaryEmbedding(nn.Module):
112
+ def __init__(self, dim, max_position_embeddings=2048, base=10000, device=None):
113
  super().__init__()
114
+
115
+ self.dim = dim
116
+ self.max_position_embeddings = max_position_embeddings
117
+ self.base = base
118
+ inv_freq = 1.0 / (self.base ** (torch.arange(0, self.dim, 2).float().to(device) / self.dim))
 
 
 
 
 
 
 
 
 
 
 
 
 
119
  self.register_buffer("inv_freq", inv_freq, persistent=False)
 
120
 
121
+ self._set_cos_sin_cache(
122
+ seq_len=max_position_embeddings,
123
+ device=self.inv_freq.device,
124
+ dtype=torch.get_default_dtype(),
125
+ )
126
+ self.max_seq_len_cached = None
 
 
127
 
128
+ def _set_cos_sin_cache(self, seq_len, device, dtype):
129
+ self.max_seq_len_cached = seq_len
130
+ t = torch.arange(self.max_seq_len_cached, device=device, dtype=self.inv_freq.dtype)
131
+
132
+ freqs = torch.outer(t, self.inv_freq.to(t.device))
133
+ emb = torch.cat((freqs, freqs), dim=-1)
134
+ self.register_buffer("cos_cached", emb.cos().to(dtype), persistent=False)
135
+ self.register_buffer("sin_cached", emb.sin().to(dtype), persistent=False)
136
+
137
+ def forward(self, x, seq_len=None):
138
+ if self.max_seq_len_cached is None or seq_len > self.max_seq_len_cached:
139
+ self._set_cos_sin_cache(seq_len=seq_len, device=x.device, dtype=x.dtype)
140
+
141
+ return (
142
+ self.cos_cached[:seq_len].to(dtype=x.dtype),
143
+ self.sin_cached[:seq_len].to(dtype=x.dtype),
144
  )
 
 
145
 
 
 
 
 
 
146
 
147
+ def yarn_find_correction_dim(num_rotations, dim, base=10000, max_position_embeddings=2048):
148
+ return (dim * math.log(max_position_embeddings / (num_rotations * 2 * math.pi))) / (2 * math.log(base))
149
+
150
+
151
+ def yarn_find_correction_range(low_rot, high_rot, dim, base=10000, max_position_embeddings=2048):
152
+ low = math.floor(yarn_find_correction_dim(low_rot, dim, base, max_position_embeddings))
153
+ high = math.ceil(yarn_find_correction_dim(high_rot, dim, base, max_position_embeddings))
154
+ return max(low, 0), min(high, dim - 1)
155
+
156
+
157
+ def yarn_get_mscale(scale=1, mscale=1):
158
+ if scale <= 1:
159
+ return 1.0
160
+ return 0.1 * mscale * math.log(scale) + 1.0
161
 
 
162
 
163
+ def yarn_linear_ramp_mask(min_val, max_val, dim):
164
+ if min_val == max_val:
165
+ max_val += 0.001
166
+ linear_func = (torch.arange(dim, dtype=torch.float32) - min_val) / (max_val - min_val)
167
+ return torch.clamp(linear_func, 0, 1)
168
 
169
+
170
+ class SarvamMLAYarnRotaryEmbedding(SarvamMLARotaryEmbedding):
171
+ def __init__(
172
+ self,
173
+ dim,
174
+ max_position_embeddings=2048,
175
+ base=10000,
176
+ device=None,
177
+ scaling_factor=40.0,
178
+ original_max_position_embeddings=4096,
179
+ beta_fast=32,
180
+ beta_slow=1,
181
+ mscale=1.0,
182
+ mscale_all_dim=1.0,
183
+ ):
184
+ self.scaling_factor = float(scaling_factor)
185
+ self.original_max_position_embeddings = int(original_max_position_embeddings)
186
+ self.beta_fast = float(beta_fast)
187
+ self.beta_slow = float(beta_slow)
188
+ self.mscale = float(mscale)
189
+ self.mscale_all_dim = float(mscale_all_dim)
190
+ super().__init__(dim, max_position_embeddings, base, device)
191
+
192
+ def _set_cos_sin_cache(self, seq_len, device, dtype):
193
+ self.max_seq_len_cached = seq_len
194
+ dim = self.dim
195
+
196
+ freq_extra = 1.0 / (self.base ** (torch.arange(0, dim, 2, dtype=torch.float32, device=device) / dim))
197
+ freq_inter = 1.0 / (
198
+ self.scaling_factor * self.base ** (torch.arange(0, dim, 2, dtype=torch.float32, device=device) / dim)
199
+ )
200
+
201
+ low, high = yarn_find_correction_range(
202
+ self.beta_fast,
203
+ self.beta_slow,
204
+ dim,
205
+ self.base,
206
+ self.original_max_position_embeddings,
207
+ )
208
+
209
+ inv_freq_mask = 1.0 - yarn_linear_ramp_mask(low, high, dim // 2).to(device=device, dtype=torch.float32)
210
+ inv_freq = freq_inter * (1 - inv_freq_mask) + freq_extra * inv_freq_mask
211
+ self.register_buffer("inv_freq", inv_freq, persistent=False)
212
+
213
+ t = torch.arange(seq_len, device=device, dtype=torch.float32)
214
+ freqs = torch.outer(t, inv_freq)
215
+
216
+ _mscale = float(
217
+ yarn_get_mscale(self.scaling_factor, self.mscale)
218
+ / yarn_get_mscale(self.scaling_factor, self.mscale_all_dim)
219
+ )
220
+
221
+ emb = torch.cat((freqs, freqs), dim=-1)
222
+ self.register_buffer("cos_cached", (emb.cos() * _mscale).to(dtype), persistent=False)
223
+ self.register_buffer("sin_cached", (emb.sin() * _mscale).to(dtype), persistent=False)
224
+
225
+
226
+ # Copied from transformers.models.llama.modeling_llama.rotate_half
227
  def rotate_half(x):
228
+ """Rotates half the hidden dims of the input."""
229
  x1 = x[..., : x.shape[-1] // 2]
230
  x2 = x[..., x.shape[-1] // 2 :]
231
  return torch.cat((-x2, x1), dim=-1)
232
 
233
 
234
+ # Copied from transformers.models.llama.modeling_llama.apply_rotary_pos_emb
235
+ def apply_rotary_pos_emb(q, k, cos, sin, position_ids, unsqueeze_dim=1):
236
+ cos = cos[position_ids].unsqueeze(unsqueeze_dim)
237
+ sin = sin[position_ids].unsqueeze(unsqueeze_dim)
238
+
239
+ b, h, s, d = q.shape
240
+ q = q.view(b, h, s, d // 2, 2).transpose(4, 3).reshape(b, h, s, d)
241
+
242
+ b, h, s, d = k.shape
243
+ k = k.view(b, h, s, d // 2, 2).transpose(4, 3).reshape(b, h, s, d)
244
+
245
+ q_embed = (q * cos) + (rotate_half(q) * sin)
246
+ k_embed = (k * cos) + (rotate_half(k) * sin)
247
  return q_embed, k_embed
248
 
249
 
250
+ class SarvamMLAMLP(nn.Module):
251
+ def __init__(self, config, hidden_size=None, intermediate_size=None):
252
  super().__init__()
253
  self.config = config
254
+ self.hidden_size = config.hidden_size if hidden_size is None else hidden_size
255
+ self.intermediate_size = config.intermediate_size if intermediate_size is None else intermediate_size
256
+
257
  self.gate_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=False)
258
  self.up_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=False)
259
  self.down_proj = nn.Linear(self.intermediate_size, self.hidden_size, bias=False)
260
  self.act_fn = ACT2FN[config.hidden_act]
261
 
262
  def forward(self, x):
263
+ down_proj = self.down_proj(self.act_fn(self.gate_proj(x)) * self.up_proj(x))
264
+ return down_proj
265
 
266
 
267
+ class MoEGate(nn.Module):
268
  def __init__(self, config):
269
  super().__init__()
270
  self.config = config
271
  self.top_k = config.num_experts_per_tok
272
+ self.n_routed_experts = config.num_experts
 
 
 
 
273
  self.routed_scaling_factor = config.routed_scaling_factor
274
+ self.scoring_func = "sigmoid"
275
+ self.topk_method = "noaux_tc"
276
+ self.n_group = getattr(config, "n_group", self.n_routed_experts // 8)
277
+ self.topk_group = getattr(config, "topk_group", 2)
278
+
279
+ self.norm_topk_prob = True
280
+ self.gating_dim = config.hidden_size
281
+ self.weight = nn.Parameter(torch.empty((self.n_routed_experts, self.gating_dim)))
282
+ if self.topk_method == "noaux_tc":
283
+ self.e_score_correction_bias = nn.Parameter(torch.empty((self.n_routed_experts)))
284
  self.reset_parameters()
285
 
286
  def reset_parameters(self) -> None:
287
  import torch.nn.init as init
288
 
289
  init.kaiming_uniform_(self.weight, a=math.sqrt(5))
290
+ if hasattr(self, "e_score_correction_bias"):
291
+ init.zeros_(self.e_score_correction_bias)
 
 
 
 
 
 
 
 
 
 
 
 
 
292
 
293
  def forward(self, hidden_states):
294
+ bsz, seq_len, h = hidden_states.shape
295
+ hidden_states = hidden_states.view(-1, h)
296
+ logits = F.linear(hidden_states.type(torch.float32), self.weight.type(torch.float32), None)
297
+ if self.scoring_func == "sigmoid":
298
+ scores = logits.sigmoid()
299
+ else:
300
+ raise NotImplementedError(f"insupportable scoring function for MoE gating: {self.scoring_func}")
301
+
302
+ if self.topk_method == "noaux_tc":
303
+ assert not self.training
304
+ scores_for_choice = scores.view(bsz * seq_len, -1) + self.e_score_correction_bias.unsqueeze(0)
305
+ group_scores = (
306
+ scores_for_choice.view(bsz * seq_len, self.n_group, -1).topk(2, dim=-1)[0].sum(dim=-1)
307
+ ) # [n, n_group]
308
+ group_idx = torch.topk(group_scores, k=self.topk_group, dim=-1, sorted=False)[1] # [n, top_k_group]
309
+ group_mask = torch.zeros_like(group_scores) # [n, n_group]
310
+ group_mask.scatter_(1, group_idx, 1) # [n, n_group]
311
+ score_mask = (
312
+ group_mask.unsqueeze(-1)
313
+ .expand(bsz * seq_len, self.n_group, self.n_routed_experts // self.n_group)
314
+ .reshape(bsz * seq_len, -1)
315
+ ) # [n, e]
316
+ tmp_scores = scores_for_choice.masked_fill(~score_mask.bool(), float("-inf")) # [n, e]
317
+ _, topk_idx = torch.topk(tmp_scores, k=self.top_k, dim=-1, sorted=False)
318
+ topk_weight = scores.gather(1, topk_idx)
319
+ else:
320
+ raise NotImplementedError(f"insupportable TopK function for MoE gating: {self.topk_method}")
321
+
322
+ ### norm gate to sum 1
323
+ if self.top_k > 1 and self.norm_topk_prob:
324
+ denominator = topk_weight.sum(dim=-1, keepdim=True) + 1e-20
325
+ topk_weight = topk_weight / denominator
326
+ topk_weight = topk_weight * self.routed_scaling_factor # must multiply the scaling factor
327
+
328
+ return topk_idx, topk_weight
329
+
330
+
331
+ class SarvamMLAMoE(nn.Module):
332
+ def __init__(self, config):
333
+ super().__init__()
334
  self.config = config
335
  self.num_experts_per_tok = config.num_experts_per_tok
336
 
337
+ if hasattr(config, "ep_size") and config.ep_size > 1:
338
+ assert config.ep_size == dist.get_world_size()
339
+ self.ep_size = config.ep_size
340
+ self.experts_per_rank = config.num_experts // config.ep_size
341
+ self.ep_rank = dist.get_rank()
342
+ self.experts = nn.ModuleList(
343
+ [
344
+ (
345
+ SarvamMLAMLP(config, intermediate_size=config.moe_intermediate_size)
346
+ if i >= self.ep_rank * self.experts_per_rank and i < (self.ep_rank + 1) * self.experts_per_rank
347
+ else None
348
+ )
349
+ for i in range(config.num_experts)
350
+ ]
351
+ )
352
+ else:
353
+ self.ep_size = 1
354
+ self.experts_per_rank = config.num_experts
355
+ self.ep_rank = 0
356
+ self.experts = nn.ModuleList(
357
+ [
358
+ SarvamMLAMLP(config, intermediate_size=config.moe_intermediate_size)
359
+ for i in range(config.num_experts)
360
+ ]
361
+ )
362
+ self.gate = MoEGate(config)
363
+ if (
364
+ hasattr(config, "num_shared_experts")
365
+ and config.num_shared_experts is not None
366
+ and config.num_shared_experts > 0
367
+ ):
368
+ intermediate_size = config.moe_intermediate_size * config.num_shared_experts
369
+ self.shared_experts = SarvamMLAMLP(config=config, intermediate_size=intermediate_size)
370
+ else:
371
+ self.shared_experts = None
372
+
373
+ def forward(self, hidden_states):
374
+ identity = hidden_states
375
+ orig_shape = hidden_states.shape
376
+ topk_idx, topk_weight = self.gate(hidden_states)
377
+ hidden_states = hidden_states.view(-1, hidden_states.shape[-1])
378
+ flat_topk_idx = topk_idx.view(-1)
379
+ if not self.training:
380
+ y = self.moe_infer(hidden_states, topk_idx, topk_weight).view(*orig_shape)
381
+ else:
382
+ # Training mode - simple implementation
383
+ # In practice, you'd want a more sophisticated training implementation
384
+ y = self.moe_infer(hidden_states, topk_idx, topk_weight).view(*orig_shape)
385
+ if self.shared_experts is not None:
386
+ y = y + self.shared_experts(identity)
387
+ return y
388
 
389
+ @torch.no_grad()
390
+ def moe_infer(self, x, topk_ids, topk_weight):
391
+ cnts = topk_ids.new_zeros((topk_ids.shape[0], len(self.experts)))
392
+ cnts.scatter_(1, topk_ids, 1)
393
+ tokens_per_expert = cnts.sum(dim=0)
394
+ idxs = topk_ids.view(-1).argsort()
395
+ sorted_tokens = x[idxs // topk_ids.shape[1]]
396
+ sorted_tokens_shape = sorted_tokens.shape
397
+ if self.ep_size > 1:
398
+ tokens_per_ep_rank = tokens_per_expert.view(self.ep_size, -1).sum(dim=1)
399
+ tokens_per_expert_group = tokens_per_expert.new_empty(tokens_per_expert.shape[0])
400
+ dist.all_to_all_single(tokens_per_expert_group, tokens_per_expert)
401
+ output_splits = tokens_per_expert_group.view(self.ep_size, -1).sum(1).cpu().numpy().tolist()
402
+ gathered_tokens = sorted_tokens.new_empty(
403
+ tokens_per_expert_group.sum(dim=0).cpu().item(), sorted_tokens.shape[1]
404
+ )
405
+ input_split_sizes = tokens_per_ep_rank.cpu().numpy().tolist()
406
+ dist.all_to_all(
407
+ list(gathered_tokens.split(output_splits)),
408
+ list(sorted_tokens.split(input_split_sizes)),
409
+ )
410
+ tokens_per_expert_post_gather = tokens_per_expert_group.view(self.ep_size, self.experts_per_rank).sum(dim=0)
411
+ gatherd_idxs = np.zeros(shape=(gathered_tokens.shape[0],), dtype=np.int32)
412
+ s = 0
413
+ for i, k in enumerate(tokens_per_expert_group.cpu().numpy()):
414
+ gatherd_idxs[s : s + k] = i % self.experts_per_rank
415
+ s += k
416
+ gatherd_idxs = gatherd_idxs.argsort()
417
+ sorted_tokens = gathered_tokens[gatherd_idxs]
418
+ tokens_per_expert = tokens_per_expert_post_gather
419
+ tokens_per_expert = tokens_per_expert.cpu().numpy()
420
 
 
421
  outputs = []
422
  start_idx = 0
423
  for i, num_tokens in enumerate(tokens_per_expert):
424
  end_idx = start_idx + num_tokens
425
  if num_tokens == 0:
426
  continue
427
+ expert = self.experts[i + self.ep_rank * self.experts_per_rank]
428
+ if expert is None:
429
+ continue
430
+ tokens_for_this_expert = sorted_tokens[start_idx:end_idx]
431
+ expert_out = expert(tokens_for_this_expert)
432
+ outputs.append(expert_out)
433
  start_idx = end_idx
434
 
435
  outs = torch.cat(outputs, dim=0) if len(outputs) else sorted_tokens.new_empty(0)
436
+ if self.ep_size > 1:
437
+ new_x = torch.empty_like(outs)
438
+ new_x[gatherd_idxs] = outs
439
+ gathered_tokens = new_x.new_empty(*sorted_tokens_shape)
440
+ dist.all_to_all(
441
+ list(gathered_tokens.split(input_split_sizes)),
442
+ list(new_x.split(output_splits)),
443
+ )
444
+ outs = gathered_tokens
445
+
446
  new_x = torch.empty_like(outs)
447
  new_x[idxs] = outs
 
448
  final_out = (
449
+ new_x.view(*topk_ids.shape, -1)
450
+ .type(topk_weight.dtype)
451
+ .mul_(topk_weight.unsqueeze(dim=-1))
452
  .sum(dim=1)
453
  .type(new_x.dtype)
454
  )
455
  return final_out
456
 
457
 
458
+ # Copied from transformers.models.llama.modeling_llama.repeat_kv
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
459
  def repeat_kv(hidden_states: torch.Tensor, n_rep: int) -> torch.Tensor:
460
  batch, num_key_value_heads, slen, head_dim = hidden_states.shape
461
  if n_rep == 1:
 
464
  return hidden_states.reshape(batch, num_key_value_heads * n_rep, slen, head_dim)
465
 
466
 
467
+ class SarvamMLAAttention(nn.Module):
468
+ is_causal = True
469
+ def __init__(self, config: SarvamMLAConfig, layer_idx: Optional[int] = None):
470
  super().__init__()
471
  self.config = config
472
  self.layer_idx = layer_idx
 
476
  "to errors during the forward call, if caching is used. Please make sure to provide a `layer_idx` "
477
  "when creating this class."
478
  )
479
+
480
  self.attention_dropout = config.attention_dropout
481
  self.hidden_size = config.hidden_size
482
  self.num_heads = config.num_attention_heads
483
+
 
 
 
 
484
  self.max_position_embeddings = config.max_position_embeddings
485
  self.rope_theta = config.rope_theta
486
+ self.q_lora_rank = getattr(config, "q_lora_rank", None)
487
+ self.qk_rope_head_dim = config.qk_rope_head_dim
488
+ self.kv_lora_rank = config.kv_lora_rank
489
+ self.v_head_dim = config.v_head_dim
490
+ self.qk_nope_head_dim = config.qk_nope_head_dim
491
+ self.q_head_dim = config.q_head_dim
492
+
493
+ if self.q_lora_rank is None:
494
+ self.q_proj = nn.Linear(self.hidden_size, self.num_heads * self.q_head_dim, bias=False)
495
+ else:
496
+ self.q_a_proj = nn.Linear(
497
+ self.hidden_size, config.q_lora_rank, bias=getattr(config, "attention_bias", False)
498
+ )
499
+ self.q_a_layernorm = SarvamMLARMSNorm(config.q_lora_rank)
500
+ self.q_b_proj = nn.Linear(config.q_lora_rank, self.num_heads * self.q_head_dim, bias=False)
501
+
502
+ self.kv_a_proj_with_mqa = nn.Linear(
503
  self.hidden_size,
504
+ config.kv_lora_rank + config.qk_rope_head_dim,
505
+ bias=getattr(config, "attention_bias", False),
506
+ )
507
+ self.kv_a_layernorm = SarvamMLARMSNorm(config.kv_lora_rank)
508
+ self.kv_b_proj = nn.Linear(
509
+ config.kv_lora_rank,
510
+ self.num_heads * (self.q_head_dim - self.qk_rope_head_dim + self.v_head_dim),
511
+ bias=False,
512
  )
513
+
514
+ self.o_proj = nn.Linear(
515
+ self.num_heads * self.v_head_dim,
516
+ self.hidden_size,
517
+ bias=getattr(config, "attention_bias", False),
518
+ )
519
+ self._init_rope()
520
+
521
+ self.softmax_scale = self.q_head_dim ** (-0.5)
522
+ if self.config.rope_scaling is not None:
523
+ mscale_all_dim = self.config.rope_scaling.get("mscale_all_dim", 0)
524
+ scaling_factor = self.config.rope_scaling["factor"]
525
+ if mscale_all_dim:
526
+ mscale = yarn_get_mscale(scaling_factor, mscale_all_dim)
527
+ self.softmax_scale = self.softmax_scale * mscale * mscale
528
+
529
+ def _init_rope(self):
530
+ rope_scaling = getattr(self.config, "rope_scaling", None)
531
+ if rope_scaling is None or rope_scaling.get("type", None) in (None, "default"):
532
+ self.rotary_emb = SarvamMLARotaryEmbedding(
533
+ self.qk_rope_head_dim,
534
+ max_position_embeddings=self.max_position_embeddings,
535
+ base=self.rope_theta,
536
+ )
537
+ return
538
+
539
+ rope_type = rope_scaling.get("type")
540
+ if rope_type == "deepseek_yarn":
541
+ self.rotary_emb = SarvamMLAYarnRotaryEmbedding(
542
+ self.qk_rope_head_dim,
543
+ max_position_embeddings=self.max_position_embeddings,
544
+ base=self.rope_theta,
545
+ scaling_factor=rope_scaling.get("factor", 40.0),
546
+ original_max_position_embeddings=rope_scaling.get("original_max_position_embeddings", 4096),
547
+ beta_fast=rope_scaling.get("beta_fast", 32),
548
+ beta_slow=rope_scaling.get("beta_slow", 1),
549
+ mscale=rope_scaling.get("mscale", 1.0),
550
+ mscale_all_dim=rope_scaling.get("mscale_all_dim", 1.0),
551
+ )
552
+ return
553
+ raise ValueError(f"Unknown rope_scaling type: {rope_type}")
554
 
555
  def _shape(self, tensor: torch.Tensor, seq_len: int, bsz: int):
556
+ return tensor.view(bsz, seq_len, self.num_heads, self.v_head_dim).transpose(1, 2).contiguous()
557
 
558
  def forward(
559
  self,
 
563
  past_key_value: Optional[Cache] = None,
564
  output_attentions: bool = False,
565
  use_cache: bool = False,
 
566
  **kwargs,
567
+ ) -> Tuple[torch.Tensor, Optional[torch.Tensor], Optional[Tuple[torch.Tensor]]]:
568
  bsz, q_len, _ = hidden_states.size()
569
+
570
+ if self.q_lora_rank is None:
571
+ q = self.q_proj(hidden_states)
572
+ else:
573
+ q = self.q_b_proj(self.q_a_layernorm(self.q_a_proj(hidden_states)))
574
+ q = q.view(bsz, q_len, self.num_heads, self.q_head_dim).transpose(1, 2)
575
+ q_nope, q_pe = torch.split(q, [self.qk_nope_head_dim, self.qk_rope_head_dim], dim=-1)
576
+
577
+ compressed_kv = self.kv_a_proj_with_mqa(hidden_states)
578
+ compressed_kv, k_pe = torch.split(compressed_kv, [self.kv_lora_rank, self.qk_rope_head_dim], dim=-1)
579
+ k_pe = k_pe.view(bsz, q_len, 1, self.qk_rope_head_dim).transpose(1, 2)
580
+ kv = (
581
+ self.kv_b_proj(self.kv_a_layernorm(compressed_kv))
582
+ .view(bsz, q_len, self.num_heads, self.qk_nope_head_dim + self.v_head_dim)
583
+ .transpose(1, 2)
 
 
584
  )
585
+
586
+ k_nope, value_states = torch.split(kv, [self.qk_nope_head_dim, self.v_head_dim], dim=-1)
587
+ kv_seq_len = value_states.shape[-2]
588
  if past_key_value is not None:
589
  if self.layer_idx is None:
590
  raise ValueError(
591
+ f"The cache structure has changed in a previous version. If you are using {self.__class__.__name__} "
592
+ "for auto-regressive decoding with k/v caching, please make sure to initialize the attention class "
593
+ "with a layer index."
594
  )
595
+ kv_seq_len += _get_usable_past_kv_length(past_key_value, kv_seq_len, self.layer_idx)
596
+ cos, sin = self.rotary_emb(value_states, seq_len=kv_seq_len)
597
+
598
+ q_pe, k_pe = apply_rotary_pos_emb(q_pe, k_pe, cos, sin, position_ids)
599
+
600
+ query_states = k_pe.new_empty(bsz, self.num_heads, q_len, self.q_head_dim)
601
+ query_states[:, :, :, : self.qk_nope_head_dim] = q_nope
602
+ query_states[:, :, :, self.qk_nope_head_dim :] = q_pe
603
+
604
+ key_states = k_pe.new_empty(bsz, self.num_heads, q_len, self.q_head_dim)
605
+ key_states[:, :, :, : self.qk_nope_head_dim] = k_nope
606
+ key_states[:, :, :, self.qk_nope_head_dim :] = k_pe
607
+ if past_key_value is not None:
608
+ cache_kwargs = {"sin": sin, "cos": cos} # Specific to RoPE models
609
+ key_states, value_states = past_key_value.update(key_states, value_states, self.layer_idx, cache_kwargs)
610
+
611
+ attn_weights = torch.matmul(query_states, key_states.transpose(2, 3)) * self.softmax_scale
612
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
613
  if attn_weights.size() != (bsz, self.num_heads, q_len, kv_seq_len):
614
  raise ValueError(
615
  f"Attention weights should be of size {(bsz, self.num_heads, q_len, kv_seq_len)}, but is"
616
  f" {attn_weights.size()}"
617
  )
618
+ assert attention_mask is not None
619
  if attention_mask is not None:
620
  if attention_mask.size() != (bsz, 1, q_len, kv_seq_len):
621
  raise ValueError(
622
  f"Attention mask should be of size {(bsz, 1, q_len, kv_seq_len)}, but is {attention_mask.size()}"
623
  )
624
  attn_weights = attn_weights + attention_mask
625
+
626
  attn_weights = nn.functional.softmax(attn_weights, dim=-1, dtype=torch.float32).to(query_states.dtype)
627
  attn_weights = nn.functional.dropout(attn_weights, p=self.attention_dropout, training=self.training)
628
  attn_output = torch.matmul(attn_weights, value_states)
629
+
630
+ if attn_output.size() != (bsz, self.num_heads, q_len, self.v_head_dim):
631
  raise ValueError(
632
+ f"`attn_output` should be of size {(bsz, self.num_heads, q_len, self.v_head_dim)}, but is"
633
  f" {attn_output.size()}"
634
  )
635
  attn_output = attn_output.transpose(1, 2).contiguous()
636
+ attn_output = attn_output.reshape(bsz, q_len, self.num_heads * self.v_head_dim)
637
+ attn_output = self.o_proj(attn_output)
 
 
 
 
638
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
639
  if not output_attentions:
640
  attn_weights = None
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
641
 
642
+ return attn_output, attn_weights, past_key_value
 
 
 
 
 
 
643
 
644
 
645
+ class SarvamMLADecoderLayer(nn.Module):
646
+ def __init__(self, config: SarvamMLAConfig, layer_idx: int):
647
  super().__init__()
648
  self.hidden_size = config.hidden_size
649
+ self.self_attn = SarvamMLAAttention(config=config, layer_idx=layer_idx)
650
+
651
+ use_moe = (
652
+ hasattr(config, "num_experts")
653
+ and config.num_experts is not None
654
+ and layer_idx >= getattr(config, "first_k_dense_replace", 0)
655
+ and layer_idx % getattr(config, "moe_layer_freq", 1) == 0
656
  )
657
+
658
+ self.mlp = SarvamMLAMoE(config) if use_moe else SarvamMLAMLP(config)
659
+ self.input_layernorm = SarvamMLARMSNorm(config.hidden_size, eps=config.rms_norm_eps)
660
+ self.post_attention_layernorm = SarvamMLARMSNorm(config.hidden_size, eps=config.rms_norm_eps)
661
 
662
  def forward(
663
  self,
 
666
  position_ids: Optional[torch.LongTensor] = None,
667
  past_key_value: Optional[Tuple[torch.Tensor]] = None,
668
  output_attentions: Optional[bool] = False,
 
669
  use_cache: Optional[bool] = False,
 
670
  **kwargs,
671
  ) -> Tuple[torch.FloatTensor, Optional[Tuple[torch.FloatTensor, torch.FloatTensor]]]:
672
  residual = hidden_states
673
  hidden_states = self.input_layernorm(hidden_states)
674
+
675
+ hidden_states, self_attn_weights, present_key_value = self.self_attn(
676
  hidden_states=hidden_states,
677
  attention_mask=attention_mask,
678
  position_ids=position_ids,
679
  past_key_value=past_key_value,
680
  output_attentions=output_attentions,
 
681
  use_cache=use_cache,
682
  **kwargs,
683
  )
684
  hidden_states = residual + hidden_states
685
+
686
  residual = hidden_states
687
  hidden_states = self.post_attention_layernorm(hidden_states)
688
  hidden_states = self.mlp(hidden_states)
689
+ hidden_states = residual + hidden_states
690
+
 
 
 
691
  outputs = (hidden_states,)
692
+
693
  if output_attentions:
694
  outputs += (self_attn_weights,)
695
  if use_cache:
696
  outputs += (present_key_value,)
 
 
697
  return outputs
698
 
699
+
700
+ class SarvamMLAPreTrainedModel(PreTrainedModel):
701
+ config_class = SarvamMLAConfig
702
  base_model_prefix = "model"
703
  supports_gradient_checkpointing = True
704
+ _no_split_modules = ["SarvamMLADecoderLayer"]
705
  _skip_keys_device_placement = "past_key_values"
706
+ _supports_flash_attn_2 = False # Not implemented yet
 
707
  _supports_cache_class = True
708
 
709
  def _init_weights(self, module):
 
718
  module.weight.data[module.padding_idx].zero_()
719
 
720
 
721
+ class SarvamMLAModel(SarvamMLAPreTrainedModel):
722
+ def __init__(self, config: SarvamMLAConfig):
 
 
723
  super().__init__(config)
724
  self.padding_idx = config.pad_token_id
725
  self.vocab_size = config.vocab_size
726
+
727
+ self.embed_tokens = nn.Embedding(config.vocab_size, config.hidden_size, self.padding_idx)
728
+ self.layers = nn.ModuleList(
729
+ [SarvamMLADecoderLayer(config, layer_idx) for layer_idx in range(config.num_hidden_layers)]
730
+ )
731
+ self._use_flash_attention_2 = False # Not implemented yet
732
+ self.norm = SarvamMLARMSNorm(config.hidden_size, eps=config.rms_norm_eps)
733
+
 
734
  self.gradient_checkpointing = False
735
+ # Initialize weights and apply final processing
736
  self.post_init()
737
 
738
  def get_input_embeddings(self):
739
+ return self.embed_tokens
740
 
741
  def set_input_embeddings(self, value):
742
+ self.embed_tokens = value
743
 
744
  def forward(
745
  self,
 
751
  use_cache: Optional[bool] = None,
752
  output_attentions: Optional[bool] = None,
753
  output_hidden_states: Optional[bool] = None,
 
754
  return_dict: Optional[bool] = None,
755
+ ) -> Union[Tuple, BaseModelOutputWithPast]:
 
756
  output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions
757
  output_hidden_states = (
758
  output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states
759
  )
 
 
 
760
  use_cache = use_cache if use_cache is not None else self.config.use_cache
761
+
762
  return_dict = return_dict if return_dict is not None else self.config.use_return_dict
763
+
764
+ # retrieve input_ids and inputs_embeds
765
  if input_ids is not None and inputs_embeds is not None:
766
  raise ValueError("You cannot specify both input_ids and inputs_embeds at the same time")
767
  elif input_ids is not None:
 
770
  batch_size, seq_length = inputs_embeds.shape[:2]
771
  else:
772
  raise ValueError("You have to specify either input_ids or inputs_embeds")
773
+
774
+ past_key_values_length = 0
775
+ if use_cache:
776
+ use_legacy_cache = not isinstance(past_key_values, Cache)
777
+ if use_legacy_cache:
778
+ past_key_values = DynamicCache.from_legacy_cache(past_key_values)
779
+ past_key_values_length = _get_usable_past_kv_length(past_key_values, seq_length)
780
+
 
 
 
781
  if position_ids is None:
782
+ device = input_ids.device if input_ids is not None else inputs_embeds.device
783
  position_ids = torch.arange(
784
+ past_key_values_length,
785
+ seq_length + past_key_values_length,
786
+ dtype=torch.long,
787
+ device=device,
788
  )
789
  position_ids = position_ids.unsqueeze(0)
790
+
791
+ if inputs_embeds is None:
792
+ inputs_embeds = self.embed_tokens(input_ids)
793
+
794
+ attention_mask = _prepare_4d_causal_attention_mask(
795
+ attention_mask,
796
+ (batch_size, seq_length),
797
+ inputs_embeds,
798
+ past_key_values_length,
799
+ )
800
+
 
 
801
  hidden_states = inputs_embeds
 
802
  all_hidden_states = () if output_hidden_states else None
803
  all_self_attns = () if output_attentions else None
 
804
  next_decoder_cache = None
805
+
806
+ for decoder_layer in self.layers:
807
  if output_hidden_states:
808
  all_hidden_states += (hidden_states,)
809
+
810
+ layer_outputs = decoder_layer(
811
+ hidden_states,
812
+ attention_mask=attention_mask,
813
+ position_ids=position_ids,
814
+ past_key_value=past_key_values,
815
+ output_attentions=output_attentions,
816
+ use_cache=use_cache,
817
+ )
818
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
819
  hidden_states = layer_outputs[0]
820
  if use_cache:
821
  next_decoder_cache = layer_outputs[2 if output_attentions else 1]
822
  if output_attentions:
823
  all_self_attns += (layer_outputs[1],)
824
+
 
825
  hidden_states = self.norm(hidden_states)
826
+
827
  if output_hidden_states:
828
  all_hidden_states += (hidden_states,)
829
+
830
  next_cache = None
831
  if use_cache:
832
+ next_cache = next_decoder_cache.to_legacy_cache() if use_legacy_cache else next_decoder_cache
833
  if not return_dict:
834
+ return tuple(v for v in [hidden_states, next_cache, all_hidden_states, all_self_attns] if v is not None)
835
+ return BaseModelOutputWithPast(
 
 
836
  last_hidden_state=hidden_states,
837
  past_key_values=next_cache,
838
  hidden_states=all_hidden_states,
839
  attentions=all_self_attns,
 
840
  )
841
 
842
 
843
+ class SarvamMLAForCausalLM(SarvamMLAPreTrainedModel):
844
  _tied_weights_keys = ["lm_head.weight"]
845
 
846
+ def __init__(self, config):
847
  super().__init__(config)
848
+ self.model = SarvamMLAModel(config)
849
  self.vocab_size = config.vocab_size
850
  self.lm_head = nn.Linear(config.hidden_size, config.vocab_size, bias=False)
851
  self.post_init()
852
 
853
  def get_input_embeddings(self):
854
+ return self.model.embed_tokens
855
 
856
  def set_input_embeddings(self, value):
857
+ self.model.embed_tokens = value
858
 
859
  def get_output_embeddings(self):
860
  return self.lm_head
 
879
  use_cache: Optional[bool] = None,
880
  output_attentions: Optional[bool] = None,
881
  output_hidden_states: Optional[bool] = None,
 
882
  return_dict: Optional[bool] = None,
883
+ ) -> Union[Tuple, CausalLMOutputWithPast]:
 
884
  output_attentions = output_attentions if output_attentions is not None else self.config.output_attentions
885
  output_hidden_states = (
886
  output_hidden_states if output_hidden_states is not None else self.config.output_hidden_states
887
  )
 
 
 
888
  return_dict = return_dict if return_dict is not None else self.config.use_return_dict
889
+
890
  outputs = self.model(
891
  input_ids=input_ids,
892
  attention_mask=attention_mask,
 
896
  use_cache=use_cache,
897
  output_attentions=output_attentions,
898
  output_hidden_states=output_hidden_states,
 
899
  return_dict=return_dict,
 
900
  )
901
+
 
902
  hidden_states = outputs[0]
903
  logits = self.lm_head(hidden_states)
904
  logits = logits.float()
905
+
906
+ loss = None
907
  if labels is not None:
908
+ # Shift so that tokens < n predict n
909
+ shift_logits = logits[..., :-1, :].contiguous()
910
+ shift_labels = labels[..., 1:].contiguous()
911
+ # Flatten the tokens
912
+ loss_fct = CrossEntropyLoss()
913
+ shift_logits = shift_logits.view(-1, self.config.vocab_size)
914
+ shift_labels = shift_labels.view(-1)
915
+ # Enable model parallelism
916
+ shift_labels = shift_labels.to(shift_logits.device)
917
+ loss = loss_fct(shift_logits, shift_labels)
918
+
919
  if not return_dict:
920
  output = (logits,) + outputs[1:]
 
 
921
  return (loss,) + output if loss is not None else output
922
+
923
+ return CausalLMOutputWithPast(
924
  loss=loss,
925
  logits=logits,
926
  past_key_values=outputs.past_key_values,
927
  hidden_states=outputs.hidden_states,
928
  attentions=outputs.attentions,
929
+ )
930
+
931
+ def prepare_inputs_for_generation(
932
+ self,
933
+ input_ids,
934
+ past_key_values=None,
935
+ attention_mask=None,
936
+ inputs_embeds=None,
937
+ **kwargs,
938
+ ):
939
+ if past_key_values is not None:
940
+ if isinstance(past_key_values, Cache):
941
+ cache_length = past_key_values.get_seq_length()
942
+ past_length = past_key_values.get_seq_length() if past_key_values is not None else 0
943
+ if hasattr(past_key_values, "get_max_length"):
944
+ max_cache_length = past_key_values.get_max_length()
945
+ else:
946
+ max_cache_length = None
947
+ else:
948
+ cache_length = past_length = past_key_values[0][0].shape[2]
949
+ max_cache_length = None
950
+
951
+ if attention_mask is not None and attention_mask.shape[1] > input_ids.shape[1]:
952
+ input_ids = input_ids[:, -(attention_mask.shape[1] - past_length) :]
953
+ elif past_length < input_ids.shape[1]:
954
+ input_ids = input_ids[:, past_length:]
955
+
956
+ if (
957
+ max_cache_length is not None
958
+ and attention_mask is not None
959
+ and cache_length + input_ids.shape[1] > max_cache_length
960
+ ):
961
+ attention_mask = attention_mask[:, -max_cache_length:]
962
+
963
+ position_ids = kwargs.get("position_ids", None)
964
+ if attention_mask is not None and position_ids is None:
965
+ position_ids = attention_mask.long().cumsum(-1) - 1
966
+ position_ids.masked_fill_(attention_mask == 0, 1)
967
+ if past_key_values:
968
+ position_ids = position_ids[:, -input_ids.shape[1] :]
969
+
970
+ # if `inputs_embeds` are passed, we only want to use them in the 1st generation step
971
+ if inputs_embeds is not None and past_key_values is None:
972
+ model_inputs = {"inputs_embeds": inputs_embeds}
973
+ else:
974
+ model_inputs = {"input_ids": input_ids}
975
+
976
+ model_inputs.update(
977
+ {
978
+ "position_ids": position_ids,
979
+ "past_key_values": past_key_values,
980
+ "use_cache": kwargs.get("use_cache"),
981
+ "attention_mask": attention_mask,
982
+ }
983
+ )
984
+ return model_inputs
985
+
986
+ @staticmethod
987
+ def _reorder_cache(past_key_values, beam_idx):
988
+ reordered_past = ()
989
+ for layer_past in past_key_values:
990
+ reordered_past += (
991
+ tuple(past_state.index_select(0, beam_idx.to(past_state.device)) for past_state in layer_past),
992
+ )
993
+ return reordered_past
tokenizer.json CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:29af880c3290d504b4ee80d998f4c48de7ba5972656e745226c47a8723238412
3
- size 33627350
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:a574ceaaff7c7a8f091179c53fd17ae33567089c099d4ff37d4cb3bc1a87e80e
3
+ size 33627251