PyTorch — ошибка времени выполнения: [принудительный сбой в inline_container.cc: 209] . файл не найден: архив/data.pkl

#python #pytorch #pickle

#python #pytorch #рассол

Вопрос:

Проблема

Я пытаюсь загрузить файл с помощью PyTorch, но состояния ошибки archive/data.pkl не существует.

Код

 import torch
cachefile = 'cacheddata.pth'
torch.load(cachefile)
  

Вывод

 ---------------------------------------------------------------------------
RuntimeError                              Traceback (most recent call last)
<ipython-input-4-8edf1f27a4bd> in <module>
      1 import torch
      2 cachefile = 'cacheddata.pth'
----> 3 torch.load(cachefile)

~/opt/anaconda3/envs/matching/lib/python3.8/site-packages/torch/serialization.py in load(f, map_location, pickle_module, **pickle_load_args)
    582                     opened_file.seek(orig_position)
    583                     return torch.jit.load(opened_file)
--> 584                 return _load(opened_zipfile, map_location, pickle_module, **pickle_load_args)
    585         return _legacy_load(opened_file, map_location, pickle_module, **pickle_load_args)
    586 

~/opt/anaconda3/envs/matching/lib/python3.8/site-packages/torch/serialization.py in _load(zip_file, map_location, pickle_module, **pickle_load_args)
    837 
    838     # Load the data (which may in turn use `persistent_load` to load tensors)
--> 839     data_file = io.BytesIO(zip_file.get_record('data.pkl'))
    840     unpickler = pickle_module.Unpickler(data_file, **pickle_load_args)
    841     unpickler.persistent_load = persistent_load

RuntimeError: [enforce fail at inline_container.cc:209] . file not found: archive/data.pkl
  

Гипотеза

Я предполагаю, что это как-то связано с pickle, из документов:

Этот процесс сохранения / загрузки использует наиболее интуитивно понятный синтаксис и требует наименьшего объема кода. Сохранение модели таким образом сохранит весь модуль, используя модуль pickle Python. Недостатком этого подхода является то, что сериализованные данные привязаны к определенным классам и точной структуре каталогов, используемой при сохранении модели. Причина этого в том, что pickle не сохраняет сам класс модели. Скорее, он сохраняет путь к файлу, содержащему класс, который используется во время загрузки. Из-за этого ваш код может по-разному ломаться при использовании в других проектах или после рефакторинга.

Версии

  • Версия PyTorch: 1.6.0
  • Версия Python: 3.8.0

Ответ №1:

Оказалось, что файл был каким-то образом поврежден. После повторной генерации он загрузился без проблем.

Комментарии:

1. У меня возникла эта проблема именно по этой причине: частой причиной этого может быть прерывание процесса обучения модели (Ctrl-C, прерывание планировщиком заданий из-за нехватки времени и т. Д.), Пока вы находитесь в процессе записи в файловую систему.

Ответ №2:

Я столкнулся с той же проблемой. Я напрямую загрузил модель ( .pt ), обученную с помощью графического процессора, из ноутбука на платформе GCP AI. Когда я загрузил его по локальной torch.load('models/model.pt', map_location=device) сети, я получил эту ошибку:

 RuntimeError: [enforce fail at inline_container.cc:145] . PytorchStreamReader failed reading zip archive: failed finding central directory`.
  

Я заметил, что размер загруженного файла намного меньше, чем ожидалось. Так же, как и @Ian, оказалось, что файл был поврежден при загрузке из ноутбука. Наконец, мне пришлось сначала перенести файл из записной книжки в корзину в облачном хранилище Google (GCS) вместо того, чтобы загружать его напрямую, а затем загрузить файл из GCS. Теперь это работает.

Ответ №3:

Я столкнулся с этой проблемой не для одного файла, а последовательно для любого файла, с которым я имел дело. Глядя на размер файла, вы могли бы сказать, что они были повреждены, в том смысле, что они были слишком маленькими и неполными, но почему они всегда создавались таким образом?

Я думаю, проблема заключалась в том, что я внес безвредную модификацию в простой класс, который я сохранял. Итак, как я создал класс Foo , сохранил данные без изменений, но добавил некоторый метод, затем попытался сохранить более старый экземпляр, когда у меня было только более новое определение класса Foo .

Вот пример того, что, я думаю, произошло, но он не воспроизводит его в точности:

 class Foo(object):
  def __init__(self):
    self.contents = [1,2,3]
    
torch.save(Foo(), "foo1.pth")

foo1 = torch.load("foo1.pth") # saved with class version 1 of Foo

# some days later the code looks like this
class Foo(object):
  def __init__(self):
    self.contents = [1,2,3]
  def __len__(self):
    return len(self.contents)

foo1 = torch.load("foo1.pth") # still works
torch.save(foo1, "foo2.pth") # try to save version 1 object where class is no longer known
  

В первый раз я получил сообщение об ошибке PicklingError: Can't pickle <class '__main__.Foo'>: it's not the same object as __main__.Foo , но при использовании функции автоматической загрузки Jupyter Notebook трудно сказать, что именно произошло.
Обычно старые классы могут быть загружены в новые определения классов без проблем.

В любом случае, что действительно произошло, мое решение состояло в том, чтобы загрузить старую версию и вручную скопировать поля данных в недавно созданную версию Foo , например:

 old = torch.load("foo1.pth")
new = Foo()
# new = old # this was the code that caused issues
new.contents = old.contents
torch.save(new, "foo2.pth")
  

Ответ №4:

В моем случае основной причиной этой ошибки был .pt поврежден файл. Я начал загружать файл, когда файл все еще создавался.

Итак, чтобы избежать ошибки, скопируйте .pt файл в другой каталог и загрузите .pt файл из этого каталога.

Ответ №5:

В моем случае мой диск был заполнен.

Комментарии:

1. На самом деле, это была моя проблема!

2. Это было очень полезно, и из сообщения об ошибке не очевидно, что основной причиной был полный жесткий диск.