Download modeling_sol_pro_hf.py from solintellegence/sol-pro: direct link, hf CLI and curl.
- Browser
- Download file 3.31 kB
-
https://huggingface.co/solintellegence/sol-pro/resolve/main/modeling_sol_pro_hf.py
- Command line
-
hf download hf://solintellegence/sol-pro/modeling_sol_pro_hf.py
-
curl -L -o modeling_sol_pro_hf.py https://huggingface.co/solintellegence/sol-pro/resolve/main/modeling_sol_pro_hf.py
3.31 kB
| import torch | |
| from torch.nn import functional as F | |
| from transformers import PreTrainedModel, GenerationMixin | |
| from transformers.modeling_outputs import CausalLMOutput | |
| from .configuration_sol_pro import SolProHFConfig | |
| from .modeling_sol_pro import SolProConfig, SolProForCausalLM | |
| class SolProHFForCausalLM(PreTrainedModel, GenerationMixin): | |
| config_class = SolProHFConfig | |
| base_model_prefix = "" | |
| main_input_name = "input_ids" | |
| _no_split_modules = ["Block"] | |
| def __init__(self, config): | |
| super().__init__(config) | |
| fields = SolProConfig.__dataclass_fields__ | |
| core = SolProForCausalLM(SolProConfig(**{k: getattr(config, k) for k in fields})) | |
| # Keep original checkpoint names, including the single tied embedding. | |
| for name, module in core.named_children(): | |
| self.add_module(name, module) | |
| for name, parameter in core.named_parameters(recurse=False): | |
| self.register_parameter(name, parameter) | |
| for name, buffer in core.named_buffers(recurse=False): | |
| self.register_buffer(name, buffer) | |
| self.post_init() | |
| def get_input_embeddings(self): | |
| return self.embedding | |
| def set_input_embeddings(self, value): | |
| self.embedding = value | |
| def get_output_embeddings(self): | |
| return self.embedding | |
| def set_output_embeddings(self, value): | |
| self.embedding = value | |
| def prepare_inputs_for_generation(self, input_ids, attention_mask=None, **kwargs): | |
| return {"input_ids": input_ids, "attention_mask": attention_mask, "use_cache": False} | |
| def forward(self, input_ids=None, attention_mask=None, labels=None, | |
| return_dict=None, use_cache=False, past_key_values=None, **kwargs): | |
| if input_ids is None: | |
| raise ValueError("input_ids are required") | |
| if past_key_values is not None: | |
| raise ValueError("KV caching is not implemented") | |
| if attention_mask is None or bool(attention_mask.bool().all()): | |
| logits = SolProForCausalLM.forward(self, input_ids) | |
| else: | |
| # Strip padding so n-gram memory and recurrent conditioning see the | |
| # same sequence as an unpadded standalone inference call. | |
| rows = [] | |
| for ids, mask in zip(input_ids, attention_mask): | |
| keep = mask.bool() | |
| positions = keep.nonzero(as_tuple=True)[0] | |
| if positions.numel() == 0: | |
| raise ValueError("An attention mask cannot be empty") | |
| values = SolProForCausalLM.forward(self, ids[keep][None])[0] | |
| row = values.new_zeros((ids.numel(), self.config.vocab_size)) | |
| rows.append(row.index_copy(0, positions, values)) | |
| logits = torch.stack(rows) | |
| loss = None | |
| if labels is not None: | |
| targets = labels[:, 1:].clone() | |
| if attention_mask is not None: | |
| targets.masked_fill_(~attention_mask[:, 1:].bool(), -100) | |
| loss = F.cross_entropy(logits[:, :-1].float().reshape(-1, logits.shape[-1]), | |
| targets.reshape(-1), ignore_index=-100) | |
| if return_dict is False: | |
| return ((loss,) if loss is not None else ()) + (logits,) | |
| return CausalLMOutput(loss=loss, logits=logits) | |