2016-11-03 4 views
8

Google недавно объявил Clould ML, https://cloud.google.com/ml/, и это очень полезно. Однако одним из ограничений является то, что вход/выход программы Tensorflow должен поддерживать gs: //.Ввод/вывод файла оболочки Google Storage (gs) для Cloud ML?

Если мы используем все APS-анализаторы для чтения/записи, это должно быть ОК, поскольку эти API поддерживают gs://.

Однако, если мы будем использовать исходный файл IO API, такие как open, он не работает, потому что они не понимают gs://

Например:

with open(vocab_file, 'wb') as f: 
     cPickle.dump(self.words, f) 

Этот код не будет работать в Google Cloud ML.

Однако изменение всех API-интерфейсов IO для файловых полей для API-интерфейсов tendorflow или API-интерфейсов Google Storage Python действительно утомительно. Есть ли простой способ сделать это? Любые обертки для поддержки систем хранения google, gs:// поверх собственного файла IO?

Как предложено здесь Pickled scipy sparse matrix as input data?, возможно, мы можем использовать file_io.read_file_to_string('gs://...'), но все же это требует значительного модификации кода.

ответ

4

Одним из решений является копирование всех данных на локальный диск при запуске программы. Вы можете сделать это с помощью GSUtil внутри сценария Python, который запускаемый, что-то вроде:

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 

Просто убедитесь, что сделать это прежде, чем любой модуль на самом деле пытается прочитать из ГКС.

1

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) 
+0

Спасибо! Это выглядит очень хорошо. Я думаю, что Tensorflow file_io также может быть решением. 'с file_io.FileIO (file_path, mode =" w ") как f'. Считаете ли вы, что это тоже нормально? Я еще не полностью тестировал. –

+2

Я интерпретировал ваш вопрос как желающий избежать необходимости заменять все вызовы функций open() специализированными функциями. Если это не так, то есть вы хотите заменить вызовы на open(), то gcsio.open_local_or_gcs и file_io.FileIO довольно похожи, просто влияют на зависимости, которые вы вносите - file_io уже входит в TF. Но FileIO использует некоторые нестандартные режимы, поэтому это может повлиять и на ваше решение. – rhaertel80

3

Делают это так:

from tensorflow.python.lib.io import file_io 

with file_io.FileIO('gs://.....', mode='w+') as f: 
    cPickle.dump(self.words, f) 

Или вы можете прочитать рассол файл в следующим образом:

file_stream = file_io.FileIO(train_file, mode='r') 
x_train, y_train, x_test, y_test = pickle.load(file_stream) 
Смежные вопросы