如何在Hugging Face Transformers的hyperparameter_search后保存最优模型?
解决Transformers超参调优后保存最佳模型的问题
问题原因
调用trainer.save_model()报错,是因为当前的trainer实例并没有持有超参搜索后得到的最佳模型。使用Ray作为backend时,超参搜索的每个trial都是独立训练的,训练结果不会自动同步回初始的trainer对象,初始trainer的model仍处于未训练状态(甚至可能为None,取决于model_init的实现),因此触发AttributeError。
解决方法
方法1:利用超参搜索返回结果重新训练并保存
hyperparameter_search()会返回包含最佳超参配置的BestRun对象,可基于这些参数重新训练并保存模型:
# 执行超参搜索并获取最佳结果 best_run = trainer.hyperparameter_search( hp_space=lambda _: config, backend='ray', n_trials=1, resources_per_trial={ "cpu": 1, "gpu": 1 }, scheduler=scheduler, keep_checkpoints_num=1, checkpoint_score_attr="training_iteration", stop=None, progress_reporter=reporter, storage_path="~/ray_results/", name="tune_transformer_pbt" ) # 用最佳超参更新训练参数 def training_args_best(): args = training_args() # 覆盖最佳超参,需根据你的config参数调整对应字段 for key, value in best_run.hyperparameters.items(): setattr(args, key, value) return args # 重新初始化trainer并完成训练 trainer_best = Trainer( model_init=model_init, args=training_args_best(), compute_metrics=compute_metrics, train_dataset=encoded_dataset['train'], eval_dataset=encoded_dataset['validation'], tokenizer=tokenizer ) trainer_best.train() # 保存最佳模型及tokenizer trainer_best.save_model("./best_model") tokenizer.save_pretrained("./best_model")
方法2:从Ray的checkpoint目录直接加载
Ray会将每个trial的checkpoint保存在指定的storage_path(即~/ray_results/tune_transformer_pbt/)下,可直接加载最佳trial的checkpoint:
- 定位最佳trial的checkpoint路径:根据
best_run.run_id找到对应trial的文件夹,其中checkpoint_xxx目录即为模型 checkpoint。 - 加载并保存模型:
from transformers import AutoModelForSequenceClassification # 替换为你的模型类型 # 替换为实际的checkpoint路径 best_model = AutoModelForSequenceClassification.from_pretrained("~/ray_results/tune_transformer_pbt/[trial_id]/checkpoint_000001") best_model.save_pretrained("./best_model") tokenizer.save_pretrained("./best_model")
额外注意事项
- 确保
model_init函数能正确返回模型实例,避免返回None引发异常。 - 保存模型时需同步保存tokenizer,否则后续加载模型无法正常使用。
内容的提问来源于stack exchange,提问作者Winson
相关产品推荐
相关产品推荐

