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.24 s, sys: 3.67 s, total: 6.91 s
Wall time: 2.25 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-v4',)
2022-12-19 15:05:28.466979: 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.
2022-12-19 15:05:28.472055: E tensorflow/stream_executor/cuda/cuda_driver.cc:271] failed call to cuInit: CUDA_ERROR_NO_DEVICE: no CUDA-capable device is detected
2022-12-19 15:05:28.472078: I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:169] retrieving CUDA diagnostic information for host: husein-MS-7D31
2022-12-19 15:05:28.472081: I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:176] hostname: husein-MS-7D31
2022-12-19 15:05:28.472163: I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:200] libcuda reported version is: Not found: was unable to find libcuda.so DSO loaded into this program
2022-12-19 15:05:28.472205: I tensorflow/stream_executor/cuda/cuda_diagnostics.cc:204] kernel reported version is: 470.161.3
[5]:
model = malaya.normalizer.abstractive.huggingface(model = 'mesolitica/finetune-noisy-translation-t5-small-bahasa-cased-v4',
                                                  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 terkejut nak keluarkan semua. Idul Fitri lagi.']
[11]:
model.generate(['@mesyceres Haha ayookk keluarkan semuanya. Bentar lagi Idul Fitri .'], max_length = 256)
[11]:
['@mesyceres Haha jom keluarkan semuanya. Idul Fitri lagi.']
[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 semua! Saya perasan semalam & hari ni ramai yang dapat biskut ni kan? Jadi hari ini saya ingin berkongsi beberapa post mortem batch 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 semua! Saya perasan semalam & hari ni ramai yang dapat biskut ni kan? Jadi hari ini saya ingin berkongsi beberapa post mortem batch 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, suruh gosok baju pun kena belajar kat toktok.']
[15]:
model.generate([s], max_length = 256)
[15]:
['Tak guna budak zaman sekarang ni, kalau 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]:
['Sepi juga bila adik beradik dah kahwin / kahwin']
[17]:
model.generate([s], max_length = 256)
[17]:
['Sepi 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 bencana. Dengan mesin yang ada, ia sebenarnya boleh. Ini adalah permulaan yang baik.']
[19]:
model.generate([s], max_length = 256)
[19]:
['Rasa janggal bila tengok kerajaan cepat buat kerja 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_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 sendiri kita kena bagi kesan yang baik untuk 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 sendiri kita dah dapat kesan yang baik menunjukkan siapa diri kita yang sebenar']
[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 cukup, puan... berehatlah dari politik agar tidak terus dibenci orang dengan kenyataan pelik dan mengelirukan...']
[23]:
model.generate([s], max_length = 256)
[23]:
['Itu sahaja, puan... berehatlah dari politik agar tidak terus dibenci orang dengan kenyataan 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]:
['Ayuh cik... rehat dari politik supaya tidak terus dibenci orang dengan kenyataan yang pelik dan mengelirukan...',
 'Itu sahaja, puan... rehatkan politik supaya tidak terus dibenci orang dengan kenyataan pelik dan mengelirukan...',
 'Dah tu pakcik... berehat dari politik supaya orang tidak terus membencinya dengan kenyataan pelik dan mengelirukan...']
[25]:
model.generate([s], max_length = 256, do_sample=True, penalty_alpha=0.6, top_k=4, temperature = 0.7,
                         num_return_sequences=3)
[25]:
['Itu sahaja, puan... rehat politik supaya tidak terus dibenci oleh orang dengan kenyataan pelik dan mengelirukan...',
 'Sudah, ayuh cik.. berehat dari politik supaya tidak terus dibenci orang dengan kenyataan pelik dan mengelirukan...',
 'Itu sahaja, makcik... rehat dari politik supaya tidak terus dibenci orang dengan kenyataan yang pelik dan mengelirukan...']
[ ]: