HanseLM-78M-Base / modeling_hanse.py
Evicka's picture
Add files using upload-large-folder tool
e8ac551 verified
Raw
History Blame Contribute Delete
2.46 kB
from __future__ import annotations
import torch
import torch.nn.functional as F
from torch import nn
from transformers import GenerationMixin, PreTrainedModel
from transformers.modeling_outputs import CausalLMOutput
from .configuration_hanse import HanseConfig
from .modeling_hanse_layers import HanseBlock, HanseRMSNorm, initialize_weights
class HanseForCausalLM(PreTrainedModel, GenerationMixin):
config_class = HanseConfig
base_model_prefix = "hanse"
_tied_weights_keys = ["lm_head.weight"]
_supports_assign_param_buffer = False
def __init__(self, config: HanseConfig) -> None:
super().__init__(config)
self.token_embedding = nn.Embedding(config.vocab_size, config.hidden_size)
self.blocks = nn.ModuleList(
HanseBlock(config, kind) for kind in config.layer_pattern
)
self.final_norm = HanseRMSNorm(config.hidden_size, config.norm_eps)
self.lm_head = nn.Linear(config.hidden_size, config.vocab_size, bias=False)
self.apply(lambda module: initialize_weights(module, config.num_layers))
self.tie_weights()
def get_input_embeddings(self) -> nn.Embedding:
return self.token_embedding
def set_input_embeddings(self, value: nn.Embedding) -> None:
self.token_embedding = value
def get_output_embeddings(self) -> nn.Linear:
return self.lm_head
def set_output_embeddings(self, value: nn.Linear) -> None:
self.lm_head = value
def forward(
self,
input_ids: torch.Tensor,
labels: torch.Tensor | None = None,
attention_mask: torch.Tensor | None = None,
use_cache: bool = False,
**_: object,
) -> CausalLMOutput:
del attention_mask, use_cache
if input_ids.ndim != 2:
raise ValueError("input_ids must have shape [batch, sequence]")
if input_ids.size(1) > self.config.max_seq_len:
raise ValueError("input exceeds max_seq_len")
hidden = self.token_embedding(input_ids)
for block in self.blocks:
hidden = block(hidden)
logits = self.lm_head(self.final_norm(hidden))
loss = None
if labels is not None:
loss = F.cross_entropy(
logits[:, :-1].float().reshape(-1, self.config.vocab_size),
labels[:, 1:].reshape(-1),
ignore_index=-100,
)
return CausalLMOutput(loss=loss, logits=logits)