Transformers documentation
Soru yanıtlama
Soru yanıtlama
Soru yanıtlama görevleri, bir soru verildiğinde bir yanıt döndürür. Alexa, Siri veya Google gibi sanlı asistanlara hava durumunu sorduysanız, daha önce bir soru yanıtlama modeli kullanmışsınız demektir. Soru yanıtlama görevlerinin iki yaygın türü vardır:
- Extractive: cevabı verilen bağlamdan çıkarın.
- Abstractive: soruyu doğru şekilde yanıtlayan bir cevabı bağlamdan üretin.
Bu kılavuz size şunları gösterecektir:
- DistilBERT modelini çıkarımsal soru cevaplamada SQuAD veri seti üzerinde ince ayarlayın.
- İnce ayarlanmış modelinizi çıkarım için kullanın.
Bu görevle uyumlu tüm mimarileri ve denetim noktalarını görmek için görev sayfasını kontrol etmenizi öneririz.
Başlamadan önce, gerekli tüm kütüphanelerin yüklendiğinden emin olun:
pip install transformers datasets evaluate
Modelinizi yükleyip toplulukla paylaşabilmeniz için Hugging Face hesabınıza giriş yapmanızı öneririz. İstendiğinde giriş yapmak için token'ınızı girin:
>>> from huggingface_hub import notebook_login
>>> notebook_login()SQuAD veri setini yükle
Önce 🤗 Datasets kütüphanesinden SQuAD veri setinin daha küçük bir alt kümesini yükleyerek başlayın. Bu, tam veri seti üzerinde daha fazla zaman harcayarak eğitimden önce her şeyin çalıştığını doğrulamanız ve deneyler yapmanız için bir fırsat sunar.
>>> from datasets import load_dataset
>>> squad = load_dataset("rajpurkar/squad", split="train[:5000]")Veri setinin train bölümünü train_test_split yöntemiyle eğitim ve test kümesine ayırın:
>>> squad = squad.train_test_split(test_size=0.2)Sonra bir örneğe göz atın:
>>> squad["train"][0]
{'answers': {'answer_start': [515], 'text': ['Saint Bernadette Soubirous']},
'context': 'Architecturally, the school has a Catholic character. Atop the Main Building\'s gold dome is a golden statue of the Virgin Mary. Immediately in front of the Main Building and facing it, is a copper statue of Christ with arms upraised with the legend "Venite Ad Me Omnes". Next to the Main Building is the Basilica of the Sacred Heart. Immediately behind the basilica is the Grotto, a Marian place of prayer and reflection. It is a replica of the grotto at Lourdes, France where the Virgin Mary reputedly appeared to Saint Bernadette Soubirous in 1858. At the end of the main drive (and in a direct line that connects through 3 statues and the Gold Dome), is a simple, modern stone statue of Mary.',
'id': '5733be284776f41900661182',
'question': 'To whom did the Virgin Mary allegedly appear in 1858 in Lourdes France?',
'title': 'University_of_Notre_Dame'
}Burada birkaç önemli alan var:
answers: cevap token'ının başlangıç konumu ve cevap metni.context: Modelin cevabı çıkarması gereken arka plan bilgisi.question: bir modelin yanıtlaması gereken soru.
Ön işleme
Bir sonraki adım, question ve context alanlarını işlemek için bir DistilBERT tokenizer yüklemektir:
>>> from transformers import AutoTokenizer
>>> tokenizer = AutoTokenizer.from_pretrained("distilbert/distilbert-base-uncased")Soru yanıtlama görevlerine özgü, bilmeniz gereken birkaç ön işleme adımı vardır:
- Veri setindeki bazı örnekler, modelin maksimum giriş uzunluğunu aşan çok uzun bir
contextiçerebilir. Daha uzun dizilerle başa çıkmak için yalnızcacontextkısmını kısaltmak üzeretruncation="only_second"ayarını yapın. - Ardından,
return_offset_mapping=Trueayarlayarak cevabın başlangıç ve bitiş konumlarını orijinalcontextile eşleştirin. - Eşlemeyi elde ettikten sonra, artık cevabın başlangıç ve bitiş token'larını bulabilirsiniz.
sequence_idsyöntemini kullanarak, ofsetin hangi kısmınınquestion'a, hangisinin isecontext'e karşılık geldiğini bulun.
answer'ın başlangıç ve bitiş token'larını context'e kırpıp eşleyecek bir fonksiyon oluşturmak için aşağıdaki adımları izleyebilirsiniz:
>>> def preprocess_function(examples):
... questions = [q.strip() for q in examples["question"]]
... inputs = tokenizer(
... questions,
... examples["context"],
... max_length=384,
... truncation="only_second",
... return_offsets_mapping=True,
... padding="max_length",
... )
... offset_mapping = inputs.pop("offset_mapping")
... answers = examples["answers"]
... start_positions = []
... end_positions = []
... for i, offset in enumerate(offset_mapping):
... answer = answers[i]
... start_char = answer["answer_start"][0]
... end_char = answer["answer_start"][0] + len(answer["text"][0])
... sequence_ids = inputs.sequence_ids(i)
... # Find the start and end of the context
... idx = 0
... while sequence_ids[idx] != 1:
... idx += 1
... context_start = idx
... while sequence_ids[idx] == 1:
... idx += 1
... context_end = idx - 1
... # If the answer is not fully inside the context, label it (0, 0)
... if offset[context_start][0] > end_char or offset[context_end][1] < start_char:
... start_positions.append(0)
... end_positions.append(0)
... else:
... # Otherwise it's the start and end token positions
... idx = context_start
... while idx <= context_end and offset[idx][0] <= start_char:
... idx += 1
... start_positions.append(idx - 1)
... idx = context_end
... while idx >= context_start and offset[idx][1] >= end_char:
... idx -= 1
... end_positions.append(idx + 1)
... inputs["start_positions"] = start_positions
... inputs["end_positions"] = end_positions
... return inputsTüm veri setine ön işleme fonksiyonunu uygulamak için 🤗 Datasets map fonksiyonunu kullanın. map fonksiyonunu, veri setinin birden çok öğesini aynı anda işlemek için batched=True değerini ayarlayarak hızlandırabilirsiniz. İhtiyacınız olmayan sütunları kaldırın:
>>> tokenized_squad = squad.map(preprocess_function, batched=True, remove_columns=squad["train"].column_names)Şimdi DefaultDataCollator kullanarak örneklerden oluşan bir batch oluşturun. 🤗 Transformers'taki diğer veri toplayıcıların aksine, DefaultDataCollator padding gibi ek bir ön işleme uygulamaz.
>>> from transformers import DefaultDataCollator
>>> data_collator = DefaultDataCollator()Eğit
Trainer ile bir modeli ince ayar yapma konusunda deneyiminiz yoksa, temel öğreticiyi burada inceleyebilirsiniz!
Artık modelinizi eğitmeye hazırsınız! DistilBERT'i AutoModelForQuestionAnswering ile yükleyin:
>>> from transformers import AutoModelForQuestionAnswering, TrainingArguments, Trainer
>>> model = AutoModelForQuestionAnswering.from_pretrained("distilbert/distilbert-base-uncased")Bu noktada yalnızca üç adım kaldı:
- Eğitim hiperparametrelerinizi TrainingArguments içinde tanımlayın. Tek zorunlu parametre, modelinizi nereye kaydedeceğinizi belirleyen
output_dir'dir. Modelinizi Hub'apush_to_hub=Trueayarlayarak yükleyeceksiniz (modelinizi yüklemek için Hugging Face'e giriş yapmış olmanız gerekir). - Eğitim argümanlarını, model, veri seti, tokenizer ve veri toplayıcı ile birlikte Trainer'a iletin.
- Modelinizi ince ayar yapmak için train() çağrın.
>>> training_args = TrainingArguments(
... output_dir="my_awesome_qa_model",
... eval_strategy="epoch",
... learning_rate=2e-5,
... per_device_train_batch_size=16,
... per_device_eval_batch_size=16,
... num_train_epochs=3,
... weight_decay=0.01,
... push_to_hub=True,
... )
>>> trainer = Trainer(
... model=model,
... args=training_args,
... train_dataset=tokenized_squad["train"],
... eval_dataset=tokenized_squad["test"],
... processing_class=tokenizer,
... data_collator=data_collator,
... )
>>> trainer.train()Eğitim tamamlandıktan sonra, modelinizi herkesin kullanabilmesi için push_to_hub() yöntemiyle Hub'a paylaşın:
>>> trainer.push_to_hub()Bir modeli soru-cevap için ince ayar yapmanın daha ayrıntılı bir örneği için ilgili PyTorch defterine göz atın.
Değerlendir
Soru yanıtlama için değerlendirme, önemli ölçüde bir son işleme gerektirir. Süreci çok uzatmamak için bu kılavuzda değerlendirme adımı atlanır. Trainer, eğitim sırasında değerlendirme kaybını hesaplamaya devam eder; bu sayede modelinizin performansıyla ilgili tamamen bilgi eksikliği yaşamazsınız.
Daha fazla vaktiniz varsa ve modelinizi soru cevaplandırmada nasıl değerlendireceğinizi merak ediyorsanız, 🤗 Hugging Face Kursu'ndaki Soru cevaplandırma bölümüne göz atın!
Çıkarım
Harika, bir model ayarladıktan sonra artık çıkarım için kullanabilirsiniz!
Modelin tahmin etmesini istediğiniz bir soru ve bazı bağlamlar belirleyin:
>>> question = "How many programming languages does BLOOM support?"
>>> context = "BLOOM has 176 billion parameters and can generate text in 46 languages natural languages and 13 programming languages."Metni tokenleştirin ve PyTorch tensörlerini döndürün:
>>> from transformers import AutoTokenizer
>>> tokenizer = AutoTokenizer.from_pretrained("my_awesome_qa_model")
>>> inputs = tokenizer(question, context, return_tensors="pt")Girdilerinizi modele iletin ve logits değerlerini döndürün:
>>> import torch
>>> from transformers import AutoModelForQuestionAnswering
>>> model = AutoModelForQuestionAnswering.from_pretrained("my_awesome_qa_model")
>>> with torch.no_grad():
... outputs = model(**inputs)Başlangıç ve bitiş konumları için model çıktısından en yüksek olasılığı alın:
>>> answer_start_index = outputs.start_logits.argmax()
>>> answer_end_index = outputs.end_logits.argmax()Tahmin edilen jetonları çözümlenerek cevabı alın:
>>> predict_answer_tokens = inputs.input_ids[0, answer_start_index : answer_end_index + 1]
>>> tokenizer.decode(predict_answer_tokens)
'176 billion parameters and can generate text in 46 languages natural languages and 13'