Raytune выдает ошибку: «модуль 'pickle' не имеет атрибута 'PickleBuffer'» при попытке поиска гиперпараметров.
Я более или менее следую [этому примеру][1], чтобы интегрировать библиотеку гиперпараметров настройки лучей с библиотекой преобразователей huggingface, используя мой собственный набор данных.
Вот мой сценарий:
import ray
from ray import tune
from ray.tune import CLIReporter
from ray.tune.examples.pbt_transformers.utils import download_data, \
build_compute_metrics_fn
from ray.tune.schedulers import PopulationBasedTraining
from transformers import glue_tasks_num_labels, AutoConfig, \
AutoModelForSequenceClassification, AutoTokenizer, Trainer, TrainingArguments
def get_model():
# tokenizer = AutoTokenizer.from_pretrained(model_name, additional_special_tokens = ['[CHARACTER]'])
model = ElectraForSequenceClassification.from_pretrained('google/electra-small-discriminator', num_labels=2)
model.resize_token_embeddings(len(tokenizer))
return model
from sklearn.metrics import accuracy_score, precision_recall_fscore_support
def compute_metrics(pred):
labels = pred.label_ids
preds = pred.predictions.argmax(-1)
precision, recall, f1, _ = precision_recall_fscore_support(labels, preds, average='weighted')
acc = accuracy_score(labels, preds)
return {
'accuracy': acc,
'f1': f1,
'precision': precision,
'recall': recall
}
training_args = TrainingArguments(
"electra_hp_tune",
report_to = "wandb",
learning_rate=2e-5, # config
do_train=True,
do_eval=True,
evaluation_strategy="epoch",
load_best_model_at_end=True,
num_train_epochs=2, # config
per_device_train_batch_size=16, # config
per_device_eval_batch_size=16, # config
warmup_steps=0,
weight_decay=0.1, # config
logging_dir="./logs",
)
trainer = Trainer(
model_init=get_model,
args=training_args,
train_dataset=chunked_encoded_dataset['train'],
eval_dataset=chunked_encoded_dataset['validation'],
compute_metrics=compute_metrics
)
tune_config = {
"per_device_train_batch_size": 32,
"per_device_eval_batch_size": 32,
"num_train_epochs": tune.choice([2, 3, 4, 5])
}
scheduler = PopulationBasedTraining(
time_attr="training_iteration",
metric="eval_acc",
mode="max",
perturbation_interval=1,
hyperparam_mutations={
"weight_decay": tune.uniform(0.0, 0.3),
"learning_rate": tune.uniform(1e-5, 2.5e-5),
"per_device_train_batch_size": [16, 32, 64],
})
reporter = CLIReporter(
parameter_columns={
"weight_decay": "w_decay",
"learning_rate": "lr",
"per_device_train_batch_size": "train_bs/gpu",
"num_train_epochs": "num_epochs"
},
metric_columns=[
"eval_f1", "eval_loss", "epoch", "training_iteration"
])
from ray.tune.integration.wandb import WandbLogger
trainer.hyperparameter_search(
hp_space=lambda _: tune_config,
backend="ray",
n_trials=10,
scheduler=scheduler,
keep_checkpoints_num=1,
checkpoint_score_attr="training_iteration",
progress_reporter=reporter,
name="tune_transformer_gr")
Последний вызов функции (в trainer.hyperparameter_search) происходит при возникновении ошибки. Сообщение об ошибке:
AttributeError: модуль pickle не имеет атрибута PickleBuffer
А вот полная трассировка стека:
AttributeError Traceback (последний вызов последним)
in ()8 checkpoint_score_attr ="training_iteration",9 progress_reporter = reporter, ---> 10 name="tune_transformer_gr")
14 кадров
/usr/local/lib/python3.7/dist-packages/transformers/trainer.py в hyperparameter_search (self, hp_space, compute_objective, n_trials,direction, backend, hp_name, **kwargs) 1666 1667
run_hp_search = run_hp_search_optuna, если back HPSearchBackend.OPTUNA else run_hp_search_ray-> 1668 best_run = run_hp_search(self, n_trials, direction, **kwargs) 1669 1670 self.hp_search_backend = Нет/usr/local/lib/python3.7/dist-packages/transformers/integrations.py в run_hp_search_ray (трейнер, n_trials, direction, **kwargs)231232 analysis = ray.tune.run(-> 233 ray.tune .with_parameters(_objective, local_trainer=trainer),234 config = trainer.hp_space (None),235 num_samples=n_trials,
/usr/local/lib/python3.7/dist-packages/ray/tune/utils/trainable.py в with_parameters(обучаемый, **kwargs)294 prefix = f"{str(trainable)}_"295 для k, v в kwargs.items (): -> 296 parameter_registry.put(prefix + k, v)297298 trainable_name = getattr(обучаемый, " имя ", "tune_with_parameters")
/usr/local/lib/python3.7/dist-packages/ray/tune/registry.py in put (self, k, v)160 self.to_flush [k] = v161 if ray.is_initialized():-> 162 self.flush ()163164 def get(self, k):
/usr/local/lib/python3.7/dist-packages/ray/tune/registry.py в flush (self)169 def flush(self):170 для k, v в self.to_flush.items (): - > 171 self.references [k] = ray.put(v)172 self.to_flush.clear ()173
/usr/local/lib/python3.7/dist-packages/ray/_private/client_mode_hook.py в оболочке (*args, **kwargs)45 if client_mode_should_convert():46 return getattr (ray, func.name)(*args, **kwargs)---> 47 return func (*args, **kwargs)4849 возвратная оболочка
/usr/local/lib/python3.7/dist-packages/ray/worker.py in put (value)
1512 with profiling.profile("ray.put"): 1513 try:-> 1514 object_ref = worker.put_object( значение) 1515 кроме ObjectStoreFullError: 1516 logger.info (/usr/local/lib/python3.7/dist-packages/ray/worker.py в put_object(self, value, object_ref)259 «вставка с ObjectRef») 260 -> 261 serialized_value = self.get_serialization_context().serialize(value)262 # Это должно быть первое место, где мы создаем этот python 263 # ObjectRef, потому что запись с 0 локальными ссылками создается, когда
/usr/local/lib/python3.7/dist-packages/ray/serialization.py в сериализации (self, value)322 return RawSerializedObject(value)323 else:-> 324 return self._serialize_to_msgpack(value)
/usr/local/lib/python3.7/dist-packages/ray/serialization.py в _serialize_to_msgpack(self, value)302 метаданные = ray_constants.OBJECT_METADATA_TYPE_PYTHON303 pickle5_serialized_object =
-> 304 self._patalethon_to :306 pickle5_serialized_object = Нет/usr/local/lib/python3.7/dist-packages/ray/serialization.py в _serialize_to_pickle5(self, metadata, value)262 за исключением Exception как e:263 self.get_and_clear_conhibited_object_refs()-> 264, наконец, поднимите e 265:266 self.set_out_of_band_serialization()
/usr/local/lib/python3.7/dist-packages/ray/serialization.py в _serialize_to_pickle5(self, metadata, value)259 self.set_in_band_serialization()260 inband = pickle.dumps(-> значение 261, протокол =5, buffer_callback=writer.buffer_callback)262, кроме Exception как e:263 self.get_and_clear_conhibited_object_refs()
/usr/local/lib/python3.7/dist-packages/ray/cloudpickle/cloudpickle_fast.py в дампах (obj, protocol, buffer_callback)71 файл, protocol = protocol, buffer_callback = buffer_callback 72)---> 73 cp. дамп (объект) 74 return file.getvalue () 75
/usr/local/lib/python3.7/dist-packages/ray/cloudpickle/cloudpickle_fast.py в дампе (self, obj)578 def dump(self, obj):579 try:-> 580 return Pickler.dump(self, obj)581, кроме RuntimeError как e:582, если "рекурсия" в e.args [0]:
/usr/local/lib/python3.7/dist-packages/pyarrow/io.pxi в pyarrow.lib.Buffer.reduce_ex()
AttributeError: модуль pickle не имеет атрибута PickleBuffer
Настройка моей среды:
- Я использую Google Colab
- Платформа: Linux-5.4.109+-x86_64-with-Ubuntu-18.04-bionic
- Версия Python: 3.7.10
- Версия трансформаторов: 4.6.1
- версия ray: 1.3.0
Что я пробовал:
- Обновление рассола
- Установлен и импортирован pickle5 как рассол
- Убедился, что у меня нет файла python с именем 'pickle' в моем непосредственном каталоге.
Откуда эта ошибка и как ее исправить?[1]: https://docs.ray.io/en/master/tune/examples/pbt_transformers.html
3 ответа
У меня была такая же ошибка при попытке использовать pickle.dump(), для меня это сработало, чтобы понизить версию pickle5 с версии 0.0.11 до 0.0.10.
Я также столкнулся с этой ошибкой в Google Colab, пытаясь выполнить поиск гиперпараметров с настройкой лучей с помощью преобразователей Huggingface.
Это помогло мне:
!pip install pickle5
затем
import pickle5 as pickle
После первого запуска появится предупреждение о перезагрузке ноутбука и та же ошибка. После второго «Перезагрузить и запустить все» начинается поиск гиперпараметров настройки луча.
Не «настоящее» решение, но, по крайней мере, обходной путь. Для меня эта проблема возникла на Python 3.7. Переход на Python 3.8 решил проблему.