-
Notifications
You must be signed in to change notification settings - Fork 34k
Update Mamba types and pass through use_cache attr to MambaModel #29605
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 5 commits
77eacd9
c975cf5
c1211ce
e4aa1b6
f9b13ec
5816a8d
5a3f59d
d8aea25
2c3fa5b
72f99a0
de6eef1
d16ffce
b4438a8
b0e7160
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -16,7 +16,7 @@ | |
|
|
||
| import math | ||
| from dataclasses import dataclass | ||
| from typing import Any, Dict, List, Optional, Tuple, Union | ||
| from typing import Any, Dict, Optional, Tuple, Union | ||
|
|
||
| import torch | ||
| import torch.utils.checkpoint | ||
|
|
@@ -50,7 +50,13 @@ | |
| causal_conv1d_update, causal_conv1d_fn = None, None | ||
|
|
||
| is_fast_path_available = all( | ||
| (selective_state_update, selective_scan_fn, causal_conv1d_fn, causal_conv1d_update, mamba_inner_fn) | ||
| ( | ||
| selective_state_update, | ||
| selective_scan_fn, | ||
| causal_conv1d_fn, | ||
| causal_conv1d_update, | ||
| mamba_inner_fn, | ||
| ) | ||
| ) | ||
|
|
||
| _CHECKPOINT_FOR_DOC = "state-spaces/mamba-130m-hf" | ||
|
|
@@ -59,6 +65,36 @@ | |
| MAMBA_PRETRAINED_MODEL_ARCHIVE_LIST = [] # See all Mamba models at https://huggingface.co/models?filter=mamba | ||
|
|
||
|
|
||
| class MambaCache: | ||
| def __init__(self, config, batch_size, dtype=torch.float16, device=None): | ||
| self.seqlen_offset = 0 | ||
| self.dtype = dtype | ||
| intermediate_size = config.intermediate_size | ||
| ssm_state_size = config.state_size | ||
| conv_kernel_size = config.conv_kernel | ||
|
|
||
| self.conv_states = { | ||
| i: torch.zeros( | ||
| batch_size, | ||
| intermediate_size, | ||
| conv_kernel_size, | ||
| device=device, | ||
| dtype=dtype, | ||
| ) | ||
| for i in range(config.num_hidden_layers) | ||
| } | ||
| self.ssm_states = { | ||
| i: torch.zeros( | ||
| batch_size, | ||
| intermediate_size, | ||
| ssm_state_size, | ||
| device=device, | ||
| dtype=dtype, | ||
| ) | ||
| for i in range(config.num_hidden_layers) | ||
| } | ||
|
|
||
|
|
||
| class MambaMixer(nn.Module): | ||
| """ | ||
| Compute ∆, A, B, C, and D the state space parameters and compute the `contextualized_states`. | ||
|
|
@@ -91,7 +127,11 @@ def __init__(self, config, layer_idx): | |
| # projection of the input hidden states | ||
| self.in_proj = nn.Linear(self.hidden_size, self.intermediate_size * 2, bias=config.use_bias) | ||
| # selective projection used to make dt, B and C input dependant | ||
| self.x_proj = nn.Linear(self.intermediate_size, self.time_step_rank + self.ssm_state_size * 2, bias=False) | ||
| self.x_proj = nn.Linear( | ||
| self.intermediate_size, | ||
| self.time_step_rank + self.ssm_state_size * 2, | ||
| bias=False, | ||
| ) | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same here |
||
| # time step projection (discretization) | ||
| self.dt_proj = nn.Linear(self.time_step_rank, self.intermediate_size, bias=True) | ||
|
|
||
|
|
@@ -112,7 +152,7 @@ def __init__(self, config, layer_idx): | |
| " https://github.com/Dao-AILab/causal-conv1d" | ||
| ) | ||
|
|
||
| def cuda_kernels_forward(self, hidden_states: torch.Tensor, cache_params=None): | ||
| def cuda_kernels_forward(self, hidden_states: torch.Tensor, cache_params: Optional[MambaCache] = None): | ||
| # 1. Gated MLP's linear projection | ||
| projected_states = self.in_proj(hidden_states).transpose(1, 2) | ||
|
|
||
|
|
@@ -150,18 +190,24 @@ def cuda_kernels_forward(self, hidden_states: torch.Tensor, cache_params=None): | |
| else: | ||
| if cache_params is not None: | ||
| conv_states = nn.functional.pad( | ||
| hidden_states, (self.conv_kernel_size - hidden_states.shape[-1], 0) | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same here, unrelated change |
||
| hidden_states, | ||
| (self.conv_kernel_size - hidden_states.shape[-1], 0), | ||
| ) | ||
| cache_params.conv_states[self.layer_idx].copy_(conv_states) | ||
| hidden_states = causal_conv1d_fn( | ||
| hidden_states, conv_weights, self.conv1d.bias, activation=self.activation | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. snae gere |
||
| hidden_states, | ||
| conv_weights, | ||
| self.conv1d.bias, | ||
| activation=self.activation, | ||
| ) | ||
|
|
||
| # 3. State Space Model sequence transformation | ||
| # 3.a. input varying initialization of time_step, B and C | ||
| ssm_parameters = self.x_proj(hidden_states.transpose(1, 2)) | ||
| time_step, B, C = torch.split( | ||
| ssm_parameters, [self.time_step_rank, self.ssm_state_size, self.ssm_state_size], dim=-1 | ||
| ssm_parameters, | ||
| [self.time_step_rank, self.ssm_state_size, self.ssm_state_size], | ||
| dim=-1, | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same here, unrelated change |
||
| ) | ||
| discrete_time_step = self.dt_proj.weight @ time_step.transpose(1, 2) | ||
|
|
||
|
|
@@ -202,7 +248,7 @@ def cuda_kernels_forward(self, hidden_states: torch.Tensor, cache_params=None): | |
| return contextualized_states | ||
|
|
||
| # fmt: off | ||
| def slow_forward(self, input_states, cache_params=None): | ||
| def slow_forward(self, input_states, cache_params: Optional[MambaCache]=None): | ||
| batch_size, seq_len, _ = input_states.shape | ||
| dtype = input_states.dtype | ||
| # 1. Gated MLP's linear projection | ||
|
|
@@ -268,34 +314,16 @@ def slow_forward(self, input_states, cache_params=None): | |
| return contextualized_states | ||
| # fmt: on | ||
|
|
||
| def forward(self, hidden_states, cache_params=None): | ||
| def forward(self, hidden_states, cache_params: Optional[MambaCache] = None): | ||
| if is_fast_path_available and "cuda" in self.x_proj.weight.device.type: | ||
| return self.cuda_kernels_forward(hidden_states, cache_params) | ||
| return self.slow_forward(hidden_states, cache_params) | ||
|
|
||
|
|
||
| class MambaCache: | ||
| def __init__(self, config, batch_size, dtype=torch.float16, device=None): | ||
| self.seqlen_offset = 0 | ||
| self.dtype = dtype | ||
| intermediate_size = config.intermediate_size | ||
| ssm_state_size = config.state_size | ||
| conv_kernel_size = config.conv_kernel | ||
|
|
||
| self.conv_states = { | ||
| i: torch.zeros(batch_size, intermediate_size, conv_kernel_size, device=device, dtype=dtype) | ||
| for i in range(config.num_hidden_layers) | ||
| } | ||
| self.ssm_states = { | ||
| i: torch.zeros(batch_size, intermediate_size, ssm_state_size, device=device, dtype=dtype) | ||
| for i in range(config.num_hidden_layers) | ||
| } | ||
|
|
||
|
Comment on lines
-277
to
-293
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. if moved, let's just keep the styling of this one please |
||
|
|
||
| class MambaRMSNorm(nn.Module): | ||
| def __init__(self, hidden_size, eps=1e-6): | ||
| """ | ||
| LlamaRMSNorm is equivalent to T5LayerNorm | ||
| MambaRMSNorm is equivalent to T5LayerNorm and LlamaRMSNorm | ||
| """ | ||
| super().__init__() | ||
| self.weight = nn.Parameter(torch.ones(hidden_size)) | ||
|
|
@@ -318,7 +346,7 @@ def __init__(self, config, layer_idx): | |
| self.norm = MambaRMSNorm(config.hidden_size, eps=config.layer_norm_epsilon) | ||
| self.mixer = MambaMixer(config, layer_idx=layer_idx) | ||
|
|
||
| def forward(self, hidden_states, cache_params=None): | ||
| def forward(self, hidden_states, cache_params: Optional[MambaCache] = None): | ||
| residual = hidden_states | ||
| hidden_states = self.norm(hidden_states.to(dtype=self.norm.weight.dtype)) | ||
| if self.residual_in_fp32: | ||
|
|
@@ -396,20 +424,20 @@ class MambaOutput(ModelOutput): | |
| Args: | ||
| last_hidden_state (`torch.FloatTensor` of shape `(batch_size, sequence_length, hidden_size)`): | ||
| Sequence of hidden-states at the output of the last layer of the model. | ||
| cache_params (list of five `torch.FloatTensor` of shape `(batch_size, hidden_size, num_hidden_layers)`): | ||
| cache_params (`MambaCache`): | ||
| The state of the model at the last time step. Can be used in a forward method with the next `input_ids` to | ||
| avoid providing the old `input_ids`. | ||
|
|
||
| Includes both the State space model states weights after the selective scan, and the Convolutional states | ||
| Includes both the State space model state matrices after the selective scan, and the Convolutional states | ||
| hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): | ||
| Tuple of `torch.FloatTensor` (one for the output of the embeddings, if the model has an embedding layer, + | ||
| one for the output of each layer) of shape `(batch_size, sequence_length, hidden_size)`. | ||
|
|
||
| Hidden-states of the model at the output of each layer plus the optional initial embedding outputs. | ||
| """ | ||
|
|
||
| last_hidden_state: torch.FloatTensor = None | ||
| cache_params: Optional[List[torch.FloatTensor]] = None | ||
| last_hidden_state: Optional[torch.FloatTensor] = None | ||
| cache_params: Optional[MambaCache] = None | ||
| hidden_states: Optional[Tuple[torch.FloatTensor]] = None | ||
|
|
||
|
|
||
|
|
@@ -423,9 +451,11 @@ class MambaCausalLMOutput(ModelOutput): | |
| Language modeling loss (for next-token prediction). | ||
| logits (`torch.FloatTensor` of shape `(batch_size, sequence_length, config.vocab_size)`): | ||
| Prediction scores of the language modeling head (scores for each vocabulary token before SoftMax). | ||
| cache_params (list of five `torch.FloatTensor` of shape `(batch_size, hidden_size, num_hidden_layers)`): | ||
| cache_params (`MambaCache`): | ||
| The state of the model at the last time step. Can be used in a forward method with the next `input_ids` to | ||
| avoid providing the old `input_ids`. | ||
|
|
||
| Includes both the State space model state matrices after the selective scan, and the Convolutional states | ||
| hidden_states (`tuple(torch.FloatTensor)`, *optional*, returned when `output_hidden_states=True` is passed or when `config.output_hidden_states=True`): | ||
| Tuple of `torch.FloatTensor` (one for the output of the embeddings, if the model has an embedding layer, + | ||
| one for the output of each layer) of shape `(batch_size, sequence_length, hidden_size)`. | ||
|
|
@@ -434,8 +464,8 @@ class MambaCausalLMOutput(ModelOutput): | |
| """ | ||
|
|
||
| loss: Optional[torch.FloatTensor] = None | ||
| logits: torch.FloatTensor = None | ||
| cache_params: Optional[List[torch.FloatTensor]] = None | ||
| logits: Optional[torch.FloatTensor] = None | ||
| cache_params: Optional[MambaCache] = None | ||
| hidden_states: Optional[Tuple[torch.FloatTensor]] = None | ||
|
|
||
|
|
||
|
|
@@ -516,7 +546,7 @@ def forward( | |
| self, | ||
| input_ids: Optional[torch.LongTensor] = None, | ||
| inputs_embeds: Optional[torch.LongTensor] = None, | ||
| cache_params: Optional[List[torch.FloatTensor]] = None, | ||
| cache_params: Optional[MambaCache] = None, | ||
| use_cache: Optional[bool] = None, | ||
| output_hidden_states: Optional[bool] = None, | ||
| return_dict: Optional[bool] = None, | ||
|
|
@@ -541,7 +571,10 @@ def forward( | |
|
|
||
| if cache_params is None and use_cache: | ||
| cache_params = MambaCache( | ||
| self.config, inputs_embeds.size(0), device=inputs_embeds.device, dtype=inputs_embeds.dtype | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. unrelated change let's revert |
||
| self.config, | ||
| inputs_embeds.size(0), | ||
| device=inputs_embeds.device, | ||
| dtype=inputs_embeds.dtype, | ||
| ) | ||
|
|
||
| hidden_states = inputs_embeds | ||
|
|
@@ -609,7 +642,12 @@ def _update_model_kwargs_for_generation( | |
| return model_kwargs | ||
|
|
||
| def prepare_inputs_for_generation( | ||
| self, input_ids, cache_params=None, inputs_embeds=None, attention_mask=None, **kwargs | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same here |
||
| self, | ||
| input_ids, | ||
| cache_params: Optional[MambaCache] = None, | ||
| inputs_embeds=None, | ||
| attention_mask=None, | ||
| **kwargs, | ||
| ): | ||
| # only last token for inputs_ids if the state is passed along. | ||
| if cache_params is not None: | ||
|
|
@@ -633,7 +671,7 @@ def forward( | |
| self, | ||
| input_ids: Optional[torch.LongTensor] = None, | ||
| inputs_embeds: Optional[torch.FloatTensor] = None, | ||
| cache_params: Optional[torch.FloatTensor] = None, | ||
| cache_params: Optional[MambaCache] = None, | ||
| labels: Optional[torch.LongTensor] = None, | ||
| output_hidden_states: Optional[bool] = None, | ||
| return_dict: Optional[bool] = None, | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. let's add use_cache as an arg here
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @ArthurZucker Added! 👍
koayon marked this conversation as resolved.
|
||
|
|
@@ -653,6 +691,7 @@ def forward( | |
| inputs_embeds=inputs_embeds, | ||
| output_hidden_states=output_hidden_states, | ||
| return_dict=return_dict, | ||
| **kwargs, | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why is this required? it should not. The cache params are passed right above
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe it's the use_cache argument that needs to be passed in for this to work as expected - we could restrict to just passing that through?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Have amended this to only pass through the
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. perfect |
||
| ) | ||
| hidden_states = mamba_outputs[0] | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is unrelated and is styling, should be reverted!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, I've updated the styling 👌