Transformers
モデルとフレームワークの対応表もここ
TODO アーキテクチャのはなしと transformes は分けたい
Auto Classes
AutoModel
AutoModelForSequenceClassification
AutoTokenizer
tokenizer.tokenize(text)
tokenizer.model_input_names 入力に期待するフィールド
tokenizer.special_tokens_map
code:look.py
[
{"name": name, "token": token, "id": tokenizer.convert_tokens_to_ids(token)}
for name, token in tokenizer.special_tokens_map.items()
]
from_pretrained で Hugging Face Hub から取ってくる
Trainer 等への入力形式は
モデル形式 → 具体的なタスクのインタフェース
forward の signature 見る(テクい)
code:signature.py
import inspect
inspect.signature(model.forward)
モデル
Encoder-Decoder
T5
Encoder
BERT, RoBERTa
向き不向き
入力テキストと強く関係ある出力を生成するなら Encoder-Decoder
分類などは Encoder のみのモデルのほうが高い性能を示しがち & 軽い
シード固定
標準の random や NumPy や PyTorch の乱数シードが固定される
code:fix_seed.py
from transformers.trainer_utils import set_seed
set_seed(10)
datasets
Pipeline
encoder
入力から文脈化トークン embedding を出力
Positional Encoding 位置符号を付加
正弦関数で位置をベクトル化
自己注意機構 (self attention)
key-query-value attention
3種類の embedding を使う
? 入力 → クエリ埋込はどうやってる? 学習?
multi-head attention
複数の注意機構を同時に適用する
? attention について別でもうちょい読む
活性化は ReLU より GELU が LLM では経験的にいいので標準的に使われている
ドロップアウト率 10% が多い
? 残差結合もよくわかってない
encoder-decoder
encoder の出力(文脈)と入力を受け取って次のトークンを出力
交差注意機構 (cross-attention)
decoder への入力(途中まで生成しているもの)に self-attention を通して
接続している encoder の出力と cross-attention でくっつける
? 小規模な NN で使える attention 実装とかあればもっとイメージわく?
decoder
入力から次のトークンを予測
encoder-decoder から交差注意機構がないもの
TODO
Early Stopping
関連パラメータ
TrainingArguments
eval_strategy='steps' 最近は 1~3 epoch 程度しか回さないので
eval_steps 全体のステップ数に合わせて
どう決める?
訓練データのサンプル数 / バッチサイズ * 1エポックあたりの評価回数
安定してきたあたりで 5~10回ぐらい評価が回る程度の回数?
save_strategy / save_steps: ES 使うなら eval と揃えておく
metric_for_best_model Trainer の compute_metrics が返す値をキー名で参照、省略時は eval_loss?
greater_is_better 参照する metric の意味に応じて、loss なら小さいほうがいいので False、score なら True
load_best_model_at_end ES したあと save するなら実質必須、止まった段階ではなくベストスコアがほしい
save_total_limit patience 回より十分多くないと消す? → なんてことはない
Trainer
eval_dataset eval するので当然いる
callbacks=[early_stopping]
EarlyStoppingCallback(...)
early_stopping_patience
eval_steps の回数、なだらかなら 2~3 / ギザギザなら 5~10 とか?? 検証グラフの揺れを乗り越えられる程度
early_stopping_threshold
メトリック次第、0 で試す / 安定してきた頃の loss 変化の 2 桁ぐらい小さい値?
訓練した後のメトリック取得
trainer.train() 後の trainer.state を見る?
trainer.state に以下が Optional で生えてる
best_metric
best_global_step
best_model_checkpoint
state に何があるかどこでわかんの??
state.save_to_json(path) がある
dataclasses.asdict(trainer.state) 相当
compute_metrics にわたすものは何?
code:compute_metrics.py
def custom_metrics(eval_pred):
logits = eval_pred.predictions
labels = eval_pred.label_ids
...
return {"custom_metircs": score}
def compute_map3(eval_pred):
logits = eval_pred.predictions
labels = eval_pred.label_ids
# logits を各ラベルの確率に
probs = torch.nn.functional.softmax(torch.tensor(logits), dim=-1).numpy()
# MAP@3 なので上位 3 つを選ぶ
top3 = np.argsort(-probs, axis=1):, :3 matches = (top_k_indices == labels:, None) score = 0
for i in range(len(labels)):
score += 1.0
score += 1.0 / 2
score += 1.0 / 3
return {"map@3": score / len(labels)}
RAdamScheduleFree
使ってみたいけど PR に optimizer.eval と train の呼び分けってしてない?
transformers が呼び分けてる
training_step 関数で optimizer に train メソッドがあれば呼ぶ self.optimizer.train()
evaluation_loop, prediction_loop で self.optimizer.eval() を呼ぶ
安心
lr_scheduler_type="constant" 推奨
Setting other lr_scheduler_type would also work, but combining Schedule-Free with other learning rate schedules is not well-studied both in research and in practice,