Transformers documentation
Mô hình hóa ngôn ngữ nhân quả
Mô hình hóa ngôn ngữ nhân quả
Có hai loại mô hình hóa ngôn ngữ: causal và masked. Hướng dẫn này minh họa mô hình hóa ngôn ngữ causal. Các mô hình ngôn ngữ causal thường được sử dụng cho việc tạo văn bản. Bạn có thể sử dụng các mô hình này cho các ứng dụng sáng tạo như chọn phiêu lưu văn bản của riêng bạn hoặc một trợ lý lập trình thông minh như Copilot hoặc CodeParrot.
Mô hình hóa ngôn ngữ nhân quả dự đoán token tiếp theo trong một chuỗi các token, và mô hình chỉ có thể chú ý đến các token ở phía bên trái. Điều này có nghĩa là mô hình không thể nhìn thấy các token trong tương lai. GPT-2 là một ví dụ về mô hình ngôn ngữ nhân quả.
Hướng dẫn này sẽ cho bạn thấy cách:
- Hạ tầng DistilGPT2 trên tập con r/askscience của bộ dữ liệu ELI5.
- Sử dụng mô hình đã tinh chỉnh của bạn để suy luận.
Để xem tất cả các kiến trúc và checkpoint tương thích với tác vụ này, chúng tôi khuyến nghị bạn kiểm tra trang tác vụ
Trước khi bắt đầu, hãy đảm bảo bạn đã cài đặt tất cả các thư viện cần thiết:
pip install transformers datasets evaluate
Chúng tôi khuyến khích bạn đăng nhập vào tài khoản Hugging Face của mình để có thể tải lên và chia sẻ mô hình của bạn với cộng đồng. Khi được yêu cầu, hãy nhập token của bạn để đăng nhập:
>>> from huggingface_hub import notebook_login
>>> notebook_login()Tải bộ dữ liệu ELI5
Bắt đầu bằng cách tải 5000 ví dụ đầu tiên từ bộ dữ liệu ELI5-Category bằng thư viện 🤗 Datasets. Điều này sẽ cho bạn cơ hội thử nghiệm và đảm bảo mọi thứ hoạt động trước khi dành thêm thời gian huấn luyện trên toàn bộ bộ dữ liệu.
>>> from datasets import load_dataset
>>> eli5 = load_dataset("dany0407/eli5_category", split="train[:5000]")Chia split train của bộ dữ liệu thành tập train và tập test bằng phương thức train_test_split:
>>> eli5 = eli5.train_test_split(test_size=0.2)Sau đó, hãy xem một ví dụ:
>>> 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']}Mặc dù điều này có vẻ như là rất nhiều, bạn thực sự chỉ quan tâm đến trường text. Điều thú vị về các tác vụ mô hình hóa ngôn ngữ là bạn không cần nhãn (còn được gọi là tác vụ không giám sát) vì từ tiếp theo chính là nhãn.
Tiền xử lý
Bước tiếp theo là nạp một tokenizer DistilGPT2 để xử lý trường con text:
>>> from transformers import AutoTokenizer
>>> tokenizer = AutoTokenizer.from_pretrained("distilbert/distilgpt2")Bạn sẽ nhận thấy từ ví dụ ở trên, trường text thực sự nằm lồng bên trong answers. Điều này có nghĩa là bạn sẽ cần
trích xuất trường con text khỏi cấu trúc lồng nhau bằng phương thức 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']}Mỗi trường con giờ là một cột riêng biệt như được chỉ ra bởi tiền tố answers, và trường text giờ là một danh sách. Thay vì tách token từng câu riêng lẻ, hãy chuyển danh sách thành một chuỗi để bạn có thể tách token chúng cùng nhau.
Dưới đây là một hàm tiền xử lý đầu tiên để ghép danh sách các chuỗi cho mỗi ví dụ và thực hiện token hóa kết quả:
>>> def preprocess_function(examples):
... return tokenizer([" ".join(x) for x in examples["answers.text"]])Để áp dụng hàm tiền xử lý này cho toàn bộ tập dữ liệu, hãy sử dụng phương thức map của 🤗 Datasets. Bạn có thể tăng tốc hàm map bằng cách đặt batched=True để xử lý nhiều phần tử của tập dữ liệu cùng lúc, và tăng số lượng tiến trình bằng num_proc. Xóa bất kỳ cột nào bạn không cần:
>>> tokenized_eli5 = eli5.map(
... preprocess_function,
... batched=True,
... num_proc=4,
... remove_columns=eli5["train"].column_names,
... )Bộ dữ liệu này chứa các chuỗi token, nhưng một số chuỗi này dài hơn độ dài đầu vào tối đa của mô hình.
Bạn có thể sử dụng một hàm tiền xử lý thứ hai để
- kết nối tất cả các chuỗi
- chia các chuỗi đã nối thành các đoạn ngắn hơn được xác định bởi
block_size, trong đóblock_sizephải ngắn hơn chiều dài đầu vào tối đa và đủ ngắn để phù hợp với bộ nhớ GPU của bạn.
>>> 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 resultÁp dụng hàm group_texts trên toàn bộ tập dữ liệu:
>>> lm_dataset = tokenized_eli5.map(group_texts, batched=True, num_proc=4)Bây giờ hãy tạo một batch các ví dụ bằng cách sử dụng DataCollatorForLanguageModeling. Việc đệm động các câu đến độ dài dài nhất trong một batch trong quá trình collation sẽ hiệu quả hơn so với việc đệm toàn bộ dataset đến độ dài tối đa.
Sử dụng token kết thúc chuỗi làm token đệm và đặt mlm=False. Thao tác này sẽ dùng các đầu vào làm nhãn được dịch sang phải một phần tử:
>>> from transformers import DataCollatorForLanguageModeling
>>> tokenizer.pad_token = tokenizer.eos_token
>>> data_collator = DataCollatorForLanguageModeling(tokenizer=tokenizer, mlm=False)Huấn luyện
Nếu bạn chưa quen với việc tinh chỉnh mô hình bằng Trainer, hãy xem tutorial cơ bản!
Bạn đã sẵn sàng để bắt đầu huấn luyện mô hình của mình! Hãy nạp DistilGPT2 bằng AutoModelForCausalLM:
>>> from transformers import AutoModelForCausalLM, TrainingArguments, Trainer
>>> model = AutoModelForCausalLM.from_pretrained("distilbert/distilgpt2")Tới bước này, chỉ còn ba bước nữa:
- Định nghĩa các siêu tham số huấn luyện của bạn trong TrainingArguments. Tham số bắt buộc duy nhất là
output_dir, chỉ định nơi lưu trữ mô hình của bạn. Bạn sẽ đẩy mô hình này lên Hub bằng cách đặtpush_to_hub=True(bạn cần đăng nhập vào Hugging Face để tải lên mô hình của mình). - Truyền các đối số huấn luyện vào Trainer cùng với mô hình, các bộ dữ liệu và bộ tổng hợp dữ liệu.
- Gọi train() để tinh chỉnh mô hình của bạn.
>>> 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()Sau khi quá trình huấn luyện hoàn tất, hãy sử dụng phương thức evaluate() để đánh giá mô hình của bạn và lấy độ perplexity của nó:
>>> import math
>>> eval_results = trainer.evaluate()
>>> print(f"Perplexity: {math.exp(eval_results['eval_loss']):.2f}")
Perplexity: 49.61Sau đó, chia sẻ mô hình của bạn lên Hub bằng phương thức push_to_hub() để mọi người có thể sử dụng mô hình của bạn:
>>> trainer.push_to_hub()Để xem một ví dụ chi tiết hơn về cách tinh chỉnh một mô hình cho mô hình hóa ngôn ngữ nhân quả, hãy xem notebook PyTorch tương ứng.
Suy luận
Tuyệt, giờ đây bạn đã tinh chỉnh một mô hình, bạn có thể sử dụng nó để suy luận!
Hãy nghĩ ra một prompt mà bạn muốn dùng để tạo văn bản:
>>> prompt = "Somatic hypermutation allows the immune system to"Cách đơn giản nhất để thử nghiệm mô hình đã tinh chỉnh của bạn cho suy luận là sử dụng nó trong một pipeline(). Khởi tạo một pipeline cho tạo văn bản với mô hình của bạn, và truyền văn bản của bạn vào đó:
>>> 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."}]Chia token văn bản và trả về input_ids dưới dạng tensor PyTorch:
>>> from transformers import AutoTokenizer
>>> tokenizer = AutoTokenizer.from_pretrained("username/my_awesome_eli5_clm-model")
>>> inputs = tokenizer(prompt, return_tensors="pt").input_idsSử dụng phương thức generate() để tạo văn bản. Để biết thêm chi tiết về các chiến lược tạo văn bản khác nhau và các tham số để kiểm soát quá trình tạo, hãy xem trang 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)Giải mã các id token đã tạo thành văn bản:
>>> 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"]