Extractive#

This tutorial is available as an IPython notebook at Malaya/example/qa-extractive.

This module only trained on standard language structure, so it is not save to use it for local language structure.

[1]:
import os

os.environ['CUDA_VISIBLE_DEVICES'] = ''
[2]:
import logging

logging.basicConfig(level=logging.INFO)
[3]:
%%time

import malaya
from pprint import pprint
/home/husein/.local/lib/python3.8/site-packages/bitsandbytes/cextension.py:34: UserWarning: The installed version of bitsandbytes was compiled without GPU support. 8-bit optimizers, 8-bit multiplication, and GPU quantization are unavailable.
  warn("The installed version of bitsandbytes was compiled without GPU support. "
/home/husein/.local/lib/python3.8/site-packages/bitsandbytes/libbitsandbytes_cpu.so: undefined symbol: cadam32bit_grad_fp32
INFO:torch.distributed.nn.jit.instantiator:Created a temporary directory at /tmp/tmpmzsrez5d
INFO:torch.distributed.nn.jit.instantiator:Writing /tmp/tmpmzsrez5d/_remote_module_non_scriptable.py
CPU times: user 2.72 s, sys: 4 s, total: 6.72 s
Wall time: 1.94 s
/home/husein/dev/malaya/malaya/tokenizer.py:214: FutureWarning: Possible nested set at position 3397
  self.tok = re.compile(r'({})'.format('|'.join(pipeline)))
/home/husein/dev/malaya/malaya/tokenizer.py:214: FutureWarning: Possible nested set at position 3927
  self.tok = re.compile(r'({})'.format('|'.join(pipeline)))

What is Extractive QA#

is a reading comprehension problem, eg,

{
    'title': 'Normans',
    'paragraphs': [
        {
            'context': 'Orang Norman (Norman: Nourmands; Perancis: Normands; Latin: Normanni) ialah orang-orang yang pada abad ke-10 dan ke-11 memberikan nama mereka kepada Normandy, sebuah wilayah di Perancis. Mereka diturunkan daripada Norse ("Norman" berasal daripada penyerang "Norseman") dan lanun dari Denmark, Iceland dan Norway yang, di bawah pimpinan mereka Rollo, bersetuju untuk bersumpah fealty kepada Raja Charles III dari Francia Barat. Melalui generasi asimilasi dan percampuran dengan penduduk asli Frankish dan Roman-Gaulish, keturunan mereka akan beransur-ansur bergabung dengan budaya Carolingian yang berpusat di Francia Barat. Identiti budaya dan etnik yang berbeza dari orang Norman muncul pada mulanya pada separuh pertama abad ke-10, dan ia terus berkembang pada abad-abad yang berjaya.',
            'qas': [
                {
                    'question': 'Di negara manakah Normandy berada?',
                    'answers': [
                        {'text': 'Perancis', 'answer_start': 177},
                        {'text': 'Perancis', 'answer_start': 177},
                        {'text': 'Perancis', 'answer_start': 177},
                        {'text': 'Perancis', 'answer_start': 177},
                    ],
                    'id': '56ddde6b9a695914005b9628',
                    'is_impossible': False,
                }
            ],
        }
    ],
}

So we need to give a long paragraph and multiple questions, and the model will return answers based on that paragraph with start and end spans. Read more about SQUAD dataset https://rajpurkar.github.io/SQuAD-explorer/

List available HuggingFace models#

[4]:
malaya.qa.extractive.available_huggingface
[4]:
{'mesolitica/finetune-qa-t5-tiny-standard-bahasa-cased': {'Size (MB)': 139,
  'exact-ms': 0.426955861,
  'f1-ms': 0.5113033923,
  'exact-en': 0.4692567567,
  'f1-en': 0.541063384},
 'mesolitica/finetune-qa-t5-small-standard-bahasa-cased': {'Size (MB)': 242,
  'exact-ms': 0.530340113,
  'f1-ms': 0.61693299,
  'exact-en': 0.55878378,
  'f1-en': 0.6292999233},
 'mesolitica/finetune-qa-t5-base-standard-bahasa-cased': {'Size (MB)': 892,
  'exact-ms': 0.570354729,
  'f1-ms': 0.64136968,
  'exact-en': 0.570354729,
  'f1-en': 0.64136968144}}

Load HuggingFace model#

def huggingface(
    model: str = 'mesolitica/finetune-qa-t5-small-standard-bahasa-cased',
    force_check: bool = True,
    **kwargs,
):
    """
    Load HuggingFace model to answer extractive question answers.

    Parameters
    ----------
    model: str, optional (default='mesolitica/finetune-qa-t5-small-standard-bahasa-cased')
        Check available models at `malaya.qa.extractive.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.

    Returns
    -------
    result: malaya.torch_model.huggingface.ExtractiveQA
    """
[23]:
model = malaya.qa.extractive.huggingface(model = 'mesolitica/finetune-qa-t5-small-standard-bahasa-cased')

Copy from wikipedia and news#

[9]:
# https://ms.wikipedia.org/wiki/Mohd_Najib_bin_Abdul_Razak

p_wikipedia = """
Najib razak telah dipilih untuk Parlimen Malaysia pada tahun 1976,
pada usia 23 tahun, menggantikan bapanya duduk di kerusi Pekan yang berpangkalan di Pahang.
Dari tahun 1982 hingga 1986 beliau menjadi Menteri Besar (Ketua Menteri) Pahang,
sebelum memasuki persekutuan Kabinet Tun Dr Mahathir Mohamad pada tahun 1986 sebagai Menteri Kebudayaan, Belia dan Sukan.
Beliau telah berkhidmat dalam pelbagai jawatan Kabinet sepanjang baki tahun 1980-an dan 1990-an, termasuk sebagai Menteri Pertahanan dan Menteri Pelajaran.
Beliau menjadi Timbalan Perdana Menteri pada 7 Januari 2004, berkhidmat di bawah Perdana Menteri Tun Dato' Seri Abdullah Ahmad Badawi,
sebelum menggantikan Badawi setahun selepas Barisan Nasional mengalami kerugian besar dalam pilihan raya 2008.
Di bawah kepimpinan beliau, Barisan Nasional memenangi pilihan raya 2013,
walaupun buat kali pertama dalam sejarah Malaysia pembangkang memenangi majoriti undi popular.
"""
q_wikipedia = [
    'pada umur berapa najib razak menggantikan ayahnya',
    'Apakah jawatan yang pernah dipegang oleh Najib Razak',
    'what date najib become deputy prime minister',
]
[10]:
# https://www.malaysiakini.com/news/574914

p_news = """
Bekas perdana menteri Najib Razak mempersoalkan tindakan polis yang menurutnya tidak serta-merta mengeluarkan kenyataan berhubung dakwaan Adun Perikatan Nasional (PN) "merancang" insiden rogol.
Sedangkan, kata ahli parlimen Pekan itu, polis pantas mengeluarkan kenyataan apabila dia dilapor terlupa mengimbas MySejahtera sebelum masuk restoran.
"Berita Najib lupa scan MySejahtera tular, kenyataan polis terus keluar. Berita Dr Mahathir Mohamad lupa scan, kenyataan, polis serta-merta keluar.
"Sebab itu saya pelik kenapa pihak polis belum sempat keluar apa-apa kenyataan berhubung kes seorang gadis membuat laporan polis untuk dakwa Adun PN rancang insiden rogolnya," katanya di Facebook hari ini.
Najib merujuk dakwaan seorang wanita yang mendakwa dirogol kenalan kepada Adun Gombak Setia, Hilman Idham.
Wanita itu mendakwa ahli politik dari Bersatu berkenaan merancang insiden yang berlaku pada 5 Dis lalu.
Menurut laporan polis pada 8 Mei, mangsa mendakwa kejadian itu berlaku di sebuah hotel di Selangor, yang pada masa itu berada di bawah perintah kawalan pergerakan bersyarat (PKPB).
"""

q_news = [
    'siapakah yang mempersoalkan tindakan polis',
    'siapakah Adun Gombak Setia',
    'when does make the allegation',
]
[11]:
# https://www.parlimen.gov.my/files/hindex/pdf/DR-19122022.pdf

p_parlimen = """
Menteri Dalam Negeri [Datuk Seri Saifuddin Nasution bin Ismail]:
Assalamualaikum warahmatullahi wabarakatuh. Tuan Yang diPertua, saya mohon
mencadangkan:
“Bahawa Majlis ini memerintahkan Ketua Polis Negara
menjaga supaya selama Penggal Dewan Rakyat Parlimen Kelima
Belas yang ada sekarang, jalan-jalan melalui lorong-lorong menuju ke
Dewan ini hendaklah sentiasa terbuka dan boleh dilalui dan jangan
ada apa-apa halangan menghalang Ahli-ahli hendak pergi dan balik
dari Dewan ini, jangan berlaku apa-apa kacau bilau di jalan-jalan
menuju ke Dewan ini, dan supaya jangan ada huru-hara di Bangunan
Dewan ini dan berhampiran dengan bangunan ini; dan Setiausaha
Dewan Rakyat hendaklah menyampaikan perintah ini kepada Ketua
Polis Negara yang tersebut itu”.
Terima kasih.
Timbalan Menteri Dalam Negeri [Datuk Seri Dr. Shamsul Anuar bin
Nasarah]: Tuan Yang di-Pertua, saya mohon menyokong.
Tuan Yang di-Pertua: Terima kasih. Ahli-ahli Yang Berhormat, masalahnya
ialah usul oleh Yang Berhormat Menteri Dalam Negeri yang telah dibacakan tadi
hendaklah dipersetujukan
"""

q_parlimen = [
    'siapakah yang mempersoalkan tindakan polis',
    'apakah ketua polis negara yang perlukan dibuat',
    'who need to instruct chief police',
]

Predict#

def predict(
    self,
    paragraph_text: str,
    question_texts: List[str],
    validate_answers: bool = True,
    validate_questions: bool = False,
    minimum_threshold_question: float = 0.05,
    **kwargs,
):
    """
    Predict extractive answers from questions given a paragraph.

    Parameters
    ----------
    paragraph_text: str
    question_texts: List[str]
        List of questions, results really depends on case sensitive questions.
    validate_answers: bool, optional (default=True)
        if True, will check the answer is inside the paragraph.
    validate_questions: bool, optional (default=True)
        if True, validate the question is subset of the paragraph using `sklearn.feature_extraction.text.CountVectorizer`
    minimum_threshold_question: float, optional (default=0.05)
        minimum score from `cosine_similarity`, only useful if `validate_questions = True`.
    **kwargs: vector arguments pass to huggingface `generate` method.
        Read more at https://huggingface.co/docs/transformers/main_classes/text_generation

    Returns
    -------
    result: List[str]
    """
[12]:
model.predict(p_wikipedia, q_wikipedia)
/home/husein/.local/lib/python3.8/site-packages/transformers/generation/utils.py:1260: UserWarning: Using the model-agnostic default `max_length` (=20) to control the generation length. We recommend setting `max_new_tokens` to control the maximum length of the generation.
  warnings.warn(
spaces_between_special_tokens is deprecated and will be removed in transformers v5. It was adding spaces between `added_tokens`, not special tokens, and does not exist in our fast implementation. Future tokenizers will handle the decoding process on a per-model rule.
[12]:
['23 tahun', 'Menteri Besar (Ketua Menteri) Pahang', '7 Januari 2004']
[13]:
model.predict(p_news, q_news)
[13]:
['Najib Razak', 'Adun Gombak Setia, Hilman Idham', '5 Dis lalu']
[14]:
model.predict(p_parlimen, q_parlimen, max_length=50,
    num_beams=5,
    early_stopping=True)
[14]:
['Datuk Seri Saifuddin Nasution bin Ismail',
 '"Bahawa Majlis ini memerintahkan Ketua Polis Negara menjaga supaya selama Penggal Dewan Rakyat Parlimen Kelima Belas',
 'Datuk Seri Saifuddin Nasution bin Ismail']

Able to mixed MS and EN#

Paragraph or questions can be both MS or EN or mixed.

[15]:
# https://ms.wikipedia.org/wiki/Mohd_Najib_bin_Abdul_Razak

p_wikipedia = """
Najib razak telah dipilih untuk Parlimen Malaysia pada tahun 1976,
pada usia 23 tahun, menggantikan bapanya duduk di kerusi Pekan yang berpangkalan di Pahang.
Dari tahun 1982 hingga 1986 beliau menjadi Menteri Besar (Ketua Menteri) Pahang,
sebelum memasuki persekutuan Kabinet Tun Dr Mahathir Mohamad pada tahun 1986 sebagai Menteri Kebudayaan, Belia dan Sukan.
Beliau telah berkhidmat dalam pelbagai jawatan Kabinet sepanjang baki tahun 1980-an dan 1990-an, termasuk sebagai Menteri Pertahanan dan Menteri Pelajaran.
Beliau menjadi Timbalan Perdana Menteri pada 7 Januari 2004, berkhidmat di bawah Perdana Menteri Tun Dato' Seri Abdullah Ahmad Badawi,
sebelum menggantikan Badawi setahun selepas Barisan Nasional mengalami kerugian besar dalam pilihan raya 2008.
Di bawah kepimpinan beliau, Barisan Nasional memenangi pilihan raya 2013,
walaupun buat kali pertama dalam sejarah Malaysia pembangkang memenangi majoriti undi popular.
"""
q_wikipedia = [
    'pada umur berapa najib razak menggantikan ayahnya',
    'Apakah jawatan yang pernah dipegang oleh Najib Razak',
    'what age najib razak replaced his father']
[16]:
model.predict(p_wikipedia, q_wikipedia)
[16]:
['23 tahun', 'Menteri Besar (Ketua Menteri) Pahang', '23 tahun']
[17]:
# https://www.malaysiakini.com/news/574914

p_news = """
Bekas perdana menteri Najib Razak mempersoalkan tindakan polis yang menurutnya tidak serta-merta mengeluarkan kenyataan berhubung dakwaan Adun Perikatan Nasional (PN) "merancang" insiden rogol.
Sedangkan, kata ahli parlimen Pekan itu, polis pantas mengeluarkan kenyataan apabila dia dilapor terlupa mengimbas MySejahtera sebelum masuk restoran.
"Berita Najib lupa scan MySejahtera tular, kenyataan polis terus keluar. Berita Dr Mahathir Mohamad lupa scan, kenyataan, polis serta-merta keluar.
"Sebab itu saya pelik kenapa pihak polis belum sempat keluar apa-apa kenyataan berhubung kes seorang gadis membuat laporan polis untuk dakwa Adun PN rancang insiden rogolnya," katanya di Facebook hari ini.
Najib merujuk dakwaan seorang wanita yang mendakwa dirogol kenalan kepada Adun Gombak Setia, Hilman Idham.
Wanita itu mendakwa ahli politik dari Bersatu berkenaan merancang insiden yang berlaku pada 5 Dis lalu.
Menurut laporan polis pada 8 Mei, mangsa mendakwa kejadian itu berlaku di sebuah hotel di Selangor, yang pada masa itu berada di bawah perintah kawalan pergerakan bersyarat (PKPB).
"""

q_news = [
    'siapakah yang mempersoalkan tindakan polis',
    'siapakah Adun Gombak Setia',
    'who is the victim on 8 may incident',
    'where does the 8 may incident happened',
]
[18]:
model.predict(p_news, q_news)
[18]:
['Najib Razak',
 'Adun Gombak Setia, Hilman Idham',
 'Adun Gombak Setia, Hilman Idham',
 'sebuah hotel di Selangor']
[21]:
# https://en.wikipedia.org/wiki/Anwar_Ibrahim

p_anwar = """
A graduate from University of Malaya, Anwar started his political career as one of the founders of youth organisation Angkatan Belia Islam Malaysia (ABIM).[4] After joining the United Malays National Organisation (UMNO), the major party in the long-time ruling BN coalition, Anwar held several cabinet positions in successive governments in the 1980s and 1990s. He was Deputy Prime Minister and Finance Minister during the 1990s and was prominent in Malaysia's response to the 1997 Asian financial crisis.[5] In 1998, he was removed from all posts by Prime Minister Mahathir Mohamad and went on to spearhead the Reformasi movement against the government. Anwar was jailed in April 1999 after a trial for sodomy and corruption that was criticised by human rights groups[6] and several foreign governments, until his release in 2004 after his conviction was overturned. He made a comeback as Leader of the Opposition from 2008 to 2015 and coalesced opposition parties into the Pakatan Rakyat (PR) coalition, which unsuccessfully contested in the 2008 and 2013 general elections. He disputed the results of the 2013 elections and led a protest in response.

In 2014, Anwar's attempt to become Selangor head of government in the 2014 Kajang Move led to a nine-month political crisis, which ended when he was sentenced to another five years imprisonment after a second sodomy conviction in 2015.[7] While still in prison, Anwar re-joined Mahathir Mohamad in the new Pakatan Harapan (PH) coalition in absentia, which went on to win the 2018 general election. Mahathir outlined a plan for Anwar to take over from himself as Prime Minister after an unspecified interim period.[8] Anwar received a royal pardon from Yang di-Pertuan Agong Muhammad V[9] and was released from prison in May 2018.[10][11] He returned to parliament in the 2018 Port Dickson by-election while his wife Wan Azizah Wan Ismail served as the Deputy Prime Minister in the PH administration. The collapse of the coalition during 2020–22 Malaysian political crisis led to the new Perikatan Nasional (PN) coalition under Muhyiddin Yassin being sworn in and Anwar becoming Leader of the Opposition for the second time in May 2020.
"""

q_anwar = [
    'tahun bila kajang move',
    'macam mana anwar mula his political career',
]
[22]:
model.predict(p_anwar, q_anwar)
[22]:
['1998', 'youth organisation Angkatan Belia Islam Malaysia (ABIM).']