Ввод/вывод файла оболочки Google Storage (gs) для Cloud ML?
Недавно Google анонсировал Clould ML, https://cloud.google.com/ml/, и это очень полезно. Однако одно ограничение заключается в том, что вход/выход из программы Tensorflow должен поддерживать gs://.
Если мы используем все APS-анализаторы для чтения/записи, это должно быть ОК, так как эти API поддерживают gs://
.
Однако, если мы используем API-интерфейсы IO собственного файла, такие как open
, это не работает, потому что они не понимают gs://
Например:
with open(vocab_file, 'wb') as f:
cPickle.dump(self.words, f)
Этот код не будет работать в Google Cloud ML.
Тем не менее, изменение всех API-интерфейсов основных файлов я в API-интерфейсах tensorflow или API-интерфейсах Google Python очень утомительно. Есть ли простой способ сделать это? Любые обертки для поддержки систем хранения Google, gs://
поверх собственного файла IO?
Как предложено здесь Масленичная разреженная матрица в качестве входных данных?, возможно, мы можем использовать file_io.read_file_to_string('gs://...')
, но все же это требует значительного модификации кода.
Ответы
Ответ 1
Одним из решений является копирование всех данных на локальный диск при запуске программы. Вы можете сделать это с помощью gsutil внутри Python script, который запускается, что-то вроде:
vocab_file = 'vocab.pickled'
subprocess.check_call(['gsutil', '-m' , 'cp', '-r',
os.path.join('gs://path/to/', vocab_file), '/tmp'])
with open(os.path.join('/tmp', vocab_file), 'wb') as f:
cPickle.dump(self.words, f)
И если у вас есть какие-либо выходы, вы можете записать их на локальный диск и gsutil rsync
их. (Но будьте осторожны, чтобы правильно обрабатывать перезагрузки, потому что вы можете быть на другой машине).
Другим решением является патч обезьяны open
(Примечание: непроверенный):
import __builtin__
# NB: not all modes are compatible; should handle more carefully.
# Probably should be reported on
# https://github.com/tensorflow/tensorflow/issues/4357
def new_open(name, mode='r', buffering=-1):
return file_io.FileIO(name, mode)
__builtin__.open = new_open
Просто обязательно сделайте это, прежде чем какой-либо модуль попытается прочитать из GCS.
Ответ 2
Сделайте это так:
from tensorflow.python.lib.io import file_io
with file_io.FileIO('gs://.....', mode='w+') as f:
cPickle.dump(self.words, f)
Или вы можете прочитать файл pickle следующим образом:
file_stream = file_io.FileIO(train_file, mode='r')
x_train, y_train, x_test, y_test = pickle.load(file_stream)
Ответ 3
apache_beam имеет gcsio модуль который может быть использован для возврата стандартного файлового объекта Python для чтения/записи объектов GCS. Вы можете использовать этот объект любым способом, который работает с файловыми объектами Python. Например
def open_local_or_gcs(path, mode):
"""Opens the given path."""
if path.startswith('gs://'):
try:
return gcsio.GcsIO().open(path, mode)
except Exception as e: # pylint: disable=broad-except
# Currently we retry exactly once, to work around flaky gcs calls.
logging.error('Retrying after exception reading gcs file: %s', e)
time.sleep(10)
return gcsio.GcsIO().open(path, mode)
else:
return open(path, mode)
with open_local_or_gcs(vocab_file, 'wb') as f:
cPickle.dump(self.words, f)