Transformers documentation
テキスト生成
テキスト生成
テキスト生成は、大規模言語モデル(LLM)の最も一般的な応用です。LLMは、初期テキスト(プロンプト)と、それまでに生成された出力を条件として、次の単語(トークン)を生成するように学習されます。この生成は、事前に定義された長さに達するか、シーケンスの終了(EOS)トークンに到達した時点で停止します。
Transformersでは、generate() APIがテキスト生成を処理します。このAPIは、生成能力を備えたすべてのモデルで利用可能です。本ガイドでは、generate()によるテキスト生成の基礎と、回避すべき一般的な落とし穴について説明します。
以下のコマンドを実行する際は、
transformers serveが実行中であることを確認してください。transformers chat Qwen/Qwen2.5-0.5B-Instruct
デフォルトの generate
開始に先立ち、bitsandbytes をインストールして非常に大きなモデルを量子化し、メモリ使用量を削減することをお勧めします。
!pip install -U transformers bitsandbytes
Bitsandbytesは、CUDAベースのGPUに加えて、複数のバックエンドをサポートしています。詳細については、マルチバックエンドのインストールガイドを参照してください。
from_pretrained() で LLM を読み込み、メモリ要件を削減するために以下の 2 つのパラメータを追加します。
device_map="auto"を指定すると、Accelerate の Big Model Inference 機能が有効になり、モデルのスケルトンを自動的に初期化し、最速のデバイス(GPU)から順に、利用可能なすべてのデバイスへモデルの重みをロードしてディスパッチします。quantization_configは、量子化の設定を定義する設定オブジェクトです。この例では、量子化バックエンドとして bitsandbytes を使用し、モデルを 4-bits で読み込みます(利用可能な他のバックエンドについては、Quantization セクションを参照してください)。
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)入力をトークン化し、LLMはパディングトークンからの生成継続を学習していないため、padding_side()パラメータを"left"に設定します。トークナイザーは入力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(model.device)入力を受け取ってトークンを生成するには 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
}generate() は、GenerationConfig のパラメータと値をオーバーライドすることでカスタマイズできます。よく調整されるパラメータについては、以下のセクションを参照してください。
# enable beam search sampling strategy
model.generate(**inputs, num_beams=4, do_sample=True)generate() は、外部ライブラリやカスタムコードによって拡張することもできます。
logits_processorパラメータには、次のトークンの確率分布を操作するためのカスタムの LogitsProcessor インスタンスを指定できます。stopping_criteriaパラメータは、テキスト生成を停止するためのカスタム StoppingCriteria をサポートします。- その他のカスタム生成メソッドは、
custom_generateフラグ(ドキュメント)を通じて読み込むことができます。
Generation strategiesガイドを参照して、検索、サンプリング、デコーディングの戦略について詳しく学んでください。
保存
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 パラメータは空にしてください。このパラメータは、1つのディレクトリに複数の生成設定を保存する場合に使用します。読み込む生成設定を指定するための手段です。単一のモデルに対して、異なる生成タスク(サンプリングによるクリエイティブなテキスト生成、ビームサーチによる要約)用に異なる設定を作成できます。
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() は、高度なカスタマイズが可能な強力なツールです。そのため、新規ユーザーにとっては intimidating に感じられるかもしれません。このセクションでは、Transformers のほとんどのテキスト生成ツール(generate()、GenerationConfig、pipelines、chat CLI など)で定義できる、よく使われる生成オプションの一覧を掲載しています。
| オプション名 | 型 | 簡略化された説明 |
|---|---|---|
max_new_tokens | int | 最大生成長を制御します。通常、デフォルト値は小さい値に設定されているため、必ず定義してください。 |
do_sample | bool | 次のトークンをサンプリングして生成を行うかどうか(True)、それとも貪欲法(グリディ)で生成を行うかどうか(False)を定義します。ほとんどのユースケースでは、このフラグをTrueに設定する必要があります。詳細はこのガイドを参照してください。 |
temperature | float | 次に選択されるトークンの予測不能性を示します。高い値(>0.8)は創造的なタスクに適しており、低い値(例: <0.4)は「思考」を必要とするタスクに適しています。do_sample=Trueが必要です。 |
num_beams | int | >1に設定すると、ビームサーチアルゴリズムが有効になります。ビームサーチは、入力に基づいたタスクに適しています。詳細については、このガイドを参照してください。 |
repetition_penalty | float | モデルが頻繁に繰り返しを生成している場合は、>1.0に設定してください。値が大きいほど、より大きなペナルティが適用されます。 |
eos_token_id | list[int] | 生成を停止させるトークンです。デフォルト値は通常問題ありませんが、別のトークンを指定することもできます。 |
落とし穴
以下のセクションでは、テキスト生成中に遭遇する可能性のある一般的な問題とその解決方法について説明します。
出力長
generate() は、モデルの GenerationConfig で特に指定されていない限り、デフォルトで最大 20 トークンを返します。出力の長さを制御するために、max_new_tokens パラメータで生成するトークン数を手動で設定することを強く推奨します。Decoder-only モデルは、生成されたトークンに加えて、元のプロンプトも返します。
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,'デコーディング戦略
generate()のデコード戦略のデフォルトはgreedy searchであり、次の最も確率の高いトークンを選択します。ただし、モデルのGenerationConfigでそれ以外が指定されている場合は除きます。このデコード戦略は、入力に基づいたタスク(文字起こし、翻訳)ではうまく機能しますが、より創造的なユースケース(ストーリー作成、チャットアプリケーション)には最適ではありません。
例えば、多項分布サンプリング戦略を有効にすると、より多様な出力を生成できます。その他のデコーディング戦略については、Generation strategyガイドを参照してください。
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]パディング側
長さが異なる場合は、入力にパディングが必要です。ただし、LLMはパディングトークンからの生成継続について学習されていないため、padding_side()パラメータは入力の左側に設定する必要があります。右パディングは、状態空間モデルやハイブリッドモデルにとってさらに悪影響を及ぼします。これらのモデルでは再帰状態が末尾のパディングトークンにわたって更新され続けるため、キャッシュがプロンプトの末尾と一致しなくなるためです。
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,'プロンプト形式
一部のモデルやタスクでは、特定の入力プロンプト形式が期待されており、形式が正しくない場合、モデルは最適でない出力を返します。プロンプトに関する詳細は、プロンプトエンジニアリングガイドを参照してください。
例えば、チャットモデルは入力をチャットテンプレートとして期待します。プロンプトには、会話に参加している者を示すためにroleとcontentを含める必要があります。プロンプトを単一の文字列として渡そうとすると、モデルが期待される出力を返さない場合があります。
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 canリソース
より具体的で専門的なテキスト生成ライブラリについては、以下をご参照ください。
- Optimum: 特定のハードウェアデバイスでの学習と推論の最適化に特化した Transformers の拡張
- Outlines: 制約付きテキスト生成のためのライブラリ(例: JSON ファイルの生成)。
- SynCode: コンテキストフリー文法による生成(JSON、SQL、Python)をガイドするためのライブラリ。
- Text Generation Inference: LLM向けの本番環境対応サーバー。
- Text generation web UI: テキスト生成用の Gradio ウェブ UI。
- logits-processor-zoo: テキスト生成を制御するための追加の logits プロセッサー。