Transformers documentation
Pemodelan bahasa kausal
Pemodelan bahasa kausal
Ada dua jenis pemodelan bahasa, yaitu kausal dan tersembunyi (masked). Panduan ini mengilustrasikan pemodelan bahasa kausal. Model bahasa kausal sering digunakan untuk generasi teks. Anda dapat menggunakan model-model ini untuk aplikasi kreatif seperti pilih petualangan teks Anda sendiri atau asisten pemrograman cerdas seperti Copilot atau CodeParrot.
Causal language modeling memprediksi token berikutnya dalam urutan token, dan model hanya dapat memperhatikan token di sebelah kiri. Ini berarti model tidak dapat melihat token di masa depan. GPT-2 adalah contoh dari model bahasa kausal.
Panduan ini akan menunjukkan cara Anda untuk:
- Lakukan finetune DistilGPT2 pada subset r/askscience dari dataset ELI5.
- Gunakan model yang telah Anda finetune untuk inferensi.
Untuk melihat semua arsitektur dan checkpoint yang kompatibel dengan tugas ini, kami menyarankan untuk memeriksa halaman tugas
Sebelum memulai, pastikan Anda telah menginstal semua pustaka yang diperlukan:
pip install transformers datasets evaluate
Kami menyarankan Anda untuk masuk ke akun Hugging Face Anda agar dapat mengunggah dan membagikan model Anda dengan komunitas. Saat diminta, masukkan token Anda untuk masuk:
>>> from huggingface_hub import notebook_login
>>> notebook_login()Muat dataset ELI5
Mulai dengan memuat 5000 contoh pertama dari dataset ELI5-Category menggunakan pustaka 🤗 Datasets. Hal ini memberi Anda kesempatan untuk bereksperimen dan memastikan semuanya berfungsi dengan baik sebelum menghabiskan lebih banyak waktu untuk pelatihan pada dataset lengkap.
>>> from datasets import load_dataset
>>> eli5 = load_dataset("dany0407/eli5_category", split="train[:5000]")Bagi split train dari dataset menjadi set train dan test dengan metode train_test_split:
>>> eli5 = eli5.train_test_split(test_size=0.2)Lalu, lihatlah sebuah contoh:
>>> eli5["train"][0]
{'q_id': '7h191n',
'title': 'What does the tax bill that was passed today mean? How will it affect Americans in each tax bracket?',
'selftext': '',
'category': 'Economics',
'subreddit': 'explainlikeimfive',
'answers': {'a_id': ['dqnds8l', 'dqnd1jl', 'dqng3i1', 'dqnku5x'],
'text': ["The tax bill is 500 pages long and there were a lot of changes still going on right to the end. It's not just an adjustment to the income tax brackets, it's a whole bunch of changes. As such there is no good answer to your question. The big take aways are: - Big reduction in corporate income tax rate will make large companies very happy. - Pass through rate change will make certain styles of business (law firms, hedge funds) extremely happy - Income tax changes are moderate, and are set to expire (though it's the kind of thing that might just always get re-applied without being made permanent) - People in high tax states (California, New York) lose out, and many of them will end up with their taxes raised.",
'None yet. It has to be reconciled with a vastly different house bill and then passed again.',
'Also: does this apply to 2017 taxes? Or does it start with 2018 taxes?',
'This article explains both the House and senate bills, including the proposed changes to your income taxes based on your income level. URL_0'],
'score': [21, 19, 5, 3],
'text_urls': [[],
[],
[],
['https://www.investopedia.com/news/trumps-tax-reform-what-can-be-done/']]},
'title_urls': ['url'],
'selftext_urls': ['url']}Meskipun ini mungkin terlihat banyak, yang benar-benar Anda butuhkan hanyalah field text. Hal menarik dari tugas pemodelan bahasa adalah Anda tidak memerlukan label (juga dikenal sebagai tugas tanpa pengawasan) karena kata berikutnya adalah labelnya.
Pra-pemrosesan
Langkah selanjutnya adalah memuat tokenizer DistilGPT2 untuk memproses subfield text:
>>> from transformers import AutoTokenizer
>>> tokenizer = AutoTokenizer.from_pretrained("distilbert/distilgpt2")Anda akan melihat dari contoh di atas, bahwa field text sebenarnya bersarang di dalam answers. Ini berarti Anda perlu mengekstrak subfield text dari struktur bersarangnya dengan metode flatten:
>>> eli5 = eli5.flatten()
>>> eli5["train"][0]
{'q_id': '7h191n',
'title': 'What does the tax bill that was passed today mean? How will it affect Americans in each tax bracket?',
'selftext': '',
'category': 'Economics',
'subreddit': 'explainlikeimfive',
'answers.a_id': ['dqnds8l', 'dqnd1jl', 'dqng3i1', 'dqnku5x'],
'answers.text': ["The tax bill is 500 pages long and there were a lot of changes still going on right to the end. It's not just an adjustment to the income tax brackets, it's a whole bunch of changes. As such there is no good answer to your question. The big take aways are: - Big reduction in corporate income tax rate will make large companies very happy. - Pass through rate change will make certain styles of business (law firms, hedge funds) extremely happy - Income tax changes are moderate, and are set to expire (though it's the kind of thing that might just always get re-applied without being made permanent) - People in high tax states (California, New York) lose out, and many of them will end up with their taxes raised.",
'None yet. It has to be reconciled with a vastly different house bill and then passed again.',
'Also: does this apply to 2017 taxes? Or does it start with 2018 taxes?',
'This article explains both the House and senate bills, including the proposed changes to your income taxes based on your income level. URL_0'],
'answers.score': [21, 19, 5, 3],
'answers.text_urls': [[],
[],
[],
['https://www.investopedia.com/news/trumps-tax-reform-what-can-be-done/']],
'title_urls': ['url'],
'selftext_urls': ['url']}Setiap subfield kini menjadi kolom terpisah seperti yang ditunjukkan oleh prefiks answers, dan field text kini berupa list. Alih-alih melakukan tokenisasi setiap kalimat secara terpisah, konversikan list tersebut menjadi string agar Anda dapat melakukan tokenisasi secara bersama-sama.
Berikut adalah fungsi pra-pemrosesan pertama untuk menggabungkan daftar string untuk setiap contoh dan melakukan tokenisasi pada hasilnya:
>>> def preprocess_function(examples):
... return tokenizer([" ".join(x) for x in examples["answers.text"]])Untuk menerapkan fungsi pra-pemrosesan ini ke seluruh dataset, gunakan metode map dari 🤗 Datasets. Anda dapat mempercepat fungsi map dengan mengatur batched=True untuk memproses beberapa elemen dataset sekaligus, serta meningkatkan jumlah proses dengan num_proc. Hapus kolom apa pun yang tidak Anda butuhkan:
>>> tokenized_eli5 = eli5.map(
... preprocess_function,
... batched=True,
... num_proc=4,
... remove_columns=eli5["train"].column_names,
... )Dataset ini berisi urutan token, tetapi beberapa di antaranya lebih panjang dari panjang input maksimum untuk model.
Anda sekarang dapat menggunakan fungsi pra-pemrosesan kedua untuk
- menggabungkan semua sekuens
- bagikan rangkaian yang telah digabungkan menjadi potongan-potongan lebih pendek yang didefinisikan oleh
block_size, yang harus lebih pendek dari panjang input maksimum dan cukup pendek untuk RAM GPU Anda.
>>> block_size = 128
>>> def group_texts(examples):
... # Concatenate all texts.
... concatenated_examples = {k: sum(examples[k], []) for k in examples.keys()}
... total_length = len(concatenated_examples[list(examples.keys())[0]])
... # We drop the small remainder, we could add padding if the model supported it instead of this drop, you can
... # customize this part to your needs.
... if total_length >= block_size:
... total_length = (total_length // block_size) * block_size
... # Split by chunks of block_size.
... result = {
... k: [t[i : i + block_size] for i in range(0, total_length, block_size)]
... for k, t in concatenated_examples.items()
... }
... result["labels"] = result["input_ids"].copy()
... return resultTerapkan fungsi group_texts pada seluruh dataset:
>>> lm_dataset = tokenized_eli5.map(group_texts, batched=True, num_proc=4)Sekarang buat satu batch contoh menggunakan DataCollatorForLanguageModeling. Lebih efisien untuk melakukan padding secara dinamis kalimat hingga panjang terpanjang dalam satu batch saat collation, daripada melakukan padding seluruh dataset hingga panjang maksimum.
Gunakan token akhir urutan sebagai token padding dan atur mlm=False. Ini akan menggunakan input sebagai label yang digeser ke kanan sebanyak satu elemen:
>>> from transformers import DataCollatorForLanguageModeling
>>> tokenizer.pad_token = tokenizer.eos_token
>>> data_collator = DataCollatorForLanguageModeling(tokenizer=tokenizer, mlm=False)Latih
Jika Anda belum familiar dengan finetuning model menggunakan Trainer, silakan lihat tutorial dasar!
Anda siap untuk mulai melatih model Anda sekarang! Muat DistilGPT2 dengan AutoModelForCausalLM:
>>> from transformers import AutoModelForCausalLM, TrainingArguments, Trainer
>>> model = AutoModelForCausalLM.from_pretrained("distilbert/distilgpt2")Pada titik ini, hanya tersisa tiga langkah:
- Definisikan hiperparameter pelatihan Anda di TrainingArguments. Satu-satunya parameter yang wajib diisi adalah
output_diryang menentukan lokasi penyimpanan model Anda. Anda akan mendorong model ini ke Hub dengan mengaturpush_to_hub=True(Anda harus masuk ke Hugging Face untuk mengunggah model Anda). - Lewatkan argumen pelatihan ke Trainer bersama dengan model, dataset, dan data collator.
- Panggil train() untuk melakukan finetuning pada model Anda.
>>> training_args = TrainingArguments(
... output_dir="my_awesome_eli5_clm-model",
... eval_strategy="epoch",
... learning_rate=2e-5,
... weight_decay=0.01,
... push_to_hub=True,
... )
>>> trainer = Trainer(
... model=model,
... args=training_args,
... train_dataset=lm_dataset["train"],
... eval_dataset=lm_dataset["test"],
... data_collator=data_collator,
... processing_class=tokenizer,
... )
>>> trainer.train()Setelah pelatihan selesai, gunakan metode evaluate() untuk mengevaluasi model Anda dan mendapatkan nilai perplexity-nya:
>>> import math
>>> eval_results = trainer.evaluate()
>>> print(f"Perplexity: {math.exp(eval_results['eval_loss']):.2f}")
Perplexity: 49.61Lalu bagikan model Anda ke Hub dengan metode push_to_hub() agar semua orang dapat menggunakan model Anda:
>>> trainer.push_to_hub()Untuk contoh yang lebih mendalam tentang cara melakukan finetuning model untuk pemodelan bahasa kausal, lihat notebook PyTorch yang sesuai.
Inferensi
Bagus, sekarang setelah Anda melakukan finetuning pada model, Anda dapat menggunakannya untuk inferensi!
Buatlah prompt yang ingin Anda gunakan untuk menghasilkan teks:
>>> prompt = "Somatic hypermutation allows the immune system to"Cara termudah untuk mencoba model finetune Anda untuk inferensi adalah dengan menggunakannya dalam pipeline(). Buat instans pipeline untuk generasi teks dengan model Anda, lalu berikan teks Anda ke dalamnya:
>>> from transformers import pipeline
>>> generator = pipeline("text-generation", model="username/my_awesome_eli5_clm-model")
>>> generator(prompt)
[{'generated_text': "Somatic hypermutation allows the immune system to be able to effectively reverse the damage caused by an infection.\n\n\nThe damage caused by an infection is caused by the immune system's ability to perform its own self-correcting tasks."}]Tokenisasi teks dan kembalikan input_ids sebagai tensor PyTorch:
>>> from transformers import AutoTokenizer
>>> tokenizer = AutoTokenizer.from_pretrained("username/my_awesome_eli5_clm-model")
>>> inputs = tokenizer(prompt, return_tensors="pt").input_idsGunakan metode generate() untuk menghasilkan teks. Untuk detail lebih lanjut tentang berbagai strategi generasi teks dan parameter untuk mengontrol generasi, lihat halaman Text generation strategies.
>>> from transformers import AutoModelForCausalLM
>>> model = AutoModelForCausalLM.from_pretrained("username/my_awesome_eli5_clm-model")
>>> outputs = model.generate(inputs, max_new_tokens=100, do_sample=True, top_k=50, top_p=0.95)Decode id token yang dihasilkan kembali menjadi teks:
>>> tokenizer.batch_decode(outputs, skip_special_tokens=True)
["Somatic hypermutation allows the immune system to react to drugs with the ability to adapt to a different environmental situation. In other words, a system of 'hypermutation' can help the immune system to adapt to a different environmental situation or in some cases even a single life. In contrast, researchers at the University of Massachusetts-Boston have found that 'hypermutation' is much stronger in mice than in humans but can be found in humans, and that it's not completely unknown to the immune system. A study on how the immune system"]