Transformers documentation
Generasi teks
Generasi teks
Generasi teks adalah aplikasi paling populer untuk model bahasa besar (LLM). LLM dilatih untuk menghasilkan kata (token) berikutnya berdasarkan teks awal (prompt) beserta output yang telah dihasilkannya sendiri hingga mencapai panjang yang telah ditentukan atau ketika mencapai token akhir urutan (EOS).
Di Transformers, API generate() menangani pembuatan teks, dan tersedia untuk semua model dengan kemampuan generatif. Panduan ini akan menunjukkan dasar-dasar pembuatan teks dengan generate() serta beberapa kesalahan umum yang perlu dihindari.
Untuk perintah-perintah berikut, pastikan
transformers servesedang berjalan.transformers chat Qwen/Qwen2.5-0.5B-Instruct
Default generate
Sebelum memulai, disarankan untuk menginstal bitsandbytes untuk mengkuantisasi model yang sangat besar guna mengurangi penggunaan memorinya.
!pip install -U transformers bitsandbytes
Bitsandbytes mendukung beberapa backend selain GPU berbasis CUDA. Lihat panduan instalasi multi-backend untuk mempelajari lebih lanjut.
Muat LLM dengan from_pretrained() dan tambahkan dua parameter berikut untuk mengurangi kebutuhan memori.
device_map="auto"mengaktifkan fitur Big Model Inference dari Accelerate untuk secara otomatis memulai kerangka model serta memuat dan mendistribusikan bobot model ke semua perangkat yang tersedia, dimulai dari perangkat tercepat (GPU).quantization_configadalah objek konfigurasi yang mendefinisikan pengaturan kuantisasi. Contoh ini menggunakan bitsandbytes sebagai backend kuantisasi (lihat bagian Kuantisasi untuk backend lain yang tersedia) dan memuat model dalam 4-bit.
from transformers import AutoTokenizer, AutoModelForCausalLM, BitsAndBytesConfig
quantization_config = BitsAndBytesConfig(load_in_4bit=True)
model = AutoModelForCausalLM.from_pretrained("mistralai/Mistral-7B-v0.1", device_map="auto", quantization_config=quantization_config)Tokenisasi input Anda, dan setel parameter padding_side() ke "left" karena LLM tidak dilatih untuk melanjutkan generasi dari token padding. Tokenizer mengembalikan input ids dan attention mask.
Proses lebih dari satu prompt sekaligus dengan meneruskan daftar string ke tokenizer. Batch input untuk meningkatkan throughput dengan sedikit biaya pada latensi dan memori.
tokenizer = AutoTokenizer.from_pretrained("mistralai/Mistral-7B-v0.1", padding_side="left")
model_inputs = tokenizer(["A list of colors: red, blue"], return_tensors="pt").to(model.device)Lewatkan input ke generate() untuk menghasilkan token, lalu gunakan batch_decode() untuk mengubah token yang dihasilkan kembali menjadi teks.
generated_ids = model.generate(**model_inputs)
tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]
"A list of colors: red, blue, green, yellow, orange, purple, pink,"Konfigurasi generasi
Semua pengaturan generasi terkandung dalam GenerationConfig. Pada contoh di atas, pengaturan generasi diturunkan dari file generation_config.json dari mistralai/Mistral-7B-v0.1. Strategi decoding default digunakan ketika tidak ada konfigurasi yang disimpan bersama model.
Periksa konfigurasi melalui atribut generation_config. Atribut ini hanya menampilkan nilai yang berbeda dari konfigurasi default, dalam hal ini bos_token_id dan eos_token_id.
from transformers import AutoModelForCausalLM
model = AutoModelForCausalLM.from_pretrained("mistralai/Mistral-7B-v0.1", device_map="auto")
model.generation_config
GenerationConfig {
"bos_token_id": 1,
"eos_token_id": 2
}Anda dapat menyesuaikan generate() dengan menimpa parameter dan nilai di GenerationConfig. Lihat bagian ini di bawah untuk parameter yang sering disesuaikan.
# enable beam search sampling strategy
model.generate(**inputs, num_beams=4, do_sample=True)generate() juga dapat diperluas dengan pustaka eksternal atau kode kustom:
- parameter
logits_processormenerima instance LogitsProcessor kustom untuk memanipulasi distribusi probabilitas token berikutnya; - parameter
stopping_criteriamendukung StoppingCriteria kustom untuk menghentikan generasi teks; - metode kustom lainnya dapat dimuat melalui flag
custom_generate(dokumentasi).
Lihat panduan Strategi generasi untuk mempelajari lebih lanjut tentang strategi pencarian, pengambilan sampel, dan decoding.
Menyimpan
Buat instance dari GenerationConfig dan tentukan parameter decoding yang diinginkan.
from transformers import AutoModelForCausalLM, GenerationConfig
model = AutoModelForCausalLM.from_pretrained("my_account/my_model")
generation_config = GenerationConfig(
max_new_tokens=50, do_sample=True, top_k=50, eos_token_id=model.config.eos_token_id
)Gunakan save_pretrained() untuk menyimpan konfigurasi generasi tertentu dan set parameter push_to_hub ke True untuk mengunggahnya ke Hub.
generation_config.save_pretrained("my_account/my_model", push_to_hub=True)Biarkan parameter config_file_name kosong. Parameter ini harus digunakan saat menyimpan beberapa konfigurasi generasi dalam satu direktori. Parameter ini memberi Anda cara untuk menentukan konfigurasi generasi mana yang akan dimuat. Anda dapat membuat konfigurasi yang berbeda untuk tugas generatif yang berbeda (generasi teks kreatif dengan sampling, ringkasan dengan beam search) untuk digunakan dengan satu model.
from transformers import AutoModelForSeq2SeqLM, AutoTokenizer, GenerationConfig
tokenizer = AutoTokenizer.from_pretrained("google-t5/t5-small")
model = AutoModelForSeq2SeqLM.from_pretrained("google-t5/t5-small")
translation_generation_config = GenerationConfig(
num_beams=4,
early_stopping=True,
decoder_start_token_id=0,
eos_token_id=model.config.eos_token_id,
pad_token=model.config.pad_token_id,
)
translation_generation_config.save_pretrained("/tmp", config_file_name="translation_generation_config.json", push_to_hub=True)
generation_config = GenerationConfig.from_pretrained("/tmp", config_file_name="translation_generation_config.json")
inputs = tokenizer("translate English to French: Configuration files are easy to use!", return_tensors="pt")
outputs = model.generate(**inputs, generation_config=generation_config)
print(tokenizer.batch_decode(outputs, skip_special_tokens=True))Opsi Umum
generate() adalah alat yang sangat kuat dan dapat dikustomisasi secara mendalam. Hal ini mungkin terasa membingungkan bagi pengguna baru. Bagian ini berisi daftar opsi generasi populer yang dapat Anda definisikan di sebagian besar alat generasi teks di Transformers: generate(), GenerationConfig, pipelines, CLI chat, …
| Nama opsi | Tipe | Deskripsi yang disederhanakan |
|---|---|---|
max_new_tokens | int | Mengontrol panjang maksimum generasi. Pastikan untuk mendefinisikannya, karena biasanya nilainya secara default kecil. |
do_sample | bool | Menentukan apakah generasi akan mengambil sampel token berikutnya (True), atau justru bersifat serakah (False). Sebagian besar kasus penggunaan sebaiknya mengatur flag ini ke True. Periksa panduan ini untuk informasi lebih lanjut. |
temperature | float | Seberapa tidak terduga token yang akan dipilih selanjutnya. Nilai tinggi (>0.8) cocok untuk tugas kreatif, sedangkan nilai rendah (misalnya <0.4) untuk tugas yang membutuhkan “pemikiran”. Memerlukan do_sample=True. |
num_beams | int | Ketika diatur ke >1, mengaktifkan algoritma beam search. Beam search cocok untuk tugas yang berbasis input. Lihat panduan ini untuk informasi lebih lanjut. |
repetition_penalty | float | Atur ke >1.0 jika Anda melihat model sering mengulang dirinya. Nilai yang lebih besar menerapkan penalti yang lebih besar. |
eos_token_id | list[int] | Token yang akan menyebabkan generasi berhenti. Nilai default biasanya sudah baik, tetapi Anda dapat menentukan token yang berbeda. |
Jebakan
Bagian di bawah ini membahas beberapa masalah umum yang mungkin Anda temui selama generasi teks dan cara menyelesaikannya.
Panjang output
generate() secara default mengembalikan hingga 20 token kecuali ditentukan lain dalam GenerationConfig model. Sangat disarankan untuk mengatur jumlah token yang dihasilkan secara manual dengan parameter max_new_tokens untuk mengontrol panjang output. Model Decoder-only mengembalikan prompt awal bersama dengan token yang dihasilkan.
model_inputs = tokenizer(["A sequence of numbers: 1, 2"], return_tensors="pt").to(model.device)generated_ids = model.generate(**model_inputs)
tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]
'A sequence of numbers: 1, 2, 3, 4, 5'generated_ids = model.generate(**model_inputs, max_new_tokens=50)
tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]
'A sequence of numbers: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,'Strategi decoding
Strategi decoding default dalam generate() adalah greedy search, yang memilih token berikutnya yang paling mungkin, kecuali ditentukan lain dalam GenerationConfig model. Meskipun strategi decoding ini bekerja dengan baik untuk tugas yang berbasis input (transkripsi, terjemahan), strategi ini tidak optimal untuk kasus penggunaan yang lebih kreatif (penulisan cerita, aplikasi chat).
Sebagai contoh, aktifkan strategi multinomial sampling untuk menghasilkan output yang lebih beragam. Lihat panduan Generation strategy untuk strategi decoding lainnya.
model_inputs = tokenizer(["I am a cat."], return_tensors="pt").to(model.device)generated_ids = model.generate(**model_inputs)
tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]generated_ids = model.generate(**model_inputs, do_sample=True)
tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]Sisi padding
Input perlu di-*padding* jika panjangnya tidak sama. Namun, LLM tidak dilatih untuk melanjutkan generasi dari token *padding*, yang berarti parameter padding_side() perlu diatur ke sisi kiri input. *Padding* di sisi kanan lebih buruk untuk model state-space dan hibrida karena keadaan rekurens mereka terus diperbarui di atas token *pad* yang berujung, sehingga cache tidak lagi cocok dengan akhir prompt.
model_inputs = tokenizer(
["1, 2, 3", "A, B, C, D, E"], padding=True, return_tensors="pt"
).to(model.device)
generated_ids = model.generate(**model_inputs)
tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]
'1, 2, 33333333333'tokenizer = AutoTokenizer.from_pretrained("mistralai/Mistral-7B-v0.1", padding_side="left")
tokenizer.pad_token = tokenizer.eos_token
model_inputs = tokenizer(
["1, 2, 3", "A, B, C, D, E"], padding=True, return_tensors="pt"
).to(model.device)
generated_ids = model.generate(**model_inputs)
tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]
'1, 2, 3, 4, 5, 6,'Format prompt
Beberapa model dan tugas mengharapkan format prompt input tertentu, dan jika formatnya salah, model akan mengembalikan output yang tidak optimal. Anda dapat mempelajari lebih lanjut tentang prompting di panduan prompt engineering.
Sebagai contoh, model chat mengharapkan input dalam bentuk template chat. Prompt Anda harus menyertakan role dan content untuk menunjukkan siapa yang berpartisipasi dalam percakapan. Jika Anda mencoba meneruskan prompt sebagai satu string tunggal, model tidak selalu mengembalikan output yang diharapkan.
from transformers import AutoTokenizer, AutoModelForCausalLM, BitsAndBytesConfig
tokenizer = AutoTokenizer.from_pretrained("HuggingFaceH4/zephyr-7b-alpha")
model = AutoModelForCausalLM.from_pretrained(
"HuggingFaceH4/zephyr-7b-alpha", device_map="auto", quantization_config=BitsAndBytesConfig(load_in_4bit=True)
)prompt = """How many cats does it take to change a light bulb? Reply as a pirate."""
model_inputs = tokenizer([prompt], return_tensors="pt").to(model.device)
input_length = model_inputs.input_ids.shape[1]
generated_ids = model.generate(**model_inputs, max_new_tokens=50)
print(tokenizer.batch_decode(generated_ids[:, input_length:], skip_special_tokens=True)[0])
"Aye, matey! 'Tis a simple task for a cat with a keen eye and nimble paws. First, the cat will climb up the ladder, carefully avoiding the rickety rungs. Then, with"messages = [
{
"role": "system",
"content": "You are a friendly chatbot who always responds in the style of a pirate",
},
{"role": "user", "content": "How many cats does it take to change a light bulb?"},
]
model_inputs = tokenizer.apply_chat_template(messages, add_generation_prompt=True, return_tensors="pt").to(model.device)
input_length = model_inputs["input_ids"].shape[1]
generated_ids = model.generate(**model_inputs, do_sample=True, max_new_tokens=50)
print(tokenizer.batch_decode(generated_ids[:, input_length:], skip_special_tokens=True)[0])
"Arr, matey! According to me beliefs, 'twas always one cat to hold the ladder and another to climb up it an’ change the light bulb, but if yer looking to save some catnip, maybe yer canSumber daya
Lihat di bawah ini untuk beberapa pustaka generasi teks yang lebih spesifik dan khusus.
- Optimum: ekstensi dari Transformers yang berfokus pada optimasi pelatihan dan inferensi pada perangkat keras tertentu
- Outlines: pustaka untuk generasi teks yang terkonstrain (misalnya, menghasilkan file JSON).
- SynCode: pustaka untuk generasi yang dipandu tata bahasa bebas konteks (JSON, SQL, Python).
- Text Generation Inference: server siap produksi untuk LLM.
- Text generation web UI: antarmuka web Gradio untuk generasi teks.
- logits-processor-zoo: logits processor tambahan untuk mengontrol generasi teks.