使用Hugging Face Trainer调参时遇model_init参数错误的排查与解决
问题分析与修复方案
1. 错误原因
- model_init参数传递错误:你直接调用
get_model(model_name, config)返回了一个模型实例,但Trainer要求model_init必须是一个可调用函数(允许0个参数或1个trial参数),而非已初始化的模型对象。 - get_model函数定义不符合要求:当前
get_model需要2个参数,但超参数调优时,Trainer会向model_init传入trial参数(用于获取超参数),你的函数参数不匹配,且没有利用超参数调整模型配置。 - my_hp_space存在参数错误:
- 字典键名错误:
arr_gradient_accumulation_steps、arr_per_device_train_batch_size是无效键,应该对应TrainingArguments里的合法参数名gradient_accumulation_steps、per_device_train_batch_size per_device_train_batch_size的suggest_int调用缺少参数名(正确格式是trial.suggest_int("参数名", 最小值, 最大值))learning_rate的范围写反了,5e-3比5e-5大,应该从小到大定义范围
- 字典键名错误:
2. 修复方案与完整代码
核心修正点
- 调整
model_init为符合要求的可调用函数 - 修正
my_hp_space的参数键名与格式 - 正确传递函数给Trainer的
model_init参数
修正后的完整代码:
def my_hp_space(trial): return { "learning_rate": trial.suggest_float("learning_rate", 5e-5, 5e-3), # 修正范围顺序 "num_train_epochs": trial.suggest_int("num_train_epochs", 8, 16), # 键名匹配参数名 "per_device_train_batch_size": trial.suggest_int("per_device_train_batch_size", 2, 4), # 修正键名和参数格式 "gradient_accumulation_steps": trial.suggest_int("gradient_accumulation_steps", 1, 4) # 可选,按需调整范围 } # 修正model_init函数,接受可选的trial参数(无需调整模型结构时,保留参数占位即可) def get_model(trial=None): model_name = 'sentence-transformers/nli-roberta-base-v2' config = AutoConfig.from_pretrained(model_name, num_labels=3) return AutoModelForSequenceClassification.from_pretrained(model_name, config=config) def compute_metric(eval_predictions): metric = load_metric('accuracy') logits, labels = eval_predictions predictions = np.argmax(logits, axis=-1) return metric.compute(predictions=predictions, references=labels) # 基础训练参数,超参数搜索会自动覆盖对应字段 training_args = TrainingArguments( output_dir='test-trainer', evaluation_strategy="epoch", num_train_epochs=10 ) data_collator = default_data_collator trainer = Trainer( model_init=get_model, # 传递函数本身,而非调用后的模型实例 args=training_args, train_dataset=tokenized_datasets['TRAIN'], eval_dataset=tokenized_datasets['TEST'], compute_metrics=compute_metric, tokenizer=None, data_collator=data_collator, ) # 执行超参数搜索 best = trainer.hyperparameter_search(direction="maximize", hp_space=my_hp_space) # 应用最优超参数并重新训练(可选) for key, value in best.hyperparameters.items(): setattr(trainer.args, key, value) trainer.train() # 打印最优超参数 print("最优超参数:", best.hyperparameters)
关键说明
model_init必须是可调用对象:如果不需要根据超参数调整模型结构,函数可以接受trial参数但不使用,确保符合Trainer的参数要求。- 超参数自动覆盖:
my_hp_space中的键必须是TrainingArguments的合法属性名,Trainer会自动将搜索到的超参数覆盖基础训练参数。 - 获取最优模型:超参数搜索结束后,
best对象包含最优超参数,你可以用这些参数重新训练得到最优模型,也可以在搜索过程中保存每个trial的模型,后续筛选性能最好的版本。
内容的提问来源于stack exchange,提问作者user3668129
相关产品推荐
相关产品推荐

