# Belge soru cevaplama

Belge Soru Cevaplama (Document Question Answering), Belge Görsel Soru Cevaplama (Document Visual Question Answering) olarak da adlandırılan, belge görselleriyle ilgili sorulara cevap verilmesini içeren bir görevdir. Bu görevi destekleyen modellere verilen girdi genellikle bir görsel ve bir sorunun birleşimidir ve çıktı, doğal dilde ifade edilen bir cevaptır. Bu modeller; metin, kelimelerin konumları (bounding box'lar) ve görselin kendisi dahil olmak üzere birden çok modaliteyi kullanır.

Bu kılavuz şunları gösterir:

- [LayoutLMv2](../model_doc/layoutlmv2) modelini [DocVQA veri seti](https://huggingface.co/datasets/nielsr/docvqa_1200_examples_donut) üzerinde ince ayar yapın.
- İnce ayarladığınız modeli çı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ı](https://huggingface.co/tasks/image-to-text) kontrol etmenizi öneririz.

LayoutLMv2, belgeler için soru-cevap görevini, tokenların son gizli durumlarının üzerine bir soru-cevap başlığı ekleyerek ve cevabın başlangıç ve bitiş tokenlarının konumlarını tahmin ederek çözer. Başka bir deyişle, problem çıkarımsal soru-cevap olarak ele alınır: bağlam verildiğinde, soruyu cevaplayan bilgi parçası çıkarılır. Bağlam, bir OCR motorunun çıktısından gelir; burada Google'ın Tesseract'ı kullanılmaktadır.

Başlamadan önce, gerekli tüm kütüphanelerin yüklü olduğundan emin olun. LayoutLMv2, detectron2, torchvision ve tesseract'a bağımlıdır.

```bash
pip install -q transformers datasets
```

```bash
pip install 'git+https://github.com/facebookresearch/detectron2.git'
pip install torchvision
```

```bash
sudo apt install tesseract-ocr
pip install -q pytesseract
```

Tüm bağımlılıkları yükledikten sonra çalışma zamanınızı yeniden başlatın.

Modelinizi toplulukla paylaşmanızı öneririz. 🤗 Hub'a yüklemek için Hugging Face hesabınıza giriş yapın. İstendiğinde giriş yapmak için token'ınızı girin:

```py
>>> from huggingface_hub import notebook_login

>>> notebook_login()
```

Bazı global değişkenler tanımlayalım.

```py
>>> model_checkpoint = "microsoft/layoutlmv2-base-uncased"
>>> batch_size = 4
```

## Verileri yükleyin

Bu kılavuzda, 🤗 Hub üzerinde bulabileceğiniz, önceden işlenmiş küçük bir DocVQA örneği kullanıyoruz. Tam DocVQA veri setini kullanmak isterseniz, [DocVQA ana sayfası](https://rrc.cvc.uab.es/?ch=17) üzerinden kayıt oluşturup indirebilirsiniz. Bunu yaparsanız, bu kılavuza devam etmek için [🤗 veri setine dosya yükleme](https://huggingface.co/docs/datasets/loading#local-and-remote-files) konusuna göz atın.

```py
>>> from datasets import load_dataset

>>> dataset = load_dataset("nielsr/docvqa_1200_examples")
>>> dataset
DatasetDict({
    train: Dataset({
        features: ['id', 'image', 'query', 'answers', 'words', 'bounding_boxes', 'answer'],
        num_rows: 1000
    })
    test: Dataset({
        features: ['id', 'image', 'query', 'answers', 'words', 'bounding_boxes', 'answer'],
        num_rows: 200
    })
})
```

Gördüğünüz gibi veri seti zaten eğitim ve test kümelerine ayrılmış durumda. Özellikleri tanıyabilmek için rastgele bir örneğe göz atın.

```py
>>> dataset["train"].features
```

İşte bireysel alanların neyi temsil ettiğine dair açıklama:

* `id`: örneğin kimliği
* `image`: Belge görüntüsünü içeren bir PIL.Image.Image nesnesi
* `query`: soru dizgesi - doğal dilde sorulan soru, birden fazla dilde
* `answers`: insan etiketleyiciler tarafından sağlanan doğru cevapların listesi
* `words` ve `bounding_boxes`: burada kullanmayacağımız OCR sonuçları
* `answer`: burada kullanmayacağımız, farklı bir model tarafından eşleşen bir yanıt

Sadece İngilizce soruları bırakalım ve başka bir modelin tahminlerini içeriyor gibi görünen `answer` özelliğini düşürelim. Ayrıca, etiketleyicilerin sağladığı kümeden cevapların ilkini alacağız. Alternatif olarak, bunu rastgele örnekleyebilirsiniz.

```py
>>> updated_dataset = dataset.map(lambda example: {"question": example["query"]["en"]}, remove_columns=["query"])
>>> updated_dataset = updated_dataset.map(
...     lambda example: {"answer": example["answers"][0]}, remove_columns=["answer", "answers"]
... )
```

Bu kılavuzda kullandığımız LayoutLMv2 checkpoint'inin `max_position_embeddings = 512` ile eğitildiğini unutmayın (bu bilgiyi [checkpoint'in `config.json` dosyasında](https://huggingface.co/microsoft/layoutlmv2-base-uncased/blob/main/config.json#L18) bulabilirsiniz). Örnekleri kırpabiliriz ancak cevabın büyük bir belgenin sonunda yer alıp kırpılmış olma durumunu önlemek için, gömme (embedding) uzunluğunun 512'den uzun olma olasılığı yüksek olan birkaç örneği burada kaldıracağız. Veri setinizdeki belgelerin çoğu uzunsa, kayan pencere (sliding window) stratejisi uygulayabilirsiniz - ayrıntılar için [bu notebook'a](https://github.com/huggingface/notebooks/blob/main/examples/question_answering.ipynb) göz atın.

```py
>>> updated_dataset = updated_dataset.filter(lambda x: len(x["words"]) + len(x["question"].split()) < 512)
```

Bu noktada, bu veri setinden OCR özelliklerini de kaldıralım. Bunlar, farklı bir modelin ince ayarlanması için OCR'den kaynaklanmaktadır. Kullanmak isteseydik yine de bazı işlemler gerektirirlerdi, çünkü bu rehberde kullandığımız modelin girdi gereksinimleriyle eşleşmiyorlar. Bunun yerine, hem OCR hem de tokenizasyon için orijinal veride [LayoutLMv2Processor](/docs/transformers/main/tr/model_doc/layoutlmv2#transformers.LayoutLMv2Processor) kullanabiliriz. Bu sayede, modelin beklediği girdiyle eşleşen girdileri elde ederiz. Görselleri manuel olarak işlemek isterseniz, modelin hangi girdi biçimini beklediğini öğrenmek için [`LayoutLMv2` model dokümantasyonuna](../model_doc/layoutlmv2) göz atın.

```py
>>> updated_dataset = updated_dataset.remove_columns("words")
>>> updated_dataset = updated_dataset.remove_columns("bounding_boxes")
```

Son olarak, bir görüntü örneğine göz atmazsak veri keşfi tamamlanmış sayılmaz.

```py
>>> updated_dataset["train"][11]["image"]
```

     
 

## Verileri ön işleme

Belge Soru Cevaplama görevi çok modallı bir görevdir ve her modaldan gelen girdilerin modelin beklentilerine göre ön işlenmesini sağlamalısınız. Hem görüntü verilerini işleyebilen bir görüntü işleyiciyi hem de metin verilerini kodlayabilen bir belirteçleyiciyi içsel olarak birleştiren [LayoutLMv2Processor](/docs/transformers/main/tr/model_doc/layoutlmv2#transformers.LayoutLMv2Processor)'yi yükleyerek başlayalım.

```py
>>> from transformers import AutoProcessor

>>> processor = AutoProcessor.from_pretrained(model_checkpoint)
```

### Belge görüntülerini ön işleme

Öncelikle, işlemciden gelen `image_processor` yardımıyla model için belge görüntülerini hazırlayalım. Varsayılan olarak görüntü işlemcisi, görüntüleri 224x224 boyutuna yeniden boyutlandırır, renk kanallarının doğru sıralamaya sahip olduğundan emin olur ve kelimeleri ile normalize edilmiş sınırlayıcı kutuları almak için tesseract ile OCR uygular. Bu öğreticide, bu varsayılanların tümüne ihtiyacımız olan şeylerdir. Bir görüntü grubuna varsayılan görüntü işleme uygulayan ve OCR sonuçlarını döndüren bir fonksiyon yazın.

```py
>>> image_processor = processor.image_processor

>>> def get_ocr_words_and_boxes(examples):
...     images = [image.convert("RGB") for image in examples["image"]]
...     encoded_inputs = image_processor(images)

...     examples["image"] = encoded_inputs.pixel_values
...     examples["words"] = encoded_inputs.words
...     examples["boxes"] = encoded_inputs.boxes

...     return examples
```

Bu ön işleme adımını tüm veri setine hızlı bir şekilde uygulamak için [map](https://huggingface.co/docs/datasets/main/en/package_reference/main_classes#datasets.Dataset.map) kullanın.

```py
>>> dataset_with_ocr = updated_dataset.map(get_ocr_words_and_boxes, batched=True, batch_size=2)
```

### Metin verilerini ön işleme

Görsellere OCR uygulandıktan sonra, modeli hazırlamak için veri setinin metin kısmını kodlamamız gerekir. Bu, önceki adımda elde ettiğimiz kelimeleri ve kutuları token düzeyinde `input_ids`, `attention_mask`, `token_type_ids` ve `bbox` olarak dönüştürmeyi içerir. Metni ön işlemek için işlemciden `tokenizer` kullanmamız gerekecektir.

```py
>>> tokenizer = processor.tokenizer
```

Yukarıda bahsedilen ön işlemlerin yanı sıra, modele etiketleri de eklememiz gerekir. 🤗 Transformers'taki `xxxForQuestionAnswering` modellerinde etiketler, cevabın başlangıcındaki ve sonundaki token'ı gösteren `start_positions` ve `end_positions` değerlerinden oluşur.

Bununla başlayalım. Daha büyük bir listede (kelimeler listesi) bir alt liste bulabilen (kelimelere ayrılmış cevap) bir yardımcı fonksiyon tanımlayın.

This function will take two lists as input, `words_list` and `answer_list`. It will then iterate over the `words_list` and check if the current word in the `words_list` (words_list[i]) is equal to the first word of answer_list (answer_list[0]) and if the sublist of `words_list` starting from the current word and of the same length as `answer_list` is equal `to answer_list`. If this condition is true, it means that a match has been found, and the function will record the match, its starting index (idx), and its ending index (idx + len(answer_list) - 1). If more than one match was found, the function will return only the first one. If no match is found, the function returns (`None`, 0, and 0).

```py
>>> def subfinder(words_list, answer_list):
...     matches = []
...     start_indices = []
...     end_indices = []
...     for idx, i in enumerate(range(len(words_list))):
...         if words_list[i] == answer_list[0] and words_list[i : i + len(answer_list)] == answer_list:
...             matches.append(answer_list)
...             start_indices.append(idx)
...             end_indices.append(idx + len(answer_list) - 1)
...     if matches:
...         return matches[0], start_indices[0], end_indices[0]
...     else:
...         return None, 0, 0
```

Bu fonksiyonun cevabın konumunu nasıl bulduğunu göstermek için bir örnekte kullanalım:

```py
>>> example = dataset_with_ocr["train"][1]
>>> words = [word.lower() for word in example["words"]]
>>> match, word_idx_start, word_idx_end = subfinder(words, example["answer"].lower().split())
>>> print("Question: ", example["question"])
>>> print("Words:", words)
>>> print("Answer: ", example["answer"])
>>> print("start_index", word_idx_start)
>>> print("end_index", word_idx_end)
Question:  Who is in  cc in this letter?
Words: ['wie', 'baw', 'brown', '&', 'williamson', 'tobacco', 'corporation', 'research', '&', 'development', 'internal', 'correspondence', 'to:', 'r.', 'h.', 'honeycutt', 'ce:', 't.f.', 'riehl', 'from:', '.', 'c.j.', 'cook', 'date:', 'may', '8,', '1995', 'subject:', 'review', 'of', 'existing', 'brainstorming', 'ideas/483', 'the', 'major', 'function', 'of', 'the', 'product', 'innovation', 'graup', 'is', 'to', 'develop', 'marketable', 'nove!', 'products', 'that', 'would', 'be', 'profitable', 'to', 'manufacture', 'and', 'sell.', 'novel', 'is', 'defined', 'as:', 'of', 'a', 'new', 'kind,', 'or', 'different', 'from', 'anything', 'seen', 'or', 'known', 'before.', 'innovation', 'is', 'defined', 'as:', 'something', 'new', 'or', 'different', 'introduced;', 'act', 'of', 'innovating;', 'introduction', 'of', 'new', 'things', 'or', 'methods.', 'the', 'products', 'may', 'incorporate', 'the', 'latest', 'technologies,', 'materials', 'and', 'know-how', 'available', 'to', 'give', 'then', 'a', 'unique', 'taste', 'or', 'look.', 'the', 'first', 'task', 'of', 'the', 'product', 'innovation', 'group', 'was', 'to', 'assemble,', 'review', 'and', 'categorize', 'a', 'list', 'of', 'existing', 'brainstorming', 'ideas.', 'ideas', 'were', 'grouped', 'into', 'two', 'major', 'categories', 'labeled', 'appearance', 'and', 'taste/aroma.', 'these', 'categories', 'are', 'used', 'for', 'novel', 'products', 'that', 'may', 'differ', 'from', 'a', 'visual', 'and/or', 'taste/aroma', 'point', 'of', 'view', 'compared', 'to', 'canventional', 'cigarettes.', 'other', 'categories', 'include', 'a', 'combination', 'of', 'the', 'above,', 'filters,', 'packaging', 'and', 'brand', 'extensions.', 'appearance', 'this', 'category', 'is', 'used', 'for', 'novel', 'cigarette', 'constructions', 'that', 'yield', 'visually', 'different', 'products', 'with', 'minimal', 'changes', 'in', 'smoke', 'chemistry', 'two', 'cigarettes', 'in', 'cne.', 'emulti-plug', 'te', 'build', 'yaur', 'awn', 'cigarette.', 'eswitchable', 'menthol', 'or', 'non', 'menthol', 'cigarette.', '*cigarettes', 'with', 'interspaced', 'perforations', 'to', 'enable', 'smoker', 'to', 'separate', 'unburned', 'section', 'for', 'future', 'smoking.', '«short', 'cigarette,', 'tobacco', 'section', '30', 'mm.', '«extremely', 'fast', 'buming', 'cigarette.', '«novel', 'cigarette', 'constructions', 'that', 'permit', 'a', 'significant', 'reduction', 'iretobacco', 'weight', 'while', 'maintaining', 'smoking', 'mechanics', 'and', 'visual', 'characteristics.', 'higher', 'basis', 'weight', 'paper:', 'potential', 'reduction', 'in', 'tobacco', 'weight.', '«more', 'rigid', 'tobacco', 'column;', 'stiffing', 'agent', 'for', 'tobacco;', 'e.g.', 'starch', '*colored', 'tow', 'and', 'cigarette', 'papers;', 'seasonal', 'promotions,', 'e.g.', 'pastel', 'colored', 'cigarettes', 'for', 'easter', 'or', 'in', 'an', 'ebony', 'and', 'ivory', 'brand', 'containing', 'a', 'mixture', 'of', 'all', 'black', '(black', 'paper', 'and', 'tow)', 'and', 'ail', 'white', 'cigarettes.', '499150498']
Answer:  T.F. Riehl
start_index 17
end_index 18
```

Ancak örnekler kodlandıktan sonra, bu şekilde görüneceklerdir:

```py
>>> encoding = tokenizer(example["question"], example["words"], example["boxes"])
>>> tokenizer.decode(encoding["input_ids"])
[CLS] who is in cc in this letter? [SEP] wie baw brown & williamson tobacco corporation research & development ...
```

Kodlanmış girdide cevabın konumunu bulmamız gerekecek.

* `token_type_ids`, hangi tokenların sorunun, hangilerinin ise belgenin kelimelerinin parçası olduğunu bize söyler.
* `tokenizer.cls_token_id`, girdinin başındaki özel token'ı bulmanıza yardımcı olacaktır.
* `word_ids`, orijinal `words` içinde bulunan cevabı, tam kodlanmış girdideki aynı cevapla eşleştirmeye ve belirlemeye yardımcı olur
kodlanmış girdide cevabın başlangıç/bitiş konumu.

Bu düşünceyle, veri setindeki örneklerin bir partisini kodlamak için bir oluşturalım:

```py
>>> def encode_dataset(examples, max_length=512):
...     questions = examples["question"]
...     words = examples["words"]
...     boxes = examples["boxes"]
...     answers = examples["answer"]

...     # encode the batch of examples and initialize the start_positions and end_positions
...     encoding = tokenizer(questions, words, boxes, max_length=max_length, padding="max_length", truncation=True)
...     start_positions = []
...     end_positions = []

...     # loop through the examples in the batch
...     for i in range(len(questions)):
...         cls_index = encoding["input_ids"][i].index(tokenizer.cls_token_id)

...         # find the position of the answer in example's words
...         words_example = [word.lower() for word in words[i]]
...         answer = answers[i]
...         match, word_idx_start, word_idx_end = subfinder(words_example, answer.lower().split())

...         if match:
...             # if match is found, use `token_type_ids` to find where words start in the encoding
...             token_type_ids = encoding["token_type_ids"][i]
...             token_start_index = 0
...             while token_type_ids[token_start_index] != 1:
...                 token_start_index += 1

...             token_end_index = len(encoding["input_ids"][i]) - 1
...             while token_type_ids[token_end_index] != 1:
...                 token_end_index -= 1

...             word_ids = encoding.word_ids(i)[token_start_index : token_end_index + 1]
...             start_position = cls_index
...             end_position = cls_index

...             # loop over word_ids and increase `token_start_index` until it matches the answer position in words
...             # once it matches, save the `token_start_index` as the `start_position` of the answer in the encoding
...             for id in word_ids:
...                 if id == word_idx_start:
...                     start_position = token_start_index
...                 else:
...                     token_start_index += 1

...             # similarly loop over `word_ids` starting from the end to find the `end_position` of the answer
...             for id in word_ids[::-1]:
...                 if id == word_idx_end:
...                     end_position = token_end_index
...                 else:
...                     token_end_index -= 1

...             start_positions.append(start_position)
...             end_positions.append(end_position)

...         else:
...             start_positions.append(cls_index)
...             end_positions.append(cls_index)

...     encoding["image"] = examples["image"]
...     encoding["start_positions"] = start_positions
...     encoding["end_positions"] = end_positions

...     return encoding
```

Bu ön işleme fonksiyonuna sahip olduğumuza göre, tüm veri setini kodlayabiliriz:

```py
>>> encoded_train_dataset = dataset_with_ocr["train"].map(
...     encode_dataset, batched=True, batch_size=2, remove_columns=dataset_with_ocr["train"].column_names
... )
>>> encoded_test_dataset = dataset_with_ocr["test"].map(
...     encode_dataset, batched=True, batch_size=2, remove_columns=dataset_with_ocr["test"].column_names
... )
```

Kodlanmış veri setinin özelliklerinin nasıl göründüğünü kontrol edelim:

```py
>>> encoded_train_dataset.features
{'image': Sequence(feature=Sequence(feature=Sequence(feature=Value(dtype='uint8', id=None), length=-1, id=None), length=-1, id=None), length=-1, id=None),
 'input_ids': Sequence(feature=Value(dtype='int32', id=None), length=-1, id=None),
 'token_type_ids': Sequence(feature=Value(dtype='int8', id=None), length=-1, id=None),
 'attention_mask': Sequence(feature=Value(dtype='int8', id=None), length=-1, id=None),
 'bbox': Sequence(feature=Sequence(feature=Value(dtype='int64', id=None), length=-1, id=None), length=-1, id=None),
 'start_positions': Value(dtype='int64', id=None),
 'end_positions': Value(dtype='int64', id=None)}
```

## Değerlendirme

Belge soru-cevap için değerlendirme, önemli miktarda son işlem gerektirir. Süreci çok uzatmamak için bu kılavuzda değerlendirme adımı atlanmıştır. [Trainer](/docs/transformers/main/tr/main_classes/trainer#transformers.Trainer), eğitim sırasında değerlendirme kaybını hesaplamaya devam eder, bu sayede modelinizin performansıyla ilgili tamamen karanlıkta kalmazsınız. Çıkarımsal soru-cevap genellikle F1/tam eşleşme ile değerlendirilir. Kendiniz uygulamak isterseniz ilham almak için Hugging Face kursunun [Soru-Cevap bölümüne](https://huggingface.co/course/chapter7/7?fw=pt#postprocessing) göz atabilirsiniz.

## Eğit

Tebrikler! Bu kılavuzun en zorlu kısmını başarıyla tamamladınız ve artık kendi modelinizi eğitmeye hazırsınız. Eğitim aşağıdaki adımları içerir:

* Modeli, ön işlemede kullanılan aynı kontrol noktasıyla [AutoModelForDocumentQuestionAnswering](/docs/transformers/main/tr/model_doc/auto#transformers.AutoModelForDocumentQuestionAnswering) kullanarak yükleyin.
* Eğitim hiperparametrelerinizi [TrainingArguments](/docs/transformers/main/tr/main_classes/trainer#transformers.TrainingArguments) içinde tanımlayın.
* Örnekleri toplu halde işleyecek bir fonksiyon tanımlayın; burada [DefaultDataCollator](/docs/transformers/main/tr/main_classes/data_collator#transformers.DefaultDataCollator) gayet yeterli olacaktır.
* Eğitim argümanlarını, model, veri seti ve veri toplayıcıyla birlikte [Trainer](/docs/transformers/main/tr/main_classes/trainer#transformers.Trainer)'a iletin.
* Modelinizi ince ayar yapmak için [train()](/docs/transformers/main/tr/main_classes/trainer#transformers.Trainer.train) çağrın.

```py
>>> from transformers import AutoModelForDocumentQuestionAnswering

>>> model = AutoModelForDocumentQuestionAnswering.from_pretrained(model_checkpoint)
```

[TrainingArguments](/docs/transformers/main/tr/main_classes/trainer#transformers.TrainingArguments) içinde modelinizi nereye kaydedeceğinizi belirtmek için `output_dir` kullanın ve hiperparametreleri uygun gördüğünüz şekilde yapılandırın. Modelinizi toplulukla paylaşmak istiyorsanız `push_to_hub` değerini `True` olarak ayarlayın (modelinizi yüklemek için Hugging Face hesabına giriş yapmış olmanız gerekir). Bu durumda `output_dir`, model kontrol noktanızın yükleneceği depoyu da adlandırır.

```py
>>> from transformers import TrainingArguments

>>> # REPLACE THIS WITH YOUR REPO ID
>>> repo_id = "MariaK/layoutlmv2-base-uncased_finetuned_docvqa"

>>> training_args = TrainingArguments(
...     output_dir=repo_id,
...     per_device_train_batch_size=4,
...     num_train_epochs=20,
...     save_steps=200,
...     logging_steps=50,
...     eval_strategy="steps",
...     learning_rate=5e-5,
...     save_total_limit=2,
...     remove_unused_columns=False,
...     push_to_hub=True,
... )
```

Örnekleri toplu olarak gruplamak için basit bir veri toplayıcı (data collator) tanımlayın.

```py
>>> from transformers import DefaultDataCollator

>>> data_collator = DefaultDataCollator()
```

Son olarak, her şeyi bir araya getirin ve [train()](/docs/transformers/main/tr/main_classes/trainer#transformers.Trainer.train) çağrısını yapın:

```py
>>> from transformers import Trainer

>>> trainer = Trainer(
...     model=model,
...     args=training_args,
...     data_collator=data_collator,
...     train_dataset=encoded_train_dataset,
...     eval_dataset=encoded_test_dataset,
...     processing_class=processor,
... )

>>> trainer.train()
```

Son modeli 🤗 Hub'a eklemek için bir model kartı oluşturun ve `push_to_hub` çağrısını yapın:

```py
>>> trainer.create_model_card()
>>> trainer.push_to_hub()
```

## Çıkarım

Artık bir LayoutLMv2 modelini ince ayarladınız ve 🤗 Hub'a yüklediniz; bu modeli çıkarım (inference) için kullanabilirsiniz. İnce ayarlanmış modelinizi çıkarım için denemenin en basit yolu, onu bir [Pipeline](/docs/transformers/main/tr/main_classes/pipelines#transformers.Pipeline) içinde kullanmaktır.

Bir örnek üzerinden gidelim:

```py
>>> example = dataset["test"][2]
>>> question = example["query"]["en"]
>>> image = example["image"]
>>> print(question)
>>> print(example["answers"])
'Who is ‘presiding’ TRRF GENERAL SESSION (PART 1)?'
['TRRF Vice President', 'lee a. waller']
```

Ardından, modelinizle belge soru-cevap için bir pipeline örneği oluşturun ve görsel + soru kombinasyonunu ona iletin.

```py
>>> from transformers import pipeline

>>> qa_pipeline = pipeline("document-question-answering", model="MariaK/layoutlmv2-base-uncased_finetuned_docvqa")
>>> qa_pipeline(image, question)
[{'score': 0.9949808120727539,
  'answer': 'Lee A. Waller',
  'start': 55,
  'end': 57}]
```

İsterseniz, pipeline sonuçlarını manuel olarak da yeniden üretebilirsiniz:

1. Bir görüntü ve bir soru alın ve bunları, modelinizden gelen processor kullanarak modele hazırlayın.
2. Sonucu veya ön işleme adımını modele iletin.
3. Model, `start_logits` ve `end_logits` değerlerini döndürür; bunlar, cevabın başlangıcında hangi tokenın
cevabın sonunda hangi tokenın olduğu. İkisinin de şekli (batch_size, sequence_length) şeklindedir.
4. `start_logits` ve `end_logits` dizilerinin son boyutunda argmax alarak tahmini `start_idx` ve `end_idx` değerlerini elde edin.
5. Cevabı tokenizer ile çözümlen.

```py
>>> import torch
>>> from transformers import AutoProcessor
>>> from transformers import AutoModelForDocumentQuestionAnswering

>>> processor = AutoProcessor.from_pretrained("MariaK/layoutlmv2-base-uncased_finetuned_docvqa")
>>> model = AutoModelForDocumentQuestionAnswering.from_pretrained("MariaK/layoutlmv2-base-uncased_finetuned_docvqa")

>>> with torch.no_grad():
...     encoding = processor(image.convert("RGB"), question, return_tensors="pt")
...     outputs = model(**encoding)
...     start_logits = outputs.start_logits
...     end_logits = outputs.end_logits
...     predicted_start_idx = start_logits.argmax(-1).item()
...     predicted_end_idx = end_logits.argmax(-1).item()

>>> processor.tokenizer.decode(encoding.input_ids.squeeze()[predicted_start_idx : predicted_end_idx + 1])
'lee a. waller'
```

