Files
wehub-resource-sync 2aaeece67c
Codestyle Check / Lint (push) Has been cancelled
Codestyle Check / Check bypass (push) Has been cancelled
Pipelines-Test / Pipelines-Test (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:37:14 +08:00

74 lines
3.1 KiB
Python

# Copyright (c) 2020 PaddlePaddle Authors. All Rights Reserved.
# Copyright 2021 The HuggingFace Inc. team. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import paddle
from paddlenlp.data import Dict, Pad
class DataCollatorMLM:
def __init__(self, tokenizer, batch_pad=None):
self.batch_pad = batch_pad
self.mask_token_id = tokenizer.mask_token_id
self.pad_token_id = tokenizer.pad_token_id
self.token_len = tokenizer.vocab_size
if batch_pad is None:
self.batch_pad = lambda samples, fn=Dict(
{
"input_ids": Pad(axis=0, pad_val=self.pad_token_id, dtype="int64"), # input
# 'token_type_ids': Pad(axis=0, pad_val=0, dtype='int64'), # segment
"special_tokens_mask": Pad(axis=0, pad_val=True, dtype="int64"), # segment
}
): fn(samples)
else:
self.batch_pad = batch_pad
def __call__(self, examples):
examples = self.batch_pad(examples)
examples = [paddle.to_tensor(e) for e in examples]
examples[0], labels = self._mask_tokens(
examples[0], paddle.cast(examples[1], dtype=bool), self.mask_token_id, self.token_len
)
examples.append(labels)
return examples
def _mask_tokens(self, inputs, special_tokens_mask, mask_token_id, token_len, mlm_prob=0.15, ignore_label=-100):
"""
Prepare masked tokens inputs/labels for masked language modeling: 80% MASK, 10% random, 10% original.
"""
labels = inputs.clone()
probability_matrix = paddle.full(labels.shape, mlm_prob)
probability_matrix[special_tokens_mask] = 0
masked_indices = paddle.cast(paddle.bernoulli(probability_matrix), dtype=bool)
labels[~masked_indices] = ignore_label # We only compute loss on masked tokens
# 80% of the time, we replace masked input tokens with tokenizer.mask_token ([MASK])
indices_replaced = paddle.cast(paddle.bernoulli(paddle.full(labels.shape, 0.8)), dtype=bool) & masked_indices
inputs[indices_replaced] = mask_token_id
# 10% of the time, we replace masked input tokens with random word
indices_random = (
paddle.cast(paddle.bernoulli(paddle.full(labels.shape, 0.5)), dtype=bool)
& masked_indices
& ~indices_replaced
)
random_words = paddle.randint(low=0, high=token_len, shape=labels.shape)
inputs[indices_random] = random_words[indices_random]
# The rest of the time (10% of the time) we keep the masked input tokens unchanged
return inputs, labels