Transformers 文件
文字生成
並獲得增強的文件體驗
開始使用
文字生成
文字生成是大型語言模型(LLM)最受歡迎的應用。LLM 經過訓練,可以根據初始文字(提示)以及自身生成的輸出,生成下一個單詞(標記),直到達到預定義長度或遇到序列結束(EOS
)標記。
在 Transformers 中,generate() API 處理文字生成,它適用於所有具有生成能力的模型。本指南將向您展示使用 generate() 進行文字生成的基礎知識以及一些常見的常見陷阱。
您還可以直接從命令列與模型聊天。(參考)
transformers chat Qwen/Qwen2.5-0.5B-Instruct
預設生成
在開始之前,安裝 bitsandbytes 以量化大型模型以減少其記憶體使用量會很有幫助。
!pip install -U transformers bitsandbytes
Bitsandbytes 除了基於 CUDA 的 GPU 外,還支援多種後端。請參閱多後端安裝指南以瞭解更多資訊。
使用 from_pretrained() 載入 LLM 並新增以下兩個引數以減少記憶體需求。
device_map="auto"
啟用 Accelerate 的大型模型推理功能,用於自動初始化模型骨架並在所有可用裝置上載入和分派模型權重,從最快的裝置(GPU)開始。quantization_config
是一個配置物件,定義了量化設定。此示例使用 bitsandbytes 作為量化後端(有關更多可用後端,請參閱量化部分),它以4 位載入模型。
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)
對您的輸入進行標記化,並將 padding_side()
引數設定為 "left"
,因為 LLM 未經訓練以從填充標記繼續生成。標記器返回輸入 ID 和注意力掩碼。
透過向標記器傳遞字串列表,一次處理多個提示。批次輸入以在延遲和記憶體方面付出少量代價來提高吞吐量。
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("cuda")
將輸入傳遞給 generate() 以生成標記,並使用 batch_decode() 將生成的標記解碼迴文本。
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,"
生成配置
所有生成設定都包含在 GenerationConfig 中。在上面的示例中,生成設定來自 mistralai/Mistral-7B-v0.1 的 generation_config.json
檔案。如果模型沒有儲存配置,則使用預設解碼策略。
透過 generation_config
屬性檢查配置。它只顯示與預設配置不同的值,在此示例中是 bos_token_id
和 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
}
您可以透過覆蓋 GenerationConfig 中的引數和值來自定義 generate()。有關常用調整引數,請參閱下面的此部分。
# enable beam search sampling strategy
model.generate(**inputs, num_beams=4, do_sample=True)
generate() 還可以透過外部庫或自定義程式碼進行擴充套件
logits_processor
引數接受自定義 LogitsProcessor 例項,用於操縱下一個標記機率分佈;stopping_criteria
引數支援自定義 StoppingCriteria 以停止文字生成;- 其他自定義生成方法可以透過
custom_generate
標誌載入(文件)。
請參閱生成策略指南,瞭解有關搜尋、取樣和解碼策略的更多資訊。
儲存
建立 GenerationConfig 例項並指定所需的解碼引數。
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
)
使用 save_pretrained() 儲存特定的生成配置,並將 push_to_hub
引數設定為 True
以將其上傳到 Hub。
generation_config.save_pretrained("my_account/my_model", push_to_hub=True)
將 config_file_name
引數留空。當在一個目錄中儲存多個生成配置時,應使用此引數。它為您提供了一種指定要載入哪個生成配置的方式。您可以為不同的生成任務(使用取樣的創意文字生成,使用束搜尋的摘要)建立不同的配置,以供單個模型使用。
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))
常用選項
generate() 是一個功能強大的工具,可以高度自定義。這對於新使用者來說可能令人生畏。本節列出了 Transformers 中大多數文字生成工具中可以定義的流行生成選項:generate()、GenerationConfig、pipelines
、chat
CLI 等。
選項名稱 | 型別 | 簡化描述 |
---|---|---|
max_new_tokens | int | 控制最大生成長度。務必定義它,因為它通常預設為一個較小的值。 |
do_sample | 布林值 | 定義生成是取樣下一個標記(True ),還是貪婪生成(False )。大多數用例應將此標誌設定為 True 。有關更多資訊,請檢視此指南。 |
temperature | 浮點數 | 下一個選定標記的不可預測性。高值(>0.8 )適用於創意任務,低值(例如 <0.4 )適用於需要“思考”的任務。需要 do_sample=True 。 |
num_beams | int | 當設定為 >1 時,啟用束搜尋演算法。束搜尋在基於輸入的任務中效果良好。有關更多資訊,請檢視此指南。 |
repetition_penalty | 浮點數 | 如果模型經常重複自身,請將其設定為 >1.0 。值越大,懲罰越大。 |
eos_token_id | list[int] | 將導致生成停止的標記。預設值通常很好,但您可以指定不同的標記。 |
常見陷阱
以下部分介紹了一些您在文字生成過程中可能遇到的常見問題以及如何解決它們。
輸出長度
除非在模型的 GenerationConfig 中另有指定,否則 generate() 預設最多返回 20 個標記。強烈建議使用 max_new_tokens
引數手動設定生成的標記數量以控制輸出長度。僅解碼器模型返回初始提示以及生成的標記。
model_inputs = tokenizer(["A sequence of numbers: 1, 2"], return_tensors="pt").to("cuda")
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'
解碼策略
除非在模型的 GenerationConfig 中另有指定,否則 generate() 中的預設解碼策略是*貪婪搜尋*,它選擇下一個最可能的標記。雖然此解碼策略適用於基於輸入的任務(轉錄、翻譯),但它不適用於更具創意性的用例(故事創作、聊天應用程式)。
例如,啟用多項式取樣策略以生成更多樣化的輸出。請參閱生成策略指南,瞭解更多解碼策略。
model_inputs = tokenizer(["I am a cat."], return_tensors="pt").to("cuda")
generated_ids = model.generate(**model_inputs)
tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]
填充側
如果輸入長度不一致,則需要填充。但是 LLM 未經訓練以從填充標記繼續生成,這意味著 padding_side()
引數需要設定為輸入的左側。
model_inputs = tokenizer(
["1, 2, 3", "A, B, C, D, E"], padding=True, return_tensors="pt"
).to("cuda")
generated_ids = model.generate(**model_inputs)
tokenizer.batch_decode(generated_ids, skip_special_tokens=True)[0]
'1, 2, 33333333333'
提示格式
某些模型和任務需要特定的輸入提示格式,如果格式不正確,模型將返回次優輸出。您可以在提示工程指南中瞭解有關提示的更多資訊。
例如,聊天模型將輸入視為聊天模板。您的提示應包含 role
和 content
以指示對話的參與者。如果您嘗試將提示作為單個字串傳遞,模型不總是返回預期的輸出。
from transformers import AutoTokenizer, AutoModelForCausalLM
tokenizer = AutoTokenizer.from_pretrained("HuggingFaceH4/zephyr-7b-alpha")
model = AutoModelForCausalLM.from_pretrained(
"HuggingFaceH4/zephyr-7b-alpha", device_map="auto", 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("cuda")
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"
資源
請看下面一些更具體和專業的文字生成庫。
- Optimum:Transformers 的擴充套件,專注於最佳化特定硬體裝置上的訓練和推理
- Outlines:一個用於受限文字生成的庫(例如生成 JSON 檔案)。
- SynCode:一個用於上下文無關語法引導生成的庫(JSON、SQL、Python)。
- Text Generation Inference:一個用於 LLM 的生產就緒伺服器。
- Text generation web UI:一個用於文字生成的 Gradio Web UI。
- logits-processor-zoo:用於控制文字生成的附加 logits 處理器。