Transformers
PyTorch
Russian
bert
Inference Endpoints
mlenjoyneer commited on
Commit
84c1993
·
1 Parent(s): 7d5ca8a

Upload 3 files

Browse files
Files changed (3) hide show
  1. README.md +116 -0
  2. config.json +40 -0
  3. pytorch_model.bin +3 -0
README.md CHANGED
@@ -1,3 +1,119 @@
1
  ---
 
2
  license: apache-2.0
 
 
 
3
  ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  ---
2
+ language: ru
3
  license: apache-2.0
4
+ datasets:
5
+ - mlenjoyneer/RuTextSegNews
6
+ - mlenjoyneer/RuTextSegWiki
7
  ---
8
+
9
+ # RuTextSegModel
10
+
11
+ Model for Russian text segmentation, trained on wiki and news corpora
12
+
13
+ ## Model description
14
+
15
+ This model is a top-level part of HierBERT model and solves the problem of text segmentation as a token classification at the sentence level. The ai-forever/sbert_large_nlu_ru with max pooling is used as a low-level model (sentence embedding generator). It's recommended to use this model only with specified low-level model with defined pooling for embeddings.
16
+
17
+ ## Intended uses & limitations
18
+
19
+ ### How to use
20
+
21
+ Here is how to use this model in PyTorch:
22
+
23
+ ```python
24
+ import torch
25
+ import torch.nn as nn
26
+ from transformers import BertForTokenClassification, AutoModel, AutoTokenizer
27
+ from razdel import sentenize
28
+
29
+ class BertForTextSegmentationEmbeddings(nn.Module):
30
+ def __init__(self, config, embeddings_dim=768):
31
+ super(BertForTextSegmentationEmbeddings, self).__init__()
32
+
33
+ self.config = config
34
+ self.position_embeddings = torch.nn.Embedding(config.max_position_embeddings, config.hidden_size)
35
+
36
+ self.LayerNorm = torch.nn.LayerNorm(config.hidden_size, eps=config.layer_norm_eps)
37
+ self.dropout = torch.nn.Dropout(config.hidden_dropout_prob)
38
+
39
+ def forward(self, inputs_embeds, position_ids=None, input_ids=None, token_type_ids=None, past_key_values_length=None):
40
+ input_shape = inputs_embeds.size()[:-1]
41
+ seq_length = input_shape[1]
42
+ device = inputs_embeds.device
43
+
44
+ assert seq_length <= self.config.max_position_embeddings, \
45
+ f"Too long sequence is passed {seq_length}. Maximum allowed sequence length is {self.config.max_position_embeddings}"
46
+
47
+ if position_ids is None:
48
+ position_ids = torch.arange(seq_length, dtype=torch.long, device=device)
49
+ position_ids = position_ids.unsqueeze(0).expand(input_shape)
50
+
51
+ position_embeddings = self.position_embeddings(position_ids)
52
+
53
+ embeddings = inputs_embeds + position_embeddings
54
+ embeddings = self.LayerNorm(embeddings)
55
+ embeddings = self.dropout(embeddings)
56
+ return embeddings
57
+
58
+ class BertForTextSegmentation(BertForTokenClassification):
59
+ def __init__(self, config):
60
+ super(BertForTextSegmentation, self).__init__(config)
61
+
62
+ self.bert.base_model.embeddings = BertForTextSegmentationEmbeddings(config)
63
+
64
+ self.init_weights()
65
+
66
+ def max_pooling(model_output, attention_mask):
67
+ token_embeddings = model_output[0] #First element of model_output contains all token embeddings
68
+ input_mask_expanded = attention_mask.unsqueeze(-1).expand(token_embeddings.size()).float()
69
+ token_embeddings[input_mask_expanded == 0] = -1e9 # Set padding tokens to large negative value
70
+ return torch.max(token_embeddings, 1)[0]
71
+
72
+ def create_embeddings(sentences, tokenizer, model):
73
+ # Tokenize sentences
74
+ encoded_input = tokenizer(sentences, padding=True, truncation=True, return_tensors='pt')
75
+ # Compute token embeddings
76
+ with torch.no_grad():
77
+ model_output = model(**encoded_input.to(device))
78
+ # Perform pooling. In this case, max pooling.
79
+ sentence_embeddings = max_pooling(model_output, encoded_input['attention_mask'])
80
+
81
+ return sentence_embeddings
82
+
83
+ device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")
84
+
85
+ emb_tokenizer = AutoTokenizer.from_pretrained("ai-forever/sbert_large_nlu_ru")
86
+ emb_model = AutoModel.from_pretrained("ai-forever/sbert_large_nlu_ru")
87
+ model = BertForTextSegmentation.from_pretrained("mlenjoyneer/RuTextSegModel")
88
+
89
+ emb_model.to(device)
90
+ model.to(device)
91
+
92
+ text = """В Норильске за годы работы телефона доверия консультанты приняли в общей сложности порядка 75 тысяч обращений, сообщает «Заполярная Правда». Служба психологической помощи появилась в 2000 году. Руководитель службы профилактики наркомании Елена Слатвицкая рассказала журналистам, что в Заполярье настал период, когда ухудшается психо– эмоциональное состояние населения. Это происходит на входе в полярную ночь и на выходе из нее. Осень является кризисным моментом. Сейчас на телефоне доверия работают 15 специалистов. Каждый — под своим псевдонимом. Тему беседы определяет звонящий. Это могут быть наркомания и алкоголизм, ВИЧ–инфекция и прочие заболевания и зависимости, кризисы семейных отношений и многое другое. Сотрудники службы отмет��ли, что больше стало звонков по поводу суицидальных намерений. Наибольшее количество обращений по суицидам пришлось на октябрь — ноябрь. Много звонков как от мужчин, так и от женщин с вопросами об одиночестве. Лидерами по количеству обращений пока остаются женщины. В сентябре в Норильске обнаружили тело девятиклассницы. По версии следствия, девочка сбросилась с крыши. В январе подросток нанес себе порезы стеклом от разбитой бутылки, пытаясь покончить с собой. Мальчик поссорился с матерью и в ходе ссоры нанес себе несколько порезов. Проводится расследование."""
93
+
94
+ input_embeds = create_embeddings([s.text for s in sentenize(text)], emb_tokenizer, emb_model).unsqueeze(0)
95
+ outputs = model(inputs_embeds=input_embeds)
96
+
97
+ logits = outputs.logits.cpu()
98
+ preds = logits.argmax(axis=2).tolist()[0] # [0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0]
99
+
100
+ # true_labels = [0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0]
101
+ ```
102
+
103
+ ## Training data
104
+
105
+ Model trained on mlenjoyneer/RuTextSegNews and mlenjoyneer/RuTextSegWiki datasets.
106
+
107
+ ## Evaluation results
108
+
109
+ | Train Dataset | Test Dataset | F1_total | F1_1 | Pk | Pk_5 | WinDiff | WinDiff_5 |
110
+ |:-------------:|:------------:|:--------:|:-----:|:----:|:----:|:-------:|:---------:|
111
+ | News+Wiki | News | 0.88 | 0.80 | 0.16 | 0.11 | 0.20 | 0.35 |
112
+ | News+Wiki | Wiki | 0.89 | 0.80 | 0.18 | 0.16 | 0.09 | 0.19 |
113
+
114
+
115
+ ### Citation info
116
+
117
+ ```bibtex
118
+ In progress
119
+ ```
config.json ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "_name_or_path": "./sbert_large_nlu_ru",
3
+ "architectures": [
4
+ "BertForTextSegmentation"
5
+ ],
6
+ "attention_probs_dropout_prob": 0.1,
7
+ "classifier_dropout": null,
8
+ "directionality": "bidi",
9
+ "gradient_checkpointing": false,
10
+ "hidden_act": "gelu",
11
+ "hidden_dropout_prob": 0.1,
12
+ "hidden_size": 1024,
13
+ "id2label": {
14
+ "0": 0,
15
+ "1": 1
16
+ },
17
+ "initializer_range": 0.02,
18
+ "intermediate_size": 4096,
19
+ "label2id": {
20
+ "0": 0,
21
+ "1": 1
22
+ },
23
+ "layer_norm_eps": 1e-12,
24
+ "max_position_embeddings": 128,
25
+ "model_type": "bert",
26
+ "num_attention_heads": 16,
27
+ "num_hidden_layers": 4,
28
+ "pad_token_id": 0,
29
+ "pooler_fc_size": 768,
30
+ "pooler_num_attention_heads": 12,
31
+ "pooler_num_fc_layers": 3,
32
+ "pooler_size_per_head": 128,
33
+ "pooler_type": "first_token_transform",
34
+ "position_embedding_type": "absolute",
35
+ "torch_dtype": "float32",
36
+ "transformers_version": "4.31.0",
37
+ "type_vocab_size": 2,
38
+ "use_cache": true,
39
+ "vocab_size": 120138
40
+ }
pytorch_model.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:cb543e3e6b3dc7ff92be64f3c88be1f85e0a29144cfdffbe4d91162087958e4b
3
+ size 202103424