# Üretim stratejileri

Bir çözümleme stratejisi, bir modelin bir sonraki üretilen token'ı nasıl seçmesi gerektiğini belirler. Çözümleme stratejilerinin birçok türü vardır ve uygun olanı seçmek, üretilen metnin kalitesi üzerinde önemli bir etkiye sahiptir.

Bu kılavuz, Transformers içindeki farklı çözümleme stratejilerini ve bunların nasıl ve ne zaman kullanılacağını anlamanıza yardımcı olacaktır.

## Temel çözümleme yöntemleri

Bunlar iyi yerleşmiş çözümleme yöntemleridir ve metin üretimi görevleri için başlangıç noktanız olmalıdır.

### Açgözlü arama

Greedy search, varsayılan çözümleme stratejisidir. Her adımda bir sonraki en olası token'ı seçer. [GenerationConfig](/docs/transformers/main/tr/main_classes/text_generation#transformers.GenerationConfig)'de aksi belirtilmedikçe, bu strateji en fazla 20 yeni token üretir.

Greedy search, yaratıcılığın öncelikli olmadığı ve çıktılarının nispeten kısa olduğu görevlerde iyi çalışır. Ancak, daha uzun diziler üretirken kendini tekrarlamaya başladığı için işlevini yitirir.

```py
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
from accelerate import Accelerator

device = Accelerator().device

tokenizer = AutoTokenizer.from_pretrained("meta-llama/Llama-2-7b-hf")
inputs = tokenizer("Hugging Face is an open-source company", return_tensors="pt").to(device)

model = AutoModelForCausalLM.from_pretrained("meta-llama/Llama-2-7b-hf", dtype=torch.float16).to(device)
# explicitly set to default length because Llama2 generation length is 4096
outputs = model.generate(**inputs, max_new_tokens=20)
tokenizer.batch_decode(outputs, skip_special_tokens=True)
'Hugging Face is an open-source company that provides a suite of tools and services for building, deploying, and maintaining natural language processing'
```

### Örnekleme

Örnekleme (sampling) veya çok terimli örnekleme (multinomial sampling), modelin tüm sözlüğü üzerindeki olasılık dağılımına dayanarak rastgele bir belirteç seçer (açgözlü aramada olduğu gibi en olası belirteç yerine). Bu, sıfırdan farklı bir olasılığa sahip olan her belirtecin seçilme şansı olduğu anlamına gelir. Örnekleme stratejileri tekrarı azaltır ve daha yaratıcı, çeşitli çıktılar üretebilir.

Çok terimli örneklemeyi `do_sample=True` ve `num_beams=1` ile etkinleştirin.

```py
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
from accelerate import Accelerator

device = Accelerator().device

tokenizer = AutoTokenizer.from_pretrained("meta-llama/Llama-2-7b-hf")
inputs = tokenizer("Hugging Face is an open-source company", return_tensors="pt").to(device)

model = AutoModelForCausalLM.from_pretrained("meta-llama/Llama-2-7b-hf", dtype=torch.float16).to(device)
# explicitly set to 100 because Llama2 generation length is 4096
outputs = model.generate(**inputs, max_new_tokens=50, do_sample=True, num_beams=1)
tokenizer.batch_decode(outputs, skip_special_tokens=True)
'Hugging Face is an open-source company 🤗\nWe are open-source and believe that open-source is the best way to build technology. Our mission is to make AI accessible to everyone, and we believe that open-source is the best way to achieve that.'
```

### Beam araması

Beam search, her zaman adımında birden fazla üretilmiş diziyi (beam) takip eder. Belirli sayıda adımın ardından, en yüksek *genel* olasılığa sahip diziyi seçer. Açgözlü aramanın aksine, bu strateji "ileriye bakabilir" ve başlangıç token'larının olasılığı daha düşük olsa bile, genel olarak daha yüksek olasılığa sahip bir dizi seçebilir. Bir görüntüyü betimleme veya konuşma tanıma gibi girdiye dayalı görevler için en uygun yöntemdir. Her adımda örneklem almak için beam search ile `do_sample=True` parametresini de kullanabilirsiniz; ancak beam search, adımlar arasında düşük olasılıklı dizileri yine de açgözlü bir şekilde eleyecektir.

> [!TIP]
> Beam search'ın nasıl çalıştığını görmek için [beam search görselleştiricisine](https://huggingface.co/spaces/m-ric/beam_search_visualizer) göz atın.

