如何在最新的 Tensorflow 2.6.0 中访问 HDFS 文件系统?

How can I access to HDFS file system in the latest Tensorflow 2.6.0?

我最近将我程序中使用的tensorflow版本升级到最近发布的2.6.0,但是我运行遇到了麻烦

import tensorflow as tf

pattern = 'hdfs://mypath'
print(tf.io.gfile.glob(pattern))

以上API在2.6版本中抛出异常:

tensorflow.python.framework.errors_impl.UnimplementedError: File system scheme'hdfs' not implemented (file:xxxxx)

然后我查看了relevant implementation code,发现官方推荐使用tensorflow/io来访问hdfs,并且提供了环境变量TF_USE_MODULAR_FILESYSTEM来使用legacy access support。由于我的代码比较复杂,短时间内难以重构,所以尝试使用这个环境变量,还是失败了。

总的来说,我的问题是:

  1. 在最新版本的tensorflow中,如果不使用“tfio”,我如何访问HDFS文件?
  2. 如果必须使用“tfio”,tf.io.gfile.glob 的等效代码调用是什么?

TL.DR。安装 tensorflow-io 并导入它 .

经过一番折腾,找到了解决办法(可能是官方推荐的方式):

从v2.6.0开始,Tensorflow不再在框架中提供HDFS、GCS等文件系统支持,而是将这些支持转移到Tensorflow/IO项目中。

因此,在以后的版本中,要有HDFS、GCS等文件系统的支持,只需要安装tensorflow-io并导入到训练程序中即可

$ pip install tensorflow-io

$ cat test.py
import tensorflow as tf
import tensorflow_io as tfio

print(tf.io.gfile.glob('hdfs://...'))

$ CLASSPATH=$(${HADOOP_HOME}/bin/hadoop classpath --glob) python test.py

会加载libtensorflow_io.so和libtensorflow_io_plugins.so,里面包含了各个extras文件系统的实现和注册逻辑:

# tensorflow_io/python/ops/__init__.py
core_ops = LazyLoader("core_ops", "libtensorflow_io.so")
try:
    plugin_ops = _load_library("libtensorflow_io_plugins.so", "fs")
except NotImplementedError as e:
    warnings.warn("unable to load libtensorflow_io_plugins.so: {}".format(e))
    # Note: load libtensorflow_io.so imperatively in case of statically linking
    try:
        core_ops = _load_library("libtensorflow_io.so")
        plugin_ops = _load_library("libtensorflow_io.so", "fs")
    except NotImplementedError as e:
        warnings.warn("file system plugins are not loaded: {}".format(e))

参考: