【Transformers】警告The attention mask and the pad token id were not set. As a consequence・・・の解決方法



1. 警告の内容
2. 警告の発生したコード
2.1. モデルの読み込み
モデルとしてllama3を使用します。トークナイザーとモデルを読み込みます。
from transformers import AutoTokenizer, AutoModelForCausalLM
import torch
model_id = "meta-llama/Meta-Llama-3-8B"
tokenizer = AutoTokenizer.from_pretrained(model_id)
model = AutoModelForCausalLM.from_pretrained(
model_id,
torch_dtype=torch.bfloat16,
device_map="auto",
load_in_4bit=True)
2.2. 問題のあるコード
prompt="Octave is "
input_ids = tokenizer.encode(
prompt,
return_tensors="pt"
).to(model.device)
temperature= 0.1
outputs = model.generate(
input_ids,
max_new_tokens=50,
do_sample=True,
temperature=temperature,
)
output=tokenizer.decode(outputs[0],skip_special_tokens=True)
出力自体はちゃんと生成されます。内容に間違いがありますが…。Octaveは数値計算に特化したソフトウェアですが、出力には「Octaveは3Dプリンティング用のソフトウェアです」と誤った情報が含まれていました。
Octave is 3D printing software that allows you to create 3D models and print them on a 3D printer. It is a free and open-source software that is available for Windows, Mac, and Linux. Octave is a powerful tool that can
本題ですが、次のような警告が発生しました。
The attention mask and the pad token id were not set. As a consequence, you may observe unexpected behavior. Please pass your input’s attention_mask to obtain reliable results.
Setting pad_token_id to eos_token_id:None for open-end generation.
The attention mask is not set and cannot be inferred from input because pad token is same as eos token. As a consequence, you may observe unexpected behavior. Please pass your input’s attention_mask to obtain reliable results.
警告の内容を日本語にすると、
ようは、attention_maskとpad token IDを指定しなさいということですね。
3. 解決方法
この警告を回避するためには、attention_maskを明示的に指定し、pad tokenを設定します。以下に修正したコードを示します。
prompt="Octave is "
# 必要に応じて pad_token を設定
if tokenizer.pad_token is None:
tokenizer.pad_token = tokenizer.eos_token
temperature = 0.1
# 入力に対して attention_mask を生成
inputs = tokenizer(prompt, return_tensors="pt", padding=True).to(model.device)
input_ids = inputs["input_ids"]
attention_mask = inputs["attention_mask"]
# モデル生成時に attention_mask を含める
outputs = model.generate(
input_ids,
attention_mask=attention_mask,
max_new_tokens=50,
do_sample=True,
temperature=temperature,
pad_token_id=tokenizer.pad_token_id # ここに pad_token_id を渡す
)
output = tokenizer.decode(outputs[0], skip_special_tokens=True)
print(output)
3.1. コードのポイント
pad_tokenの設定: トークナイザーにpad_tokenがない場合、eos_tokenをpad_tokenとして設定しています。
if tokenizer.pad_token is None:
tokenizer.pad_token = tokenizer.eos_token
attention_maskの生成: tokenizerからpadding=Trueを指定して、入力データとattention_maskを取得しています。
inputs = tokenizer(prompt, return_tensors="pt", padding=True).to(model.device)
input_ids = inputs["input_ids"]
attention_mask = inputs["attention_mask"]
pad_token_idとattention_maskの指定: トークンの生成時にpad_token_idとattention_maskを明示的に設定します。
outputs = model.generate(
input_ids,
attention_mask=attention_mask,
max_new_tokens=50,
do_sample=True,
temperature=temperature,
pad_token_id=tokenizer.pad_token_id # ここに pad_token_id を渡す
)