`num_beams` parametresiyle beam search etkinleştirin (1'den büyük olmalıdır, aksi takdirde greedy search ile eşdeğerdir).

```py
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
from accelerate import Accelerator

device = Accelerator().device

tokenizer = AutoTokenizer.from_pretrained("meta-llama/Llama-2-7b-hf")
inputs = tokenizer("Hugging Face is an open-source company", return_tensors="pt").to(device)

model = AutoModelForCausalLM.from_pretrained("meta-llama/Llama-2-7b-hf", dtype=torch.float16).to(device)
# explicitly set to 100 because Llama2 generation length is 4096
outputs = model.generate(**inputs, max_new_tokens=50, num_beams=2)
tokenizer.batch_decode(outputs, skip_special_tokens=True)
"['Hugging Face is an open-source company that develops and maintains the Hugging Face platform, which is a collection of tools and libraries for building and deploying natural language processing (NLP) models. Hugging Face was founded in 2018 by Thomas Wolf']"
```

## Özel üretim yöntemleri

Özel üretim yöntemleri, aşağıdaki gibi özel davranışlar sağlar:

- belirsizse modelin düşünmeye devam etmesini sağlar;
- model takılırsa üretimi geri alın;
- özel jetonları özel mantıkla işleyin;
- özel KV önbellekleri kullanın;

Model depoları aracılığıyla özel üretim yöntemlerini etkinleştiriyoruz; bunun için belirli bir model etiketi ve dosya yapısı varsayılır (aşağıdaki alt bölümü bkz.). Bu özellik, [özel modelleme kodunun](./models#custom-models) bir uzantısıdır ve benzer şekilde `trust_remote_code=True` ayarını gerektirir.

Bir model deposu özel bir üretim yöntemi içeriyorsa, bunu denemenin en kolay yolu modeli yükleyip onunla üretim yapmaktır:

```py
from transformers import AutoModelForCausalLM, AutoTokenizer

# `transformers-community/custom_generate_example` holds a copy of `Qwen/Qwen2.5-0.5B-Instruct`, but
# with custom generation code -> calling `generate` uses the custom generation method!
tokenizer = AutoTokenizer.from_pretrained("transformers-community/custom_generate_example")
model = AutoModelForCausalLM.from_pretrained(
    "transformers-community/custom_generate_example", device_map="auto", trust_remote_code=True
)

inputs = tokenizer(["The quick brown"], return_tensors="pt").to(model.device)
# The custom generation method is a minimal greedy decoding implementation. It also prints a custom message at run time.
gen_out = model.generate(**inputs)
# you should now see its custom message, "✨ using a custom generation method ✨"
print(tokenizer.batch_decode(gen_out, skip_special_tokens=True))
'The quick brown fox jumps over a lazy dog, and the dog is a type of animal. Is'
```

Özel üretim yöntemlerine sahip model depolarının özel bir özelliği vardır: üretim yöntemi, [generate()](/docs/transformers/main/tr/main_classes/text_generation#transformers.GenerationMixin.generate)'nin `custom_generate` argümanı aracılığıyla **herhangi** bir modelden yüklenebilir. Bu, kullanıcıların ek Python paketleri kurmasına gerek kalmadan, özel üretim yönteminin herhangi bir Transformers modeliyle çalışacak şekilde oluşturulup paylaşılabilmesi anlamına gelir.

```py
from transformers import AutoModelForCausalLM, AutoTokenizer

tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen2.5-0.5B-Instruct")
model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen2.5-0.5B-Instruct", device_map="auto")

inputs = tokenizer(["The quick brown"], return_tensors="pt").to(model.device)
# `custom_generate` replaces the original `generate` by the custom generation method defined in
# `transformers-community/custom_generate_example`
gen_out = model.generate(**inputs, custom_generate="transformers-community/custom_generate_example", trust_remote_code=True)
print(tokenizer.batch_decode(gen_out, skip_special_tokens=True)[0])
'The quick brown fox jumps over a lazy dog, and the dog is a type of animal. Is'
```

Özel üretim stratejisini içeren depodaki `README.md` dosyasını okuyarak, varsa yeni argümanların ve çıktı türü farklarının neler olduğunu görmelisiniz. Aksi takdirde, temel [generate()](/docs/transformers/main/tr/main_classes/text_generation#transformers.GenerationMixin.generate) metodu gibi çalıştığını varsayabilirsiniz.

> [!TIP]
> Tüm özel üretim yöntemlerini [özel etiketlerini](https://huggingface.co/models?other=custom_generate), `custom_generate`, aratarak bulabilirsiniz.

Örnek olarak [transformers-community/custom_generate_example](https://huggingface.co/transformers-community/custom_generate_example) Hub deposunu ele alalım. `README.md` dosyasında, prompttan önce belirli sayıda dolgu (padding) tokenı ekleyen `left_padding` adlı ek bir girdi argümanı olduğu belirtilmektedir.

```py
gen_out = model.generate(
    **inputs, custom_generate="transformers-community/custom_generate_example", trust_remote_code=True, left_padding=5
)
print(tokenizer.batch_decode(gen_out)[0])
'<|endoftext|><|endoftext|><|endoftext|><|endoftext|><|endoftext|>The quick brown fox jumps over the lazy dog.\n\nThe sentence "The quick'
```

Özel yöntem, ortamınızın karşılamadığı sabitlenmiş Python gereksinimleri içeriyorsa, eksik gereksinimlere ilişkin bir istisna alırsınız. Örneğin, [transformers-community/custom_generate_bad_requirements](https://huggingface.co/transformers-community/custom_generate_bad_requirements) adlı yöntemde `custom_generate/requirements.txt` dosyasında imkânsız bir gereksinim seti tanımlanmıştır ve bu yöntemi çalıştırmaya çalışırsanız aşağıdaki hata mesajını görürsünüz.

```text
ImportError: Missing requirements in your local environment for `transformers-community/custom_generate_bad_requirements`:
foo (installed: None)
bar==0.0.0 (installed: None)
torch>=99.0 (installed: 2.6.0)
```

Bu hata mesajını kaldırmak için Python gereksinimlerinizi buna göre güncelleyin.

### Özel bir üretim yöntemi oluşturma

Yeni bir üretim yöntemi oluşturmak için yeni bir [**Model**](https://huggingface.co/new) deposu oluşturup içine birkaç dosya göndermeniz gerekir.

1. Üretim yönteminizi tasarladığınız model.
2. Özel üretim yönteminiz için tüm mantığı içeren `custom_generate/generate.py`.
3. `custom_generate/requirements.txt`, yönteminizi doğru şekilde kullanmak için yeni Python gereksinimlerini isteğe bağlı olarak eklemek ve/veya belirli sürümleri kilitlemek için kullanılır.
4. `README.md` dosyasına `custom_generate` etiketini eklemeli ve özel yönteminizin yeni argümanlarını veya çıktı türü farklarını burada belgelemelisiniz.

Tüm gerekli dosyaları ekledikten sonra, deponuz aşağıdaki gibi görünmelidir

```text
your_repo/
├── README.md          # include the 'custom_generate' tag
├── config.json
├── ...
└── custom_generate/
    ├── generate.py
    └── requirements.txt
```

#### Temel modelin eklenmesi

Özel üretim yönteminiz için başlangıç noktası, diğer tüm model depoları gibi bir model deposudur. Bu depoya eklenecek model, yönteminizi tasarladığınız model olmalı ve işlevsel, kendi içinde tam bir model-üretim çiftinin parçası olarak tasarlanmalıdır. Bu depodaki model yüklendiğinde, özel üretim yönteminiz `generate` işlevinin üzerine yazılır. Endişelenmeyin -- yukarıdaki bölümde açıklandığı gibi, üretim yönteminiz hâlâ Transformers'daki herhangi bir başka modelle yüklenebilir.

Mevcut bir modeli kopyalamak istiyorsanız, bunu

```py
from transformers import AutoModelForCausalLM, AutoTokenizer

tokenizer = AutoTokenizer.from_pretrained("source/model_repo")
model = AutoModelForCausalLM.from_pretrained("source/model_repo")
tokenizer.save_pretrained("your/generation_method", push_to_hub=True)
model.save_pretrained("your/generation_method", push_to_hub=True)
```

#### generate.py

Bu, üretim yönteminizin çekirdeğidir. *mutlaka* `generate` adında bir yöntem içermelidir ve bu yöntem *mutlaka* ilk argümanı olarak bir `model` argümanı içermelidir. `model`, model örneğidir; bu da modeldeki tüm özniteliklere ve yöntemlere, [GenerationMixin](/docs/transformers/main/tr/main_classes/text_generation#transformers.GenerationMixin) içinde tanımlananlar (temel `generate` yöntemi gibi) dahil olmak üzere erişiminiz olduğu anlamına gelir.

> [!WARNING]
> `generate.py` dosyası, depoyun kök dizininde değil, `custom_generate` adlı bir klasörün içinde bulunmalıdır. Bu özellik için dosya yolları sabitlenmiştir.

Arka planda, temel [generate()](/docs/transformers/main/tr/main_classes/text_generation#transformers.GenerationMixin.generate) metodu bir `custom_generate` argümanı ile çağrıldığında, önce Python gereksinimlerini (varsa) kontrol eder, ardından özel `generate` metodunu `generate.py` içinde bulur ve son olarak özel `generate` metodunu çağırır. Alınan tüm argümanlar ve `model`, özel üretimi tetiklemek için kullanılan argümanlar (`trust_remote_code` ve `custom_generate`) hariç olmak üzere, sizin özel `generate` metodunuza iletilir.

Bu, aşağıda gösterildiği gibi `generate` fonksiyonunuzun orijinal ve özel argümanların (ayrıca farklı bir çıktı türünün) bir karışımına sahip olabileceği anlamına gelir.

```py
import torch

def generate(model, input_ids, generation_config=None, left_padding=None, **kwargs):
    generation_config = generation_config or model.generation_config  # default to the model generation config
    cur_length = input_ids.shape[1]
    max_length = generation_config.max_length or cur_length + generation_config.max_new_tokens

    # Example of custom argument: add `left_padding` (integer) pad tokens before the prompt
    if left_padding is not None:
        if not isinstance(left_padding, int) or left_padding < 0:
            raise ValueError(f"left_padding must be an integer larger than 0, but is {left_padding}")

        pad_token = kwargs.pop("pad_token", None) or generation_config.pad_token_id or model.config.pad_token_id
        if pad_token is None:
            raise ValueError("pad_token is not defined")
        batch_size = input_ids.shape[0]
        pad_tensor = torch.full(size=(batch_size, left_padding), fill_value=pad_token).to(input_ids.device)
        input_ids = torch.cat((pad_tensor, input_ids), dim=1)
        cur_length = input_ids.shape[1]

    # Simple greedy decoding loop
    while cur_length < max_length:
        logits = model(input_ids).logits
        next_token_logits = logits[:, -1, :]
        next_tokens = torch.argmax(next_token_logits, dim=-1)
        input_ids = torch.cat((input_ids, next_tokens[:, None]), dim=-1)
        cur_length += 1

    return input_ids
```

Özel üretim yönteminizin beklenildiği gibi çalışmasını sağlamak için aşağıdaki önerilen uygulamaları izleyin.

- Orijinal [generate()](/docs/transformers/main/tr/main_classes/text_generation#transformers.GenerationMixin.generate) içindeki doğrulama ve girdi hazırlama mantığını yeniden kullanmaktan çekinmeyin.
- `model` içinde herhangi bir özel yöntem/özellik kullanıyorsanız, gereksinimlerde `transformers` sürümünü sabitleyin.
- Kullanıcıların kodunuzu kendi ortamlarında doğrulamalarına yardımcı olmak için model doğrulama, girdi doğrulama veya hatta ayrı bir test dosyası eklemeyi düşünün.

Özel `generate` yönteminiz, `custom_generate` klasöründen göreli olarak kod içe aktarabilir. Örneğin, bir `utils.py` dosyanız varsa, bunu şu şekilde içe aktarabilirsiniz:

```py
from .utils import some_function
```

Yalnızca aynı seviyedeki `custom_generate` klasöründen göreli içe aktarmalar desteklenir. Üst/dizin klasör içe aktarmaları geçerli değildir. `custom_generate` argümanı, `custom_generate` yapısını içeren herhangi bir dizinle yerel olarak da çalışır; bu, özel üretim yönteminizi geliştirmek için önerilen iş akışıdır.

```py
gen_out = model.generate(**inputs, custom_generate="path/to/local/dir", trust_remote_code=True)
```

> [!WARNING]
> Yerel bir dizin yüklenirken yine `custom_generate/generate.py` çalıştırılır; bu nedenle bir Hub deposu gibi `trust_remote_code=True` gerektirir. `trust_remote_code=True` parametresini yalnızca kendiniz yazdığınız veya incelediğiniz kod için iletin.

#### requirements.txt

`custom_generate` klasörünün içinde bir `requirements.txt` dosyasında ek Python gereksinimlerini isteğe bağlı olarak belirleyebilirsiniz. Bu gereksinimler çalışma zamanında denetlenir ve eksiklerse bir istisna fırlatılır; bu da kullanıcıların ortamlarını buna göre güncellemeleri yönünde bir uyarı niteliği taşır.

#### README.md

Model deposundaki kök seviyedeki `README.md` dosyası genellikle içindeki modeli açıklar. Ancak, deponun odağı özel üretim yöntemi olduğundan, odağını özel üretim yöntemini açıklamaya kaydırmanızı şiddetle öneririz. Yöntemin açıklamasının yanı sıra, orijinal [generate()](/docs/transformers/main/tr/main_classes/text_generation#transformers.GenerationMixin.generate) ile girdi ve/veya çıktı farklarını da belgelemenizi öneririz. Bu sayede kullanıcılar yeniliklere odaklanabilir ve genel uygulama detayları için Transformers belgelerine başvurabilir.

Keşfedilebilirlik için, `custom_generate` etiketini reponuza eklemenizi şiddetle öneririz. Bunu yapmak için `README.md` dosyanızın başı aşağıdaki örnekteki gibi görünmelidir. Dosyayı gönderdikten sonra etiketi repoda görmelisiniz!

```text
---
library_name: transformers
tags:
  - custom_generate
---

(your markdown content here)
```

Önerilen uygulamalar:

- [generate()](/docs/transformers/main/tr/main_classes/text_generation#transformers.GenerationMixin.generate) içindeki girdi ve çıktı farklarını belgeleyin.
- Hızlı deneysel çalışmalar yapılabilmesini sağlamak için kendi içinde tam örnekler ekleyin.
- Yöntemin yalnızca belirli bir model ailesiyle iyi çalışması gibi yumuşak gereksinimleri açıklayın.

### `generate`'in girdi hazırlığını yeniden kullanma

Yeni bir çözümleme döngüsü ekliyorsanız, `generate` içindeki girdi hazırlama işlemlerini (toplu genişletme, dikkat maskeleri, logit işleyicileri, durdurma kriterleri vb.) korumak isteyebilirsiniz. Ayrıca, yalnızca çözümleme döngüsünü geçersiz kılarken [generate()](/docs/transformers/main/tr/main_classes/text_generation#transformers.GenerationMixin.generate)'in tam hazırlama hattını yeniden kullanmak için `custom_generate`'ye bir **callable** iletebilirsiniz.

```py
def custom_loop(model, input_ids, attention_mask, logits_processor, stopping_criteria, generation_config, **model_kwargs):
    next_tokens = input_ids
    while input_ids.shape[1] < stopping_criteria[0].max_length:
        logits = model(next_tokens, attention_mask=attention_mask, **model_kwargs).logits
        next_token_logits = logits_processor(input_ids, logits[:, -1, :])
        next_tokens = torch.argmax(next_token_logits, dim=-1)[:, None]
        input_ids = torch.cat((input_ids, next_tokens), dim=-1)
        attention_mask = torch.cat((attention_mask, torch.ones_like(next_tokens)), dim=-1)
    return input_ids

output = model.generate(
    **inputs,
    custom_generate=custom_loop,
    max_new_tokens=10,
)
```

> [!TIP]
> `custom_generate` deposu yayınlarsanız, `generate` uygulamanız kendi içinde bir çağrılabilir tanımlayabilir ve bunu `model.generate()` fonksiyonuna iletebilir. Bu sayede, Transformers'ın yerleşik girdi hazırlama mantığından faydalanmaya devam ederken çözümleme döngüsünü özelleştirebilirsiniz.

### Özel üretim yöntemlerini bulma

Tüm özel üretim yöntemlerini [özel etiketlerini aratarak](https://huggingface.co/models?other=custom_generate) bulabilirsiniz: `custom_generate`. Etiketin yanı sıra, `custom_generate` yöntemlerinin iki koleksiyonunu derledik:

- [Özel üretim yöntemleri - Topluluk](https://huggingface.co/collections/transformers-community/custom-generation-methods-community-6888fb1da0efbc592d3a8ab6) -- topluluk tarafından katkıda bulunan güçlü yöntemlerin bir derlemesi;
- [Özel üretim yöntemleri - Eğiticiler](https://huggingface.co/collections/transformers-community/custom-generation-methods-tutorials-6823589657a94940ea02cfec) -- daha önce `transformers`'ın bir parçası olan yöntemler için referans uygulamaların yanı sıra `custom_generate` için eğiticiler içeren bir koleksiyon.

## Kaynaklar

Ortak çözümleme stratejilerinin nasıl çalıştığına dair bir açıklama için [Metin üretimi: Transformers ile dil üretimi için farklı çözümleme yöntemlerinin kullanımı](https://huggingface.co/blog/how-to-generate) blog yazısını okuyun.

