IvoHoese's picture
Upload utils.py
810cd42 verified
Raw
History Blame
4.04 kB
from transformers import OlmoModel, OlmoPreTrainedModel, GenerationMixin, AutoConfig, AutoModelForSequenceClassification
from transformers.modeling_outputs import SequenceClassifierOutputWithPast
import torch
from peft import PeftModel, PeftConfig
from transformers import AutoConfig
# The custom model for using Olmo with a sequence classification task
device = "cuda" if torch.cuda.is_available() else "cpu"
class OlmoForSequenceClassification(OlmoPreTrainedModel, GenerationMixin):
def __init__(self, config):
# Check OlmoForCausalLM.__init__
super().__init__(config)
self.model = OlmoModel(config)
self.num_labels = config.num_labels
self.classifier = torch.nn.Linear(config.hidden_size, config.num_labels)
# Initialize weights and apply final processing
self.post_init()
def forward(
self,
input_ids: torch.LongTensor = None,
attention_mask: torch.Tensor | None = None,
labels: torch.LongTensor | None = None,
**kwargs,
) -> SequenceClassifierOutputWithPast:
outputs = self.model(
input_ids=input_ids,
attention_mask=attention_mask,
**kwargs,
)
logits = self.classifier(outputs.last_hidden_state) # [B, N, H] => [B, N, C]
pooled_logits = logits[:, -1] # NOTE: tokenizer.padding_side must be 'left'
loss = None
if labels is not None:
loss = self.loss_function(
logits=logits,
labels=labels,
pooled_logits=pooled_logits,
config=self.config,
)
return SequenceClassifierOutputWithPast(
loss=loss,
logits=pooled_logits,
past_key_values=outputs.past_key_values,
hidden_states=outputs.hidden_states,
attentions=outputs.attentions,
)
# The function for loading a fulltuning model
def get_fulltuning_model(model_path, model_type="olmo"):
if model_type == "olmo":
model = OlmoForSequenceClassification.from_pretrained(
model_path,
trust_remote_code=True,
torch_dtype=torch.float32,
).to("cuda" if torch.cuda.is_available() else "cpu")
model.eval()
elif model_type == "pythia":
cfg = AutoConfig.from_pretrained(model_path, num_labels=3)
model = AutoModelForSequenceClassification.from_pretrained(
model_path,
config=cfg,
torch_dtype=torch.float32,
).to(device)
else:
raise ValueError(f"Unsupported model_type: {model_type}")
return model
# The function for loading a softprompt model
# NOTE: The "missing or unexpected params" warning is no reason for concern. It stems from the
# fact that the model is first loaded without a classifier head, which is added afterwards.
def get_peft_model(model_path, model_type="olmo"):
peft_config = PeftConfig.from_pretrained(model_path)
if model_type == "olmo":
config = AutoConfig.from_pretrained(
peft_config.base_model_name_or_path,
trust_remote_code=True,
num_labels=2
)
base = OlmoForSequenceClassification.from_pretrained(
peft_config.base_model_name_or_path,
trust_remote_code=True,
torch_dtype=torch.float32,
config=config,
).to(device)
elif model_type == "pythia":
config = AutoConfig.from_pretrained(
peft_config.base_model_name_or_path,
num_labels=2
)
base = AutoModelForSequenceClassification.from_pretrained(
peft_config.base_model_name_or_path,
config=config,
torch_dtype=torch.float32,
).to(device)
else:
raise ValueError(f"Unsupported model_type: {model_type}")
model = PeftModel.from_pretrained(
base,
model_path,
).to("cuda" if torch.cuda.is_available() else "cpu")
model.eval()
return model