Files
modelscope/maas_lib/preprocessors/nlp.py
hemu.zp 8a76f40754 [to #42322933]Add text-generation-pipeline with Palm model.
将 Palm 中文模型接入 MaaS,添加了文本生成 pipeline
        Link: https://code.alibaba-inc.com/Ali-MaaS/MaaS-lib/codereview/8934393

    * add text_generation model and pipeline

* fix bug

* fix bug

* add TextGenerator in pipeline

* fix bug

* update checkpoint and test inputs

* remove magic number..

* fix bug

* adjust code with AutoModel

* clear comments and tidy up the code

* move model.eval() into generator

* update master interface and lint code

* replace 'palm-text-generation' with 'palm'

* add text_generation model and pipeline

* fix bug

* fix bug

* add TextGenerator in pipeline

* fix bug

* fix conflict of pipeline.txt

* remove magic number..

* fix bug

* adjust code with AutoModel

* clear comments and tidy up the code

* move model.eval() into generator

* fix conflict

* replace 'palm-text-generation' with 'palm'

* fix conflict

* add test_run_modelhub

* update sofa version

* modify sofa version

* add test_run_with_model_name

* fix bug
2022-06-08 17:11:04 +08:00

150 lines
4.6 KiB
Python

# Copyright (c) Alibaba, Inc. and its affiliates.
import uuid
from typing import Any, Dict, Union
from transformers import AutoTokenizer
from maas_lib.utils.constant import Fields, InputFields
from maas_lib.utils.type_assert import type_assert
from .base import Preprocessor
from .builder import PREPROCESSORS
__all__ = ['Tokenize', 'SequenceClassificationPreprocessor']
@PREPROCESSORS.register_module(Fields.nlp)
class Tokenize(Preprocessor):
def __init__(self, tokenizer_name) -> None:
self._tokenizer = AutoTokenizer.from_pretrained(tokenizer_name)
def __call__(self, data: Union[str, Dict[str, Any]]) -> Dict[str, Any]:
if isinstance(data, str):
data = {InputFields.text: data}
token_dict = self._tokenizer(data[InputFields.text])
data.update(token_dict)
return data
@PREPROCESSORS.register_module(
Fields.nlp, module_name=r'bert-sentiment-analysis')
class SequenceClassificationPreprocessor(Preprocessor):
def __init__(self, model_dir: str, *args, **kwargs):
"""preprocess the data via the vocab.txt from the `model_dir` path
Args:
model_dir (str): model path
"""
super().__init__(*args, **kwargs)
from easynlp.modelzoo import AutoTokenizer
self.model_dir: str = model_dir
self.first_sequence: str = kwargs.pop('first_sequence',
'first_sequence')
self.second_sequence = kwargs.pop('second_sequence', 'second_sequence')
self.sequence_length = kwargs.pop('sequence_length', 128)
self.tokenizer = AutoTokenizer.from_pretrained(self.model_dir)
@type_assert(object, str)
def __call__(self, data: str) -> Dict[str, Any]:
"""process the raw input data
Args:
data (str): a sentence
Example:
'you are so handsome.'
Returns:
Dict[str, Any]: the preprocessed data
"""
new_data = {self.first_sequence: data}
# preprocess the data for the model input
rst = {
'id': [],
'input_ids': [],
'attention_mask': [],
'token_type_ids': []
}
max_seq_length = self.sequence_length
text_a = new_data[self.first_sequence]
text_b = new_data.get(self.second_sequence, None)
feature = self.tokenizer(
text_a,
text_b,
padding='max_length',
truncation=True,
max_length=max_seq_length)
rst['id'].append(new_data.get('id', str(uuid.uuid4())))
rst['input_ids'].append(feature['input_ids'])
rst['attention_mask'].append(feature['attention_mask'])
rst['token_type_ids'].append(feature['token_type_ids'])
return rst
@PREPROCESSORS.register_module(Fields.nlp, module_name=r'palm')
class TextGenerationPreprocessor(Preprocessor):
def __init__(self, model_dir: str, *args, **kwargs):
"""preprocess the data using the vocab.txt from the `model_dir` path
Args:
model_dir (str): model path
"""
from sofa import PalmTokenizer
super().__init__(*args, **kwargs)
self.model_dir: str = model_dir
self.first_sequence: str = kwargs.pop('first_sequence',
'first_sequence')
self.second_sequence: str = kwargs.pop('second_sequence',
'second_sequence')
self.sequence_length: int = kwargs.pop('sequence_length', 128)
self.tokenizer = PalmTokenizer.from_pretrained(model_dir)
@type_assert(object, str)
def __call__(self, data: str) -> Dict[str, Any]:
"""process the raw input data
Args:
data (str): a sentence
Example:
'you are so handsome.'
Returns:
Dict[str, Any]: the preprocessed data
"""
import torch
new_data = {self.first_sequence: data}
# preprocess the data for the model input
rst = {'input_ids': [], 'attention_mask': [], 'token_type_ids': []}
max_seq_length = self.sequence_length
text_a = new_data.get(self.first_sequence, None)
text_b = new_data.get(self.second_sequence, None)
feature = self.tokenizer(
text_a,
text_b,
padding='max_length',
truncation=True,
max_length=max_seq_length)
rst['input_ids'].append(feature['input_ids'])
rst['attention_mask'].append(feature['attention_mask'])
rst['token_type_ids'].append(feature['token_type_ids'])
return {k: torch.tensor(v) for k, v in rst.items()}