jvaquet commited on
Commit
f0bb526
·
verified ·
1 Parent(s): 2266147

Upload MultilabelNerPipeline

Browse files
README.md ADDED
@@ -0,0 +1,199 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ library_name: transformers
3
+ tags: []
4
+ ---
5
+
6
+ # Model Card for Model ID
7
+
8
+ <!-- Provide a quick summary of what the model is/does. -->
9
+
10
+
11
+
12
+ ## Model Details
13
+
14
+ ### Model Description
15
+
16
+ <!-- Provide a longer summary of what this model is. -->
17
+
18
+ This is the model card of a 🤗 transformers model that has been pushed on the Hub. This model card has been automatically generated.
19
+
20
+ - **Developed by:** [More Information Needed]
21
+ - **Funded by [optional]:** [More Information Needed]
22
+ - **Shared by [optional]:** [More Information Needed]
23
+ - **Model type:** [More Information Needed]
24
+ - **Language(s) (NLP):** [More Information Needed]
25
+ - **License:** [More Information Needed]
26
+ - **Finetuned from model [optional]:** [More Information Needed]
27
+
28
+ ### Model Sources [optional]
29
+
30
+ <!-- Provide the basic links for the model. -->
31
+
32
+ - **Repository:** [More Information Needed]
33
+ - **Paper [optional]:** [More Information Needed]
34
+ - **Demo [optional]:** [More Information Needed]
35
+
36
+ ## Uses
37
+
38
+ <!-- Address questions around how the model is intended to be used, including the foreseeable users of the model and those affected by the model. -->
39
+
40
+ ### Direct Use
41
+
42
+ <!-- This section is for the model use without fine-tuning or plugging into a larger ecosystem/app. -->
43
+
44
+ [More Information Needed]
45
+
46
+ ### Downstream Use [optional]
47
+
48
+ <!-- This section is for the model use when fine-tuned for a task, or when plugged into a larger ecosystem/app -->
49
+
50
+ [More Information Needed]
51
+
52
+ ### Out-of-Scope Use
53
+
54
+ <!-- This section addresses misuse, malicious use, and uses that the model will not work well for. -->
55
+
56
+ [More Information Needed]
57
+
58
+ ## Bias, Risks, and Limitations
59
+
60
+ <!-- This section is meant to convey both technical and sociotechnical limitations. -->
61
+
62
+ [More Information Needed]
63
+
64
+ ### Recommendations
65
+
66
+ <!-- This section is meant to convey recommendations with respect to the bias, risk, and technical limitations. -->
67
+
68
+ Users (both direct and downstream) should be made aware of the risks, biases and limitations of the model. More information needed for further recommendations.
69
+
70
+ ## How to Get Started with the Model
71
+
72
+ Use the code below to get started with the model.
73
+
74
+ [More Information Needed]
75
+
76
+ ## Training Details
77
+
78
+ ### Training Data
79
+
80
+ <!-- This should link to a Dataset Card, perhaps with a short stub of information on what the training data is all about as well as documentation related to data pre-processing or additional filtering. -->
81
+
82
+ [More Information Needed]
83
+
84
+ ### Training Procedure
85
+
86
+ <!-- This relates heavily to the Technical Specifications. Content here should link to that section when it is relevant to the training procedure. -->
87
+
88
+ #### Preprocessing [optional]
89
+
90
+ [More Information Needed]
91
+
92
+
93
+ #### Training Hyperparameters
94
+
95
+ - **Training regime:** [More Information Needed] <!--fp32, fp16 mixed precision, bf16 mixed precision, bf16 non-mixed precision, fp16 non-mixed precision, fp8 mixed precision -->
96
+
97
+ #### Speeds, Sizes, Times [optional]
98
+
99
+ <!-- This section provides information about throughput, start/end time, checkpoint size if relevant, etc. -->
100
+
101
+ [More Information Needed]
102
+
103
+ ## Evaluation
104
+
105
+ <!-- This section describes the evaluation protocols and provides the results. -->
106
+
107
+ ### Testing Data, Factors & Metrics
108
+
109
+ #### Testing Data
110
+
111
+ <!-- This should link to a Dataset Card if possible. -->
112
+
113
+ [More Information Needed]
114
+
115
+ #### Factors
116
+
117
+ <!-- These are the things the evaluation is disaggregating by, e.g., subpopulations or domains. -->
118
+
119
+ [More Information Needed]
120
+
121
+ #### Metrics
122
+
123
+ <!-- These are the evaluation metrics being used, ideally with a description of why. -->
124
+
125
+ [More Information Needed]
126
+
127
+ ### Results
128
+
129
+ [More Information Needed]
130
+
131
+ #### Summary
132
+
133
+
134
+
135
+ ## Model Examination [optional]
136
+
137
+ <!-- Relevant interpretability work for the model goes here -->
138
+
139
+ [More Information Needed]
140
+
141
+ ## Environmental Impact
142
+
143
+ <!-- Total emissions (in grams of CO2eq) and additional considerations, such as electricity usage, go here. Edit the suggested text below accordingly -->
144
+
145
+ Carbon emissions can be estimated using the [Machine Learning Impact calculator](https://mlco2.github.io/impact#compute) presented in [Lacoste et al. (2019)](https://arxiv.org/abs/1910.09700).
146
+
147
+ - **Hardware Type:** [More Information Needed]
148
+ - **Hours used:** [More Information Needed]
149
+ - **Cloud Provider:** [More Information Needed]
150
+ - **Compute Region:** [More Information Needed]
151
+ - **Carbon Emitted:** [More Information Needed]
152
+
153
+ ## Technical Specifications [optional]
154
+
155
+ ### Model Architecture and Objective
156
+
157
+ [More Information Needed]
158
+
159
+ ### Compute Infrastructure
160
+
161
+ [More Information Needed]
162
+
163
+ #### Hardware
164
+
165
+ [More Information Needed]
166
+
167
+ #### Software
168
+
169
+ [More Information Needed]
170
+
171
+ ## Citation [optional]
172
+
173
+ <!-- If there is a paper or blog post introducing the model, the APA and Bibtex information for that should go in this section. -->
174
+
175
+ **BibTeX:**
176
+
177
+ [More Information Needed]
178
+
179
+ **APA:**
180
+
181
+ [More Information Needed]
182
+
183
+ ## Glossary [optional]
184
+
185
+ <!-- If relevant, include terms and calculations in this section that can help readers understand the model or model card. -->
186
+
187
+ [More Information Needed]
188
+
189
+ ## More Information [optional]
190
+
191
+ [More Information Needed]
192
+
193
+ ## Model Card Authors [optional]
194
+
195
+ [More Information Needed]
196
+
197
+ ## Model Card Contact
198
+
199
+ [More Information Needed]
config.json ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "add_cross_attention": false,
3
+ "architectures": [
4
+ "BertForMultiLabelTokenClassification"
5
+ ],
6
+ "attention_probs_dropout_prob": 0.1,
7
+ "auto_map": {
8
+ "AutoConfig": "configuration_multilabelbert.MultiLabelBertConfig",
9
+ "AutoModelForTokenClassification": "modeling_multilabelbert.BertForMultiLabelTokenClassification"
10
+ },
11
+ "bos_token_id": null,
12
+ "classifier_dropout": null,
13
+ "custom_pipelines": {
14
+ "multilabel-ner": {
15
+ "default": {
16
+ "model": {
17
+ "pt": [
18
+ "jvaquet/multilabel-classification-bert",
19
+ "main"
20
+ ]
21
+ }
22
+ },
23
+ "impl": "multilabel_ner.MultilabelNerPipeline",
24
+ "pt": [
25
+ "AutoModelForTokenClassification"
26
+ ],
27
+ "type": "text"
28
+ }
29
+ },
30
+ "directionality": "bidi",
31
+ "dtype": "float32",
32
+ "eos_token_id": null,
33
+ "gradient_checkpointing": false,
34
+ "hidden_act": "gelu",
35
+ "hidden_dropout_prob": 0.1,
36
+ "hidden_size": 1024,
37
+ "id2label": {
38
+ "0": "B-MISC",
39
+ "1": "I-MISC",
40
+ "2": "E-MISC",
41
+ "3": "S-MISC",
42
+ "4": "B-ORG",
43
+ "5": "I-ORG",
44
+ "6": "E-ORG",
45
+ "7": "S-ORG",
46
+ "8": "B-PER",
47
+ "9": "I-PER",
48
+ "10": "E-PER",
49
+ "11": "S-PER",
50
+ "12": "B-LOC",
51
+ "13": "I-LOC",
52
+ "14": "E-LOC",
53
+ "15": "S-LOC"
54
+ },
55
+ "initializer_range": 0.02,
56
+ "intermediate_size": 4096,
57
+ "is_decoder": false,
58
+ "label2id": {
59
+ "B-LOC": 12,
60
+ "B-MISC": 0,
61
+ "B-ORG": 4,
62
+ "B-PER": 8,
63
+ "E-LOC": 14,
64
+ "E-MISC": 2,
65
+ "E-ORG": 6,
66
+ "E-PER": 10,
67
+ "I-LOC": 13,
68
+ "I-MISC": 1,
69
+ "I-ORG": 5,
70
+ "I-PER": 9,
71
+ "S-LOC": 15,
72
+ "S-MISC": 3,
73
+ "S-ORG": 7,
74
+ "S-PER": 11
75
+ },
76
+ "layer_norm_eps": 1e-12,
77
+ "max_position_embeddings": 512,
78
+ "model_type": "MultiLabelBert",
79
+ "num_attention_heads": 16,
80
+ "num_hidden_layers": 24,
81
+ "pad_token_id": 0,
82
+ "pooler_fc_size": 768,
83
+ "pooler_num_attention_heads": 12,
84
+ "pooler_num_fc_layers": 3,
85
+ "pooler_size_per_head": 128,
86
+ "pooler_type": "first_token_transform",
87
+ "position_embedding_type": "absolute",
88
+ "tie_word_embeddings": true,
89
+ "transformers_version": "5.5.3",
90
+ "type_vocab_size": 2,
91
+ "use_cache": true,
92
+ "vocab_size": 28996
93
+ }
configuration_multilabelbert.py ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ from transformers import BertConfig, AutoConfig
2
+
3
+ class MultiLabelBertConfig(BertConfig):
4
+ model_type = 'MultiLabelBert'
5
+
6
+ AutoConfig.register('MultiLabelBert', MultiLabelBertConfig)
7
+ MultiLabelBertConfig.register_for_auto_class()
model.safetensors ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:c8d43ff02648f12146cc4cec24cd36dfbaaa077d6417b571efa928fecfee36f8
3
+ size 1330231072
modeling_multilabelbert.py ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from transformers import BertPreTrainedModel, BertModel, AutoConfig, AutoModelForTokenClassification
2
+ import torch
3
+ import torch.nn as nn
4
+
5
+ from transformers.modeling_outputs import TokenClassifierOutput
6
+ from transformers.utils import TransformersKwargs, can_return_tuple
7
+ from transformers.processing_utils import Unpack
8
+
9
+ from .configuration_multilabelbert import MultiLabelBertConfig
10
+
11
+ from typing import Optional
12
+
13
+
14
+ class BertForMultiLabelTokenClassification(BertPreTrainedModel):
15
+ config_class = MultiLabelBertConfig
16
+
17
+ def __init__(self, config):
18
+ super().__init__(config)
19
+ self.num_labels = config.num_labels
20
+
21
+ self.bert = BertModel(config, add_pooling_layer=False)
22
+ classifier_dropout = (
23
+ config.classifier_dropout if config.classifier_dropout is not None else config.hidden_dropout_prob
24
+ )
25
+ self.dropout = nn.Dropout(classifier_dropout)
26
+ self.classifier = nn.Linear(config.hidden_size, config.num_labels)
27
+
28
+ # Initialize weights and apply final processing
29
+ self.post_init()
30
+
31
+ @can_return_tuple
32
+ def forward(
33
+ self,
34
+ input_ids: torch.Tensor | None = None,
35
+ attention_mask: torch.Tensor | None = None,
36
+ token_type_ids: torch.Tensor | None = None,
37
+ position_ids: torch.Tensor | None = None,
38
+ inputs_embeds: torch.Tensor | None = None,
39
+ labels: torch.Tensor | None = None,
40
+ special_tokens_mask: Optional[torch.Tensor] = None,
41
+ **kwargs: Unpack[TransformersKwargs],
42
+ ) -> tuple[torch.Tensor] | TokenClassifierOutput:
43
+ outputs = self.bert(
44
+ input_ids,
45
+ attention_mask=attention_mask,
46
+ token_type_ids=token_type_ids,
47
+ position_ids=position_ids,
48
+ inputs_embeds=inputs_embeds,
49
+ return_dict=True,
50
+ **kwargs,
51
+ )
52
+
53
+ sequence_output = outputs[0]
54
+
55
+ sequence_output = self.dropout(sequence_output)
56
+ logits = self.classifier(sequence_output)
57
+
58
+ loss = None
59
+ if labels is not None:
60
+ loss_fct = nn.BCEWithLogitsLoss(reduction = 'none')
61
+ loss = loss_fct(logits, labels)
62
+
63
+ if special_tokens_mask is not None:
64
+ loss = loss[special_tokens_mask != 1].mean()
65
+ else:
66
+ loss = loss.mean()
67
+
68
+ return TokenClassifierOutput(
69
+ loss=loss,
70
+ logits=logits,
71
+ hidden_states=outputs.hidden_states,
72
+ attentions=outputs.attentions,
73
+ )
74
+
75
+ AutoModelForTokenClassification.register(MultiLabelBertConfig, BertForMultiLabelTokenClassification)
76
+ BertForMultiLabelTokenClassification.register_for_auto_class('AutoModelForTokenClassification')
multilabel_ner.py ADDED
@@ -0,0 +1,182 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from transformers import Pipeline
2
+ import torch
3
+ import torch.nn as nn
4
+
5
+ MODEL_FOR_MULTILABEL_TOKEN_CLASSIFICATION = [
6
+ 'BertForMultiLabelTokenClassification'
7
+ ]
8
+
9
+ class MultilabelNerPipeline(Pipeline):
10
+
11
+ def __init__(self, *args, **kwargs):
12
+ super().__init__(*args, **kwargs)
13
+
14
+ self.check_model_type(MODEL_FOR_MULTILABEL_TOKEN_CLASSIFICATION)
15
+
16
+ self.entity_types = {label[2:] for label in self.model.config.label2id}
17
+
18
+
19
+ def _sanitize_parameters(self, **kwargs):
20
+ preprocess_kwargs = {}
21
+ if 'stride' in kwargs:
22
+ preprocess_kwargs['stride'] = kwargs['stride']
23
+
24
+ postprocess_kwargs = {}
25
+ if 'threshold' in kwargs:
26
+ postprocess_kwargs['threshold'] = kwargs['threshold']
27
+ if 'use_hierarchy_heuristic' in kwargs:
28
+ postprocess_kwargs['use_hierarchy_heuristic'] = kwargs['use_hierarchy_heuristic']
29
+
30
+ return preprocess_kwargs, {}, postprocess_kwargs
31
+
32
+ def preprocess(self, inputs, stride=128):
33
+ tokenized_inputs = self.tokenizer(inputs,
34
+ truncation=True,
35
+ padding=True,
36
+ stride=stride,
37
+ return_tensors='pt',
38
+ return_overflowing_tokens=True,
39
+ return_special_tokens_mask=True
40
+ )
41
+
42
+ n_samples = tokenized_inputs.input_ids.size()[0]
43
+ char_offsets = [tokenized_inputs[idx].offsets for idx in range(n_samples)]
44
+
45
+ return {
46
+ 'input_ids': tokenized_inputs.input_ids,
47
+ 'attention_mask': tokenized_inputs.attention_mask,
48
+ 'char_offsets': char_offsets,
49
+ 'special_tokens_mask': tokenized_inputs.special_tokens_mask,
50
+ 'text': inputs
51
+ }
52
+
53
+ def _forward(self, model_inputs):
54
+ return {
55
+ 'logits': self.model(**model_inputs).logits,
56
+ 'text': model_inputs['text'],
57
+ 'char_offsets': model_inputs['char_offsets'],
58
+ 'special_tokens_mask': model_inputs['special_tokens_mask']
59
+ }
60
+
61
+ def postprocess(self, model_outputs, threshold=0.5, use_hierarchy_heuristic=False):
62
+ predictions = nn.functional.sigmoid(model_outputs['logits'])
63
+ predictions[model_outputs['special_tokens_mask'] == 1] = 0
64
+
65
+ spans_single = self.extract_single_token_spans(predictions, threshold)
66
+ spans_multi = self.extract_multi_token_spans(predictions, threshold)
67
+
68
+ spans = self.token_spans_to_char_spans(spans_single + spans_multi, model_outputs['char_offsets'], model_outputs['text'])
69
+
70
+ spans = self.deduplicate_spans(spans)
71
+
72
+ if use_hierarchy_heuristic:
73
+ spans = self.apply_hierarchy_heristic(spans)
74
+
75
+ return spans
76
+
77
+
78
+ def extract_single_token_spans(self, predictions, threshold):
79
+ return [{
80
+ 'label': entity_type,
81
+ 'batch': idx_batch,
82
+ 'span_token': (int(idx_token), int(idx_token+1))
83
+ }
84
+ for entity_type in self.entity_types
85
+ for idx_batch, idx_token in zip(*torch.where(predictions[:,:, self.model.config.label2id[f'S-{entity_type}']] >= threshold))
86
+ ]
87
+
88
+ def extract_multi_token_spans(self, predictions, threshold):
89
+ return [{
90
+ 'label': entity_type,
91
+ 'batch': idx_batch_begin,
92
+ 'span_token': (int(idx_token_begin), int(idx_token_end+1))
93
+ }
94
+ for entity_type in self.entity_types
95
+ for idx_batch_begin, idx_token_begin in zip(*torch.where(predictions[:,:, self.model.config.label2id[f'B-{entity_type}']] >= threshold))
96
+ for idx_batch_end, idx_token_end in zip(*torch.where(predictions[:,:, self.model.config.label2id[f'E-{entity_type}']] >= threshold))
97
+ if idx_batch_begin == idx_batch_end
98
+ if idx_token_begin < idx_token_end
99
+ if torch.all(predictions[idx_batch_begin, idx_token_begin+1:idx_token_end, self.model.config.label2id[f'I-{entity_type}']] >= threshold)
100
+ ]
101
+
102
+ def token_spans_to_char_spans(self, spans, char_offsets, text):
103
+ return [{
104
+ 'label': span['label'],
105
+ 'span': (char_start, char_end),
106
+ 'text': text[char_start:char_end]
107
+ }
108
+ for span in spans
109
+ if (batch := span['batch']) is not None
110
+ if (span_token := span['span_token']) is not None
111
+ if (char_start := char_offsets[batch][span_token[0]][0]) is not None
112
+ if (char_end := char_offsets[batch][span_token[1]-1][1]) is not None]
113
+
114
+ def deduplicate_spans(self, spans):
115
+ return [dict(tup)
116
+ for tup in {tuple(span.items()) for span in spans}
117
+ ]
118
+
119
+ def apply_hierarchy_heristic(self, spans):
120
+
121
+ def _group_spans(spans):
122
+ groups = []
123
+ for span in sorted(spans, key=lambda span: span['span'][0] - span['span'][1]):
124
+ found_group = False
125
+ for cur_group in groups:
126
+ if (cur_group['label'] == span['label']
127
+ and cur_group['start'] <= span['span'][0]
128
+ and cur_group['end'] >= span['span'][1]):
129
+ cur_group['spans'].append(span)
130
+ found_group = True
131
+ break
132
+
133
+ # If no group found, make new one
134
+ if not found_group:
135
+ groups.append({
136
+ 'start': span['span'][0],
137
+ 'end': span['span'][1],
138
+ 'spans': [span],
139
+ 'label': span['label']
140
+ })
141
+ return groups
142
+
143
+ return_spans = []
144
+ for group in _group_spans(spans):
145
+ sorted_spans = sorted(group['spans'], key=lambda span: span['span'][1] - span['span'][0])
146
+
147
+ # Collect all start and end positions
148
+ span_starts = {span['span'][0] for span in sorted_spans}
149
+ span_ends = {span['span'][1] for span in sorted_spans}
150
+
151
+ # Except for start and end of group
152
+ span_starts.discard(sorted_spans[-1]['span'][0])
153
+ span_ends.discard(sorted_spans[-1]['span'][1])
154
+
155
+ # Preserve encapsulating span
156
+ cur_spans = [sorted_spans[-1]]
157
+
158
+ # Iteratively add shortest span, if it covers an unused start or end point
159
+ for cur_span in sorted_spans[:-1]:
160
+ if len(span_starts) + len(span_ends) == 0:
161
+ break
162
+
163
+ if cur_span['span'][0] in span_starts \
164
+ or cur_span['span'][1] in span_ends:
165
+ cur_spans.append(cur_span)
166
+ span_starts.discard(cur_span['span'][0])
167
+ span_ends.discard(cur_span['span'][1])
168
+
169
+ return_spans += cur_spans
170
+
171
+ return return_spans
172
+
173
+ from transformers.pipelines import PIPELINE_REGISTRY
174
+ from transformers import AutoModelForTokenClassification
175
+
176
+ PIPELINE_REGISTRY.register_pipeline(
177
+ 'multilabel-ner',
178
+ pipeline_class=MultilabelNerPipeline,
179
+ pt_model=AutoModelForTokenClassification,
180
+ default={'pt': ('jvaquet/multilabel-classification-bert', 'main')},
181
+ type='text',
182
+ )
tokenizer.json ADDED
The diff for this file is too large to render. See raw diff
 
tokenizer_config.json ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "backend": "tokenizers",
3
+ "cls_token": "[CLS]",
4
+ "do_lower_case": false,
5
+ "is_local": false,
6
+ "mask_token": "[MASK]",
7
+ "model_max_length": 512,
8
+ "pad_token": "[PAD]",
9
+ "sep_token": "[SEP]",
10
+ "strip_accents": null,
11
+ "tokenize_chinese_chars": true,
12
+ "tokenizer_class": "BertTokenizer",
13
+ "unk_token": "[UNK]"
14
+ }