Transformers documentation
Üretim stratejileri
Ü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.
- Üretim yönteminizi tasarladığınız model.
- Özel üretim yönteminiz için tüm mantığı içeren
custom_generate/generate.py. 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.README.mddosyasınacustom_generateetiketini 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.txtTemel 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.pydosyası, depoyun kök dizininde değil,custom_generateadlı 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.
modeliçinde herhangi bir özel yöntem/özellik kullanıyorsanız, gereksinimlerdetransformerssü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_functionYalnı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 gibitrust_remote_code=Truegerektirir.trust_remote_code=Trueparametresini 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_generatedeposu yayınlarsanız,generateuygulamanız kendi içinde çağrılabilir bir nesne tanımlayabilir ve bunumodel.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:
- Özel üretim yöntemleri - Topluluk — topluluk tarafından katkıda bulunan güçlü yöntemlerin bir koleksiyonu;
- Özel üretim yöntemleri - Eğitimler — daha önce
transformers'ın bir parçası olan yöntemler için referans uygulamaların yanı sıracustom_generateiçin eğitimler.
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