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.98 s, sys: 3.56 s, total: 7.54 s
Wall time: 3.27 s

List available HuggingFace models#

[3]:
malaya.normalizer.abstractive.available_huggingface()
[3]:
Size (MB) BLEU SacreBLEU Verbose Suggested length
mesolitica/finetune-noisy-translation-t5-tiny-bahasa-cased-v2 139 60.000967 77.9/63.9/54.6/47.7 (BP = 1.000 ratio = 1.036 ... 256
mesolitica/finetune-noisy-translation-t5-small-bahasa-cased-v4 242 64.062582 80.1/67.7/59.1/52.5 (BP = 1.000 ratio = 1.042 ... 256
mesolitica/finetune-noisy-translation-t5-base-bahasa-cased-v2 892 64.583819 80.2/68.1/59.8/53.2 (BP = 1.000 ratio = 1.048 ... 256

Load HuggingFace model#

def huggingface(
    model: str = 'mesolitica/finetune-noisy-translation-t5-small-bahasa-cased-v4',
    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-noisy-translation-t5-small-bahasa-cased-v4')
        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`.
        Also you can pass as None to skip spelling correction but still apply rules normalizer.
        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`.
        Also you can pass as None to skip stemming but still apply rules normalizer.
        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
    """
[4]:
model_default = malaya.normalizer.abstractive.huggingface(model = 'mesolitica/finetune-noisy-translation-t5-small-bahasa-cased-v3',)
2023-02-23 02:15:54.625947: I tensorflow/core/platform/cpu_feature_guard.cc:142] This TensorFlow binary is optimized with oneAPI Deep Neural Network Library (oneDNN) to use the following CPU instructions in performance-critical operations:  AVX2 FMA
To enable them in other operations, rebuild TensorFlow with the appropriate compiler flags.
2023-02-23 02:15:54.634908: E tensorflow/stream_executor/cuda/cuda_driver.cc:271] failed call to cuInit: CUDA_ERROR_NO_DEVICE: no CUDA-capable device is detected
2023-02-23 02:15:54.634927: I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:169] retrieving CUDA diagnostic information for host: husein-MS-7D31
2023-02-23 02:15:54.634930: I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:176] hostname: husein-MS-7D31
2023-02-23 02:15:54.634984: I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:200] libcuda reported version is: 470.161.3
2023-02-23 02:15:54.634997: I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:204] kernel reported version is: 470.161.3
2023-02-23 02:15:54.634999: I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:310] kernel version seems to match DSO: 470.161.3
[5]:
model = malaya.normalizer.abstractive.huggingface(model = 'mesolitica/finetune-noisy-translation-t5-small-bahasa-cased-v3',
                                                  use_rules_normalizer = False)
[6]:
model_default.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']
[7]:
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.
[7]:
['Saya tidak suka awak']
[8]:
model_default.generate(['Dia kat lane dalam tapi nk masuk kanan'], max_length = 256)
[8]:
['Dia berada di lorong dalam tetapi mahu masuk ke kanan']
[9]:
model.generate(['Dia kat lane dalam tapi nk masuk kanan'], max_length = 256)
[9]:
['Dia berada di lorong dalam tetapi mahu masuk ke kanan']
[10]:
model_default.generate(['@mesyceres Haha ayookk keluarkan semuanya. Bentar lagi Idul Fitri .'], max_length = 256)
[10]:
['@mesyceres Haha syok nak keluarkan semuanya. Selamat hari raya aidilfitri.']
[11]:
model.generate(['@mesyceres Haha ayookk keluarkan semuanya. Bentar lagi Idul Fitri .'], max_length = 256)
[11]:
['@mesyceres Haha jom keluarkan semuanya. Selamat Hari Raya Aidilfitri.']
[12]:
model_default.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)
[12]:
['Hai kawan-kawan! Saya perasan semalam & hari ini ramai yang dapat biskut ni kan? Jadi hari ini saya ingin berkongsi beberapa post mortem kumpulan pertama kami:']
[13]:
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)
[13]:
['Hai kawan-kawan! Saya perasan semalam & hari ini ramai yang dapat biskut ni kan? Jadi hari ini saya ingin berkongsi beberapa post mortem kumpulan pertama kami:']
[14]:
s = 'Punyalah tak guna bebudak zaman sekarang ni sampaikan gosok baju pun kena belajar kat tiktok.'
model_default.generate([s], max_length = 256)
[14]:
['Tak guna budak zaman sekarang ni, nak cuci baju pun kena belajar kat toktok.']
[15]:
model.generate([s], max_length = 256)
[15]:
['Tak guna budak zaman sekarang ni, nak gosok baju pun kena belajar kat tiktok.']
[16]:
s = 'Lonely jugak ye when your siblings are married/ getting married'
model_default.generate([s], max_length = 256)
[16]:
['Seronok juga bila adik beradik dah kahwin / kahwin']
[17]:
model.generate([s], max_length = 256)
[17]:
['Seronok juga bila adik beradik dah kahwin/ kahwin']
[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_default.generate([s], max_length = 256)
[18]:
['Rasa janggal bila tengok kerajaan cepat buat kerja semasa bencana. Dengan mesin mesin yang ada, anda sebenarnya boleh. Ini adalah permulaan yang baik.']
[19]:
model.generate([s], max_length = 256)
[19]:
['Rasa janggal bila tengok kerajaan cepat buat kerja semasa bencana. Dengan mesin yang ada, anda 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_default.generate([s], max_length = 256)
[20]:
['kalau boleh elakkan ada perkataan macam ni dalam resume. Bukan sebab apa, sebelum kita pergi fasa temuduga, dekat resume kita sendiri dah bagi impression yang baik menunjukkan siapa kita sebenarnya.']
[21]:
model.generate([s], max_length = 256)
[21]:
['kalau boleh elakkan ada perkataan macam ni dalam resume. Bukan sebab apa, sebelum kita pergi fasa temuduga, dekat resume kita sendiri dah bagi impression yang baik menunjukkan siapa kita sebenarnya.']
[22]:
s = 'Udah2 lah ayoh cik...berehatlah dari politik agar tidak berterusan dibenci orang dgn kenyataan yg pelik dan mengelirukan...'
model_default.generate([s], max_length = 256)
[22]:
['Sudah-Sudah, cik... berehatlah dari politik agar tidak terus dibenci oleh orang dengan kenyataan yang pelik dan mengelirukan...']
[24]:
model.generate([s], max_length = 256)
[24]:
['Ayuh cik... berehatlah dari politik agar tidak terus dibenci oleh orang 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

[25]:
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)
[25]:
['Dah ada, puan... berehatlah dari politik supaya tidak terus membenci orang dengan kenyataan yang pelik dan mengelirukan...',
 'Ayuh cik... berehatlah dari politik agar tidak terus dibenci orang dengan kenyataan pelik dan mengelirukan...',
 'Dah macam tu cik... rehatlah dari politik agar tidak terus dibenci oleh orang dengan kenyataan yang pelik dan mengelirukan...']
[26]:
model.generate([s], max_length = 256, do_sample=True, penalty_alpha=0.6, top_k=4, temperature = 0.7,
                         num_return_sequences=3)
[26]:
['Itu sahaja, puan... berehatlah dari politik agar tidak terus dibenci oleh orang dengan kenyataan pelik dan mengelirukan...',
 'Ayuh cik... rehatlah dari politik agar tidak terus dibenci oleh rakyat dengan kenyataan yang pelik dan mengelirukan...',
 'Ayuh cik... berehatlah dari politik agar tidak terus dibenci oleh orang dengan kenyataan yang pelik dan mengelirukan...']