Transformers documentation

Üretim stratejileri

You are viewing main version, which requires installation from source. If you'd like regular pip install, checkout the latest stable version (v5.22.1).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Ü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'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.

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 her belirtecin seçilme şansına sahip 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.

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 bir adım sayısından sonra, 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. Ayrıca, her adımda örneklem almak için beam search ile do_sample=True kullanabilirsiniz; ancak beam search, adımlar arasında düşük olasılıklı dizileri yine de açgözlü bir şekilde elemeye devam edecektir.

Beam search'ın nasıl çalıştığını görmek için beam search görselleştiricisine 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).

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 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:

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öntemleri, generate()'nin custom_generate argümanı aracılığıyla herhangi bir modelden yüklenebilir. Bu, kullanıcıların ek Python paketleri yüklemesi gerekmeden, özel üretim yöntemlerinin oluşturulup paylaşılabilmesi ve potansiyel olarak herhangi bir Transformers modeliyle çalışabilmesi anlamına gelir.

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() metodu gibi çalıştığını varsayabilirsiniz.

Tüm özel üretim yöntemlerini özel etiketlerini, custom_generate, aratarak bulabilirsiniz.

Örnek olarak 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.

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 gereksinimlerle ilgili bir istisna alırsınız. Örneğin, transformers-community/custom_generate_bad_requirements custom_generate/requirements.txt dosyasında imkânsız bir gereksinim seti tanımlar ve bunu çalıştırmaya çalışırsanız aşağıdaki hata mesajını görürsünüz.

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 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, deponuzun görünümü şu şekilde olmalıdır

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ğerlerinden farksız 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 düşünülmelidir. 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â herhangi bir diğer Transformers modeliyle yüklenebilir.

Mevcut bir modeli kopyalamak istiyorsanız, bunu

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 içinde tanımlananlar (temel generate yöntemi gibi) dahil olmak üzere erişiminiz olduğu anlamına gelir.

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() 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.

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() 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:

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.

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

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 kendinizin yazdığı veya incelediği kodlar 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 kontrol edilir 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ğindedir.

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ırmayı şiddetle öneririz. Yöntemin açıklamasının yanı sıra, orijinal generate() ile girdi ve/veya çıktı farklarını da belgelemeyi ö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!

---
library_name: transformers
tags:
  - custom_generate
---

(your markdown content here)

Önerilen uygulamalar:

  • 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ırlığını (toplu genişletme, dikkat maskeleri, logit işleyicileri, durdurma kriterleri vb.) korumak isteyebilirsiniz. Ayrıca, generate()'in tam hazırlama hattını yeniden kullanıp yalnızca çözümleme döngüsünü geçersiz kılmak için custom_generate'ye bir callable iletebilirsiniz.

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,
)

custom_generate deposu yayınlarsanız, generate uygulamanız kendi içinde çağrılabilir bir nesne 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 bulabilirsiniz: custom_generate. Etiketin yanı sıra, custom_generate yöntemlerinin iki koleksiyonunu derledik:

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ı blog yazısını okuyun.

Update on GitHub