Google Cloud ML 的存储 (gs) 包装文件 input/out?
Google Storage (gs) wrapper file input/out for Cloud ML?
Google 最近宣布了 Clould ML,https://cloud.google.com/ml/ 它非常有用。但是,一个限制是 Tensorflow 程序的 input/out 应该支持 gs://.
如果我们将所有 tensorflow APIS 用于 read/write 文件,应该没问题,因为这些 API 支持 gs://
。
但是,如果我们使用open
等本地文件IO API,它就不起作用,因为他们不理解gs://
例如:
with open(vocab_file, 'wb') as f:
cPickle.dump(self.words, f)
此代码在 Google Cloud ML 中无效。
但是,将所有原生文件IO API 修改为tensorflow API 或Google Storage Python API 确实很繁琐。有什么简单的方法可以做到这一点吗?支持 google 存储系统的任何包装器,gs://
在本机文件 IO 之上?
正如这里所建议的,也许我们可以使用file_io.read_file_to_string('gs://...')
,但这仍然需要大量的代码修改。
一种解决方案是在程序启动时将所有数据复制到本地磁盘。您可以在获取 运行 的 Python 脚本中使用 gsutil 来做到这一点,例如:
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 读取之前执行此操作。
apache_beam has the gcsio 模块,可用于 return 标准 Python 文件对象到 read/write 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)
这样做:
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)
Google 最近宣布了 Clould ML,https://cloud.google.com/ml/ 它非常有用。但是,一个限制是 Tensorflow 程序的 input/out 应该支持 gs://.
如果我们将所有 tensorflow APIS 用于 read/write 文件,应该没问题,因为这些 API 支持 gs://
。
但是,如果我们使用open
等本地文件IO API,它就不起作用,因为他们不理解gs://
例如:
with open(vocab_file, 'wb') as f:
cPickle.dump(self.words, f)
此代码在 Google Cloud ML 中无效。
但是,将所有原生文件IO API 修改为tensorflow API 或Google Storage Python API 确实很繁琐。有什么简单的方法可以做到这一点吗?支持 google 存储系统的任何包装器,gs://
在本机文件 IO 之上?
正如这里file_io.read_file_to_string('gs://...')
,但这仍然需要大量的代码修改。
一种解决方案是在程序启动时将所有数据复制到本地磁盘。您可以在获取 运行 的 Python 脚本中使用 gsutil 来做到这一点,例如:
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 读取之前执行此操作。
apache_beam has the gcsio 模块,可用于 return 标准 Python 文件对象到 read/write 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)
这样做:
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)