From e00ae18f81d956e10c2803608c289b9a80190710 Mon Sep 17 00:00:00 2001 From: wxywb Date: Tue, 27 Sep 2022 16:22:17 +0800 Subject: [PATCH] update the operator. Signed-off-by: wxywb --- README.md | 84 +++++++++++++++++++++++++++++++++++++++++++++++++++- __init__.py | 2 +- opus_mt.py | 4 +-- result.png | Bin 0 -> 12266 bytes 4 files changed, 86 insertions(+), 4 deletions(-) create mode 100644 result.png diff --git a/README.md b/README.md index 81792b8..95817a4 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,84 @@ -# opus_mt +# Machine Translation with Opus-MT +*author: David Wang* + +
+ +## Description + +A machine translation operator translates a sentence, paragraph, or document from source language +to the target language. This operator is trained on [OPUS](https://opus.nlpl.eu/) data by Helsinki-NLP. +More detail can be found in [ Helsinki-NLP/Opus-MT ](https://github.com/Helsinki-NLP/Opus-MT). + +
+ +## Code Example + +Use the pre-trained model 'opus-mt-en-zh' +to generate the Chinese translation for the sentence "Hello, world.". + +*Write the pipeline*: + +```python +import towhee + +( + towhee.dc(["Hello, world."]) + .machine_translation.opus_mt(model_name="opus-mt-en-zh") +) +``` + +*Write a same pipeline with explicit inputs/outputs name specifications:* + +```python +import towhee + +( + towhee.dc['text'](["Hello, world."]) + .machine_translation.opus_mt['text', 'vec'](model_name="opus-mt-en-zh") + .show() +) +``` + + + +
+ +## Factory Constructor + +Create the operator via the following factory method: + +***machine_translatioin.opus_mt(model_name="opus-mt-en-zh")*** + +**Parameters:** + +***model_name***: *str* + +The model name in string. +The default model name is "opus-mt-en-zh". + +Supported model names: + - opus-mt-en-zh + - opus-mt-zh-en + +
+ +## Interface + +The operator takes a piece of text in string as input. +It loads tokenizer and pre-trained model using model name. +and then return translated text in string. + +***__call__(text)*** + +**Parameters:** + +***text***: *str* + +​ The source language text in string. + +**Returns**: + +*str* + +​ The target language text. diff --git a/__init__.py b/__init__.py index 89f28f3..0c60ce3 100644 --- a/__init__.py +++ b/__init__.py @@ -14,5 +14,5 @@ from .opus_mt import OpusMT -def opus_mt(model_name: str): +def opus_mt(model_name: str = 'opus-mt-en-zh'): return OpusMT(model_name) diff --git a/opus_mt.py b/opus_mt.py index df14415..9860433 100644 --- a/opus_mt.py +++ b/opus_mt.py @@ -37,8 +37,8 @@ class OpusMT(NNOperator): self.model = AutoModelForSeq2SeqLM.from_pretrained(config['model']) self.model.to(self.device) - def __call__(self, data): - input_ids = self.tokenizer(data, return_tensors='pt', padding=True)['input_ids'].to(self.device) + def __call__(self, text): + input_ids = self.tokenizer(text, return_tensors='pt', padding=True)['input_ids'].to(self.device) outputs = self.model.generate(input_ids) decoded = self.tokenizer.decode(outputs[0].detach().cpu(), skip_special_tokens=True) return decoded diff --git a/result.png b/result.png new file mode 100644 index 0000000000000000000000000000000000000000..f4607fc1930461f81fb72e4f9f26d52c4a61532d GIT binary patch literal 12266 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 literal 0 HcmV?d00001