Ошибка ввода-вывода функции загрузки sklearn joblib из AWS S3

Я пытаюсь загрузить pkl-дамп моего классификатора из sklearn-learn.

Дамп joblib обеспечивает гораздо лучшее сжатие, чем дамп cPickle для моего объекта, поэтому я хотел бы его придерживаться. Однако я получаю сообщение об ошибке при попытке прочитать объект из AWS S3.

Случаи:

  • Объект Pkl размещен локально: pickle.load работает, joblib.load работает
  • Объект Pkl помещен в Heroku с помощью приложения (загрузка из статической папки): pickle.load работает, joblib.load работает
  • Объект Pkl помещен в S3: pickle.load работает, joblib.load возвращает IOError. (тестирование из приложения heroku и тестирование из локального скрипта)

Обратите внимание, что объекты pkl для joblib и pickle - это разные объекты, сбрасываемые соответствующими методами. (т.е. joblib загружает только joblib.dump (obj), а pickle загружает только cPickle.dump (obj).

Joblib против кода cPickle

# case 2, this works for joblib, object pushed to heroku
resources_dir = os.getcwd() + "/static/res/" # main resource directory
input = joblib.load(resources_dir + 'classifier.pkl')

# case 3, this does not work for joblib, object hosted on s3
aws_app_assets = "https://%s.s3.amazonaws.com/static/res/" % keys.AWS_BUCKET_NAME
classifier_url_s3 = aws_app_assets + 'classifier.pkl'

# does not work with raw url, IO Error
classifier = joblib.load(classifier_url_s3)

# urrllib2, can't open instance
# TypeError: coercing to Unicode: need string or buffer, instance found
req = urllib2.Request(url=classifier_url_s3)
f = urllib2.urlopen(req)
classifier = joblib.load(urllib2.urlopen(classifier_url_s3))

# but works with a cPickle object hosted on S3
classifier = cPickle.load(urllib2.urlopen(classifier_url_s3))

Мое приложение отлично работает в случае 2, но из-за очень медленной загрузки я хотел попробовать отправить все статические файлы на S3, особенно эти дампы рассола. Есть ли что-то принципиально иное в способе загрузки joblib и pickle, что могло бы вызвать эту ошибку?

Это моя ошибка

File "/usr/local/lib/python2.7/site-packages/sklearn/externals/joblib/numpy_pickle.py", line 409, in load
with open(filename, 'rb') as file_handle:
IOError: [Errno 2] No such file or directory: classifier url on s3
[Finished in 0.3s with exit code 1]

Это не проблема с разрешениями, поскольку я сделал все свои объекты на s3 общедоступными для тестирования, и объекты pickle.dump загружаются нормально. Объект joblib.dump также загружается, если я напрямую ввожу URL-адрес в браузер.

Я мог чего-то полностью упустить.

Спасибо.


person Jasmine    schedule 26.08.2015    source источник


Ответы (1)


joblib.load () ожидает имя файла, присутствующего в файловой системе.

Signature: joblib.load(filename, mmap_mode=None)
Parameters
-----------
filename: string
    The name of the file from which to load the object

Более того, публикация всех ваших ресурсов может быть плохой идеей для других активов, даже если вы не возражаете против того, чтобы маринованная модель была доступна миру.

Достаточно просто сначала скопировать объект из S3 в локальную файловую систему вашего воркера:

from boto.s3.connection import S3Connection
from sklearn.externals import joblib
import os

s3_connection = S3Connection(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY)
s3_bucket = s3_connection.get_bucket(keys.AWS_BUCKET_NAME)
local_file = '/tmp/classifier.pkl'
s3_bucket.get_key(aws_app_assets + 'classifier.pkl').get_contents_to_filename(local_file)
clf = joblib.load(local_file)
os.remove(local_file)

Надеюсь, это помогло.

P.S. вы можете использовать этот подход для маринования всего sklearn конвейера. Это включает также вменение признаков. Только остерегайтесь конфликтов версий библиотек между обучением и прогнозированием.

person volodymyr    schedule 03.09.2015
comment
Спасибо, этого и ожидалось. Я посмотрел на исходный код и увидел приведенное выше, но не понял, что это означает, что это должно быть путь относительно файловой системы. - person Jasmine; 03.09.2015
comment
У меня есть аналогичная версия, в которой также используется tempfile для более безопасного создания временных файлов: stackoverflow.com/questions/56571731/ - person Alexei Andreev; 24.09.2019