Views
No views yet
1import torch
2import torch.nn as nn
3import torch.nn.functional as F
4from torch import Tensor
5from transformers import AutoConfig, PretrainedConfig, PreTrainedModel
6from transformers import AutoModel, AutoTokenizer, logging
7
8class SimCSEConfig(PretrainedConfig):
9 def __init__(self, version=1.0, **kwargs):
10 self.version = version
11 super().__init__(**kwargs)
12
13class SimCSEModel(PreTrainedModel):
14 config_class = SimCSEConfig
15
16 def __init__(self, config):
17 super().__init__(config)
18 self.backbone = AutoModel.from_pretrained(config.base_model)
19 self.hidden_size: int = self.backbone.config.hidden_size
20 self.dense = nn.Linear(self.hidden_size, self.hidden_size)
21 self.activation = nn.Tanh()
22
23 def forward(
24 self,
25 input_ids: Tensor,
26 attention_mask: Tensor = None,
27 # RoBERTa variants don't have token_type_ids, so this argument is optional
28 token_type_ids: Tensor = None,
29 ) -> Tensor:
30 # shape of input_ids: (batch_size, seq_len)
31 # shape of attention_mask: (batch_size, seq_len)
32 outputs: BaseModelOutputWithPoolingAndCrossAttentions = self.backbone(
33 input_ids=input_ids,
34 attention_mask=attention_mask,
35 token_type_ids=token_type_ids,
36 )
37
38 emb = outputs.last_hidden_state[:, 0]
39
40 if self.training:
41 emb = self.dense(emb)
42 emb = self.activation(emb)
43
44 return emb
45
46def show_embedding_score(tokenizer, model, sentences):
47 inputs = tokenizer(sentences, padding=True, truncation=True, return_tensors="pt")
48 embeddings = model(**inputs)
49 score01 = cal_score(embeddings[0,:], embeddings[1,:])
50 score02 = cal_score(embeddings[0,:], embeddings[2,:])
51 print(score01, score02)
52
53def cal_score(a, b):
54 if len(a.shape) == 1: a = a.unsqueeze(0)
55 if len(b.shape) == 1: b = b.unsqueeze(0)
56 a_norm = a / a.norm(dim=1)[:, None]
57 b_norm = b / b.norm(dim=1)[:, None]
58 return torch.mm(a_norm, b_norm.transpose(0, 1)) * 100
59
60# Load pre-trained model
61model = SimCSEModel.from_pretrained("daekeun-ml/KoSimCSE-supervised-roberta-large")
62tokenizer = AutoTokenizer.from_pretrained("daekeun-ml/KoSimCSE-supervised-roberta-large")
63
64# Inference example
65sentences = ['이번 주 일요일에 분당 이마트 점은 문을 여나요?',
66 '일요일에 분당 이마트는 문 열어요?',
67 '분당 이마트 점은 토요일에 몇 시까지 하나요']
68
69show_embedding_score(tokenizer, model.cpu(), sentences)ml.g4dn.xlarge trains well, but we recommend ml.g4dn.12xlarge or ml.g5.12xlarge for faster training.ml.g4dn.xlargeml.g4dn.xlarge (Minimum)ml.g5.12xlarge (Recommended)1{
2 "batch_size": 64,
3 "num_epochs": 1 (for unsupervised training), 3 (for supervised training)
4 "lr": 3e-05,
5 "num_warmup_steps": 0,
6 "temperature": 0.05,
7 "lr_scheduler_type": "linear",
8 "max_seq_len": 32,
9 "use_fp16": "True",
10}| Model | Avg | Cosine Pearson | Cosine Spearman | Euclidean Pearson | Euclidean Spearman | Manhattan Pearson | Manhattan Spearman | Dot Pearson | Dot Spearman |
|---|---|---|---|---|---|---|---|---|---|
| KoSimCSE-RoBERTa-base (Unsupervised) | 81.17 | 81.27 | 80.96 | 81.70 | 80.97 | 81.63 | 80.89 | 81.12 | 80.81 |
| KoSimCSE-RoBERTa-base (Supervised) | 84.19 | 83.04 | 84.46 | 84.97 | 84.50 | 84.95 | 84.45 | 82.88 | 84.28 |
| KoSimCSE-RoBERTa-large (Unsupervised) | 81.96 | 82.09 | 81.71 | 82.45 | 81.73 | 82.42 | 81.69 | 81.98 | 81.58 |
| KoSimCSE-RoBERTa-large (Supervised) | 85.37 | 84.38 | 85.99 | 85.97 | 85.81 | 86.00 | 85.79 | 83.87 | 85.15 |
| Model | Avg | Cosine Pearson | Cosine Spearman | Euclidean Pearson | Euclidean Spearman | Manhattan Pearson | Manhattan Spearman | Dot Pearson | Dot Spearman |
|---|---|---|---|---|---|---|---|---|---|
| KoSimCSE-RoBERTa-base (Unsupervised) | 81.20 | 81.53 | 81.17 | 80.89 | 81.20 | 80.93 | 81.22 | 81.48 | 81.14 |
| KoSimCSE-RoBERTa-base (Supervised) | 85.33 | 85.16 | 85.46 | 85.37 | 85.45 | 85.31 | 85.37 | 85.13 | 85.41 |
| KoSimCSE-RoBERTa-large (Unsupervised) | 81.71 | 82.10 | 81.78 | 81.12 | 81.78 | 81.15 | 81.80 | 82.15 | 81.80 |
| KoSimCSE-RoBERTa-large (Supervised) | 85.54 | 85.41 | 85.78 | 85.18 | 85.51 | 85.26 | 85.61 | 85.70 | 85.90 |