Abstractive Normalizer HuggingFace#

This tutorial is available as an IPython notebook at Malaya/example/normalizer-abstractive.

Results generated using stochastic methods.

[1]:
import os

os.environ['CUDA_VISIBLE_DEVICES'] = ''
[2]:
%%time
import malaya
CPU times: user 3.18 s, sys: 3.4 s, total: 6.58 s
Wall time: 2.33 s

List available HuggingFace models#

[3]:
malaya.normalizer.abstractive.available_huggingface()
[3]:
Size (MB) ROUGE-1 ROUGE-2 ROUGE-L Suggested length
mesolitica/finetune-noisy-translation-t5-small-bahasa-cased-v4 242.0 0.757218 0.496729 0.304022 256.0
mesolitica/finetune-noisy-translation-t5-base-bahasa-cased-v2 892.0 0.713227 0.470135 0.366797 256.0

Load HuggingFace model#

def huggingface(
    model: str = 'mesolitica/finetune-normalizer-t5-small-standard-bahasa-cased',
    force_check: bool = True,
    use_rules_normalizer: bool = True,
    kenlm_model: str = 'bahasa-wiki-news',
    stem_model: str = 'noisy',
    segmenter: Callable = None,
    text_scorer: Callable = None,
    replace_augmentation: bool = True,
    minlen_speller: int = 2,
    maxlen_speller: int = 12,
    **kwargs,
):
    """
    Load HuggingFace model to abstractive text normalizer.
    text -> rules based text normalizer -> abstractive.
    To skip rules based text normalizer, set `use_rules_normalizer=False`.

    Parameters
    ----------
    model: str, optional (default='mesolitica/finetune-normalizer-t5-small-standard-bahasa-cased')
        Check available models at `malaya.normalizer.abstractive.available_huggingface()`.
    force_check: bool, optional (default=True)
        Force check model one of malaya model.
        Set to False if you have your own huggingface model.
    use_rules_normalizer: bool, optional(default=True)
    kenlm_model: str, optional (default='bahasa-wiki-news')
        the model trained on `malaya.language_model.kenlm(model = 'bahasa-wiki-news')`,
        but you can use any kenlm model from `malaya.language_model.available_kenlm`.
        This parameter will be ignored if `use_rules_normalizer=False`.
    stem_model: str, optional (default='noisy')
        the model trained on `malaya.stem.deep_model(model = 'noisy'),
        but you can use any stemmer model from `malaya.stem.available_model`.
        This parameter will be ignored if `use_rules_normalizer=False`.
    segmenter: Callable, optional (default=None)
        segmenter function to segment text, read more at https://malaya.readthedocs.io/en/stable/load-normalizer.html#Use-segmenter
        during training session, we use `malaya.segmentation.huggingface()`.
        It is save to set as None.
        This parameter will be ignored if `use_rules_normalizer=False`.
    text_scorer: Callable, optional (default=None)
        text scorer to validate upper case.
        during training session, we use `malaya.language_model.kenlm(model = 'bahasa-wiki-news')`.
        This parameter will be ignored if `use_rules_normalizer=False`.
    replace_augmentation: bool, optional (default=True)
        Use replace norvig augmentation method. Enabling this might generate bigger candidates, hence slower.
        This parameter will be ignored if `use_rules_normalizer=False`.
    minlen_speller: int, optional (default=2)
        minimum length of word to check spelling correction.
        This parameter will be ignored if `use_rules_normalizer=False`.
    maxlen_speller: int, optional (default=12)
        max length of word to check spelling correction.
        This parameter will be ignored if `use_rules_normalizer=False`.

    Returns
    -------
    result: malaya.torch_model.huggingface.Normalizer
    """
[5]:
model = malaya.normalizer.abstractive.huggingface(model = 'mesolitica/finetune-noisy-translation-t5-small-bahasa-cased-v4',
                                                  use_rules_normalizer = False)
[6]:
model.generate(['ak tk suka hg'], max_length = 256)
You're using a T5TokenizerFast tokenizer. Please note that with a fast tokenizer, using the `__call__` method is faster than using a method to encode the text followed by a call to the `pad` method to get a padded encoding.
[6]:
['Saya tidak suka awak']
[13]:
model.generate(['Dia kat lane dalam tapi nk masuk kanan'], max_length = 256)
[13]:
['Dia berada di lorong dalam tetapi dia mahu masuk ke kanan']
[14]:
model.generate(['@mesyceres Haha ayookk keluarkan semuanya. Bentar lagi Idul Fitri .'], max_length = 256)
[14]:
['@mesyceres Haha jom keluarkan semuanya. Idul Fitri lagi.']
[15]:
model.generate(['Hi guys! I noticed semalam & harini dah ramai yang dapat cookies ni kan. So harini i nak share some post mortem of our first batch:'],
              max_length = 256)
[15]:
['Hai kawan-kawan! Saya perasan semalam & hari ini ramai yang dapat biskut ni kan? Jadi hari ini saya ingin berkongsi beberapa post mortem batch pertama kami:']
[16]:
s = 'Punyalah tak guna bebudak zaman sekarang ni sampaikan gosok baju pun kena belajar kat tiktok.'
model.generate([s], max_length = 256)
[16]:
['Tak guna budak zaman sekarang ni, nak gosok baju pun kena belajar tiktok.']
[17]:
s = 'Lonely jugak ye when your siblings are married/ getting married'
model.generate([s], max_length = 256)
[17]:
['Sepi juga apabila adik-beradik anda sudah berkahwin/berkahwin']
[18]:
s = 'Rasa awkward bila tengok kerajaan laju buat kerja time bencana. With the machineries yang ada, sebenarnya boleh je. This is a good start.'
model.generate([s], max_length = 256)
[18]:
['Rasa janggal bila tengok kerajaan cepat buat kerja masa bencana. Dengan mesin yang ada, ia sebenarnya boleh. Ini adalah permulaan yang baik.']
[20]:
s = 'kalau boleh elakkan ada perkataan macam ni dalam resume. Bukan sebab apa, sebelum kita ke fasa interview, dekat resume tu sendiri kita dah kene bagi good impression menunjukkan siapa diri kita yang sebenarnya'
model.generate([s], max_length = 256)
[20]:
['kalau boleh elakkan ada perkataan macam ni dalam resume. Bukan sebab apa, sebelum kita pergi ke fasa temuduga, dekat resume kita sendiri, kita di sini untuk memberi kesan yang baik untuk menunjukkan siapa kita sebenarnya']
[21]:
s = 'Udah2 lah ayoh cik...berehatlah dari politik agar tidak berterusan dibenci orang dgn kenyataan yg pelik dan mengelirukan...'
model.generate([s], max_length = 256)
[21]:
['Sudah, bro.. berehat dari politik supaya orang tidak terus dibenci dengan kenyataan yang pelik dan mengelirukan...']

Good thing about HuggingFace#

In generate method, you can do greedy, beam, sampling, nucleus decoder and so much more, read it at https://huggingface.co/blog/how-to-generate

[24]:
s = 'Udah2 lah ayoh cik...berehatlah dari politik agar tidak berterusan dibenci orang dgn kenyataan yg pelik dan mengelirukan...'
model.generate([s], max_length = 256, do_sample=True, top_k=100, top_p=0.95, temperature=0.7,
                         num_return_sequences=3)
[24]:
['Sudah ayoh cik... rehat dari politik supaya tidak terus dibenci orang dengan kenyataan yang pelik dan mengelirukan...',
 'Sudah-Sudahlah bro.. berehat dari politik supaya orang tidak terus dibenci dengan kenyataan yang pelik dan mengelirukan...',
 'Itu sahaja.. berehat dari politik supaya tidak terus dibenci orang dengan kenyataan yang pelik dan mengelirukan...']
[27]:
model.generate([s], max_length = 256, do_sample=True, penalty_alpha=0.6, top_k=4, temperature = 0.7,
                         num_return_sequences=3)
[27]:
['Sudah, bro.. berehat dari politik supaya tidak terus dibenci orang dengan kenyataan yang pelik dan mengelirukan...',
 'Itu sahaja bro.. rehat daripada politik supaya tidak dibenci orang dengan kenyataan yang pelik dan mengelirukan...',
 'Itu sahaja bro... berehatlah dari politik supaya orang tidak terus dibenci dengan kenyataan yang pelik dan mengelirukan...']