背景

TensorFlow 框架通常用在多进程和多机器环境(例如 Google 数据中心、Google Cloud Machine Learning、Amazon Web Services (AWS) 和现场分布式聚类)中。为了共享和保存 TensorFlow 生成的某些类型的状态,该框架会假定存在可靠的共享文件系统。这个共享文件系统具有诸多用途,例如:

  • 状态检查点通常会保存到分布式文件系统中,以实现可靠性和容错能力

  • 训练流程通过将事件文件写入受 TensorBoard 监视的目录,与 TensorBoard 通信。即使 TensorBoard 在不同的进程或机器中运行,共享文件系统也允许进行此通信

在现实世界中有许多不同的共享或分布式文件系统实现,因此 TensorFlow 使用户能够实现可向 TensorFlow 运行时注册的自定义文件系统插件。当 TensorFlow 运行时尝试通过 FileSystem 接口写入文件时,它会根据路径名的一部分动态选择应该用于文件系统操作的实现。因此,添加对自定义文件系统的支持需要实现 FileSystem 接口,编译包含该实现的共享对象,并在运行时在需要写入该文件系统的任何进程中加载该对象。

请注意,TensorFlow 已包含很多文件系统实现,例如:

  • 标准 POSIX 文件系统

    注意:NFS 文件系统通常作为 POSIX 接口装载,因此标准 TensorFlow 可以在 NFS 装载的远程文件系统上运行

  • HDFS - Hadoop 文件系统

  • GCS - Google Cloud Storage 文件系统

  • S3 - Amazon Simple Storage Service 文件系统

  • “内存映射文件” 文件系统

本指南的其余部分介绍了如何实现自定义文件系统。

实现自定义文件系统插件

要实现自定义文件系统插件,您必须执行以下操作:

  • 实现 RandomAccessFile、WriteableFile、AppendableFile 和 ReadOnlyMemoryRegion 的子类

  • 实现 FileSystem 接口(作为子类)

  • 使用适当的前缀模式注册 FileSystem 实现

  • 在需要写入该文件系统的进程中加载文件系统插件

FileSystem 接口

FileSystem 接口是在 file_system.h 中定义的抽象 C++ 接口。FileSystem 接口的实现应该实现该接口定义的所有相关方法。实现该接口需要定义一些操作,例如创建 RandomAccessFile 和 WritableFile,以及实现诸如 FileExists、IsDirectory、GetMatchingPaths、DeleteFile 等标准文件系统操作。这些接口的实现通常涉及将函数的输入参数转换为委托到已存在的库函数(实现自定义文件系统中的等效功能)。

例如,PosixFileSystem 实现会使用 POSIX unlink() 函数实现 DeleteFile;CreateDir 直接调用 mkdir();GetFileSize 涉及对文件调用 stat(),然后返回 stat 对象返回的结果报告的文件大小。同样,对于 HDFSFileSystem实现,这些调用只是委托到类似功能的 libHDFS 实现,例如为 DeleteFile 委托到 hdfsDelete。

建议您查看这些代码示例,了解不同的文件系统实现如何调用其现有库。例如:

  • POSIX 插件

    (https://github.com/tensorflow/tensorflow/blob/master/tensorflow/core/platform/posix/posix_file_system.h?hl=zh-CN)

  • HDFS 插件

    (https://github.com/tensorflow/tensorflow/blob/master/tensorflow/core/platform/hadoop/hadoop_file_system.h?hl=zh-CN)

  • GCS 插件

    (https://github.com/tensorflow/tensorflow/blob/master/tensorflow/core/platform/cloud/gcs_file_system.h?hl=zh-CN)

  • S3 插件

    (https://github.com/tensorflow/tensorflow/blob/master/tensorflow/core/platform/s3/s3_file_system.h?hl=zh-CN)

File 接口

除了允许您查询和操作文件系统中的文件和目录的操作之外,FileSystem 接口还要求您实现返回抽象对象(例如 RandomAccessFile 和 WritableFile)实现的工厂,以便 TensorFlow 代码读取和写入该 FileSystem 实现中的文件。

要实现 RandomAccessFile,您必须实现一个名为 Read() 的接口,相应实现必须在其中提供一种读取指定文件中的偏移量的方法。

例如,下面是 POSIX 文件系统的 RandomAccessFile 实现,它使用 pread() 随机访问 POSIX 函数来实现读取操作。请注意,特定实现必须知道如何从底层文件系统重试或传播错误。

class PosixRandomAccessFile : public RandomAccessFile {
     public:
      PosixRandomAccessFile(const string& fname, int fd)
          : filename_(fname), fd_(fd) {}
      ~PosixRandomAccessFile() override { close(fd_); }
      Status Read(uint64 offset, size_t n, StringPiece* result,
                  char* scratch) const override {
        Status s;
        char* dst = scratch;
        while (n > 0 && s.ok()) {
          ssize_t r = pread(fd_, dst, n, static_cast(offset));
          if (r > 0) {
            dst += r;
            n -= r;
            offset += r;
          } else if (r == 0) {
            s = Status(error::OUT_OF_RANGE, "Read less bytes than requested");
          } else if (errno == EINTR || errno == EAGAIN) {
            // Retry
          } else {
            s = IOError(filename_, errno);
          }
        }
        *result = StringPiece(scratch, dst - scratch);
        return s;
      }
     private:
      string filename_;
      int fd_;
    };

要实现 WritableFile 顺序写入抽象功能,必须实现一些接口,例如 Append()、Flush()、Sync() 和 Close()。

例如,下面是 POSIX 文件系统的 WritableFile 实现,它会在其构造函数中接受 FILE 对象,并在该对象上使用标准 posix 函数来实现接口。

class PosixWritableFile : public WritableFile {
     public:
      PosixWritableFile(const string& fname, FILE* f)
          : filename_(fname), file_(f) {}
      ~PosixWritableFile() override {
        if (file_ != NULL) {
          fclose(file_);
        }
      }
      Status Append(const StringPiece& data) override {
        size_t r = fwrite(data.data(), 1, data.size(), file_);
        if (r != data.size()) {
          return IOError(filename_, errno);
        }
        return Status::OK();
      }
      Status Close() override {
        Status result;
        if (fclose(file_) != 0) {
          result = IOError(filename_, errno);
        }
        file_ = NULL;
        return result;
      }
      Status Flush() override {
        if (fflush(file_) != 0) {
          return IOError(filename_, errno);
        }
        return Status::OK();
      }
      Status Sync() override {
        Status s;
        if (fflush(file_) != 0) {
          s = IOError(filename_, errno);
        }
        return s;
      }
     private:
      string filename_;
      FILE* file_;
    };

有关更多详情,请参阅这些接口的文档,并查看示例实现以获得启发。

注册并加载文件系统

为自定义文件系统实现了 FileSystem 实现后,您需要在 “架构” 下注册它,以便将以该架构为前缀的路径定向到您的实现。为此,您应调用 REGISTER_FILE_SYSTEM:

REGISTER_FILE_SYSTEM("foobar", FooBarFileSystem);

当 TensorFlow 尝试对其路径以 foobar:// 开头的文件执行操作时,它将使用 FooBarFileSystem 实现。

string filename = "foobar://path/to/file.txt";
    std::unique_ptr file;
    // Calls FooBarFileSystem::NewWritableFile to return
    // a WritableFile class, which happens to be the FooBarFileSystem's
    // WritableFile implementation.
    TF_RETURN_IF_ERROR(env->NewWritableFile(filename, &file));

接下来,您必须编译包含此实现的共享对象。您可以在 此处 找到使用 bazel 的 cc_binary 规则执行此操作的示例,但您也可以使用任何编译系统执行此操作。有关类似说明,请参阅 编译操作库 部分(https://tensorflow.google.cn/guide/extend/adding_an_op?hl=zh-CN#build_the_op_library)。

注:此处 链接

https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/BUILD?hl=zh-CN#L244

编译此目标会生成 .so 共享对象文件。

最后,您必须在进程中动态加载此实现。在 Python 中,您可以调用 tf.load_file_system_library(file_system_library) 函数,并将路径传递给共享对象。在客户端程序中调用此函数会加载进程中的共享对象,从而将您的实现注册为可用于通过 FileSystem 接口的所有文件操作。您可以查看 test_file_system.py 了解示例(https://github.com/tensorflow/tensorflow/blob/master/tensorflow/python/framework/file_system_test.py?hl=zh-CN)。

哪些操作会使用此接口?

TensorFlow 中的几乎所有核心 C++ 文件操作(例如 CheckpointWriter、EventsWriter)以及许多其他实用程序都使用 FileSystem 接口。这意味着实现 FileSystem 实现可以让大多数 TensorFlow 程序写入共享文件系统。

在 Python 中,gfile 和 file_io 类通过 SWIG 绑定到 FileSystem 实现,这意味着在加载了此文件系统库后,您便可以运行以下命令:

with gfile.Open("foobar://path/to/file.txt") as w:
  w.write("hi")

运行此命令时,包含 “hi” 的文件将出现在共享文件系统的“/path/to/file.txt”中。

更多 AI 相关阅读:

  • TensorFlow 的 C++ API

  • 采用其他编程语言的 TensorFlow

  • 在 TensorFlow Probability 中对结构时间序列建模

tensorflow保存内容到相对文件路径下_如何添加自定义文件系统插件相关推荐

  1. CMD查看当前文件路径下的所有文件名

    介绍 我们知道Linux系统下查看当前文件路径下的所有文件名,可以用ls或ll来查看,那么CMD中怎么查看当前路径下的所有文件呢? 方案 使用 dir 命令即可 效果如下:

  2. python文件保存在哪里_Python文件路径是什么?怎么写?

    我们经常要进行导入文件的操作,用python是个不错的选择.保存之后的文件都有一个专属地址,也就是我们所说的路径.如果有的小伙伴有保存记录的习惯,还是比较容易下次翻阅.有时候一些小伙伴迷迷糊糊,随便保 ...

  3. php遍历文件夹下文件内容_php遍历文件夹下所有文件的代码示例

    本篇文章给大家带来的内容是关于php遍历文件夹下所有文件的代码示例,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 不论是面试还是正常工作需要都会用到遍历文件夹下的所有文件,今天就记录 ...

  4. python遍历读取文件夹下所有文件内容_python遍历文件夹下所有文件

    python遍历文件夹下所有文件的方法:首先打开相应的代码文件:然后通过"for f in files:print(os.path.join(root, f))"方式遍历所有的文件 ...

  5. linux ext3 大文件,Linux下Ext2与Ext3文件系统

    Linux下的Ext2文件系统,是 GNU/Linux 系统中标准的文件系统,其特点为存取文件的性能极好,对于中小型的文件更显示出优势,这主要得利于其簇快取层的优良设计. Ext3文件系统,它属于一种 ...

  6. python文件路径过滤器_自定义过滤器及标签

    代码布局(自定义的代码,放在哪里) 1,某个app特有的 --app目标下,templateags 文件夹 --再到ttemplateags 文件夹下创建python模块(py文件) 2,定义复用 - ...

  7. android 有道笔记 装在哪个目录,有道云笔记文件保存在哪里在哪个路径下

    有道云笔记是一款非常好用的云共享笔记,经常有网友使用有道云笔记进行文件.网页等资料的保存.不过,一些刚使用这款软件的网友,还不是很清楚这款软件的保存路径.今天小编就分别讲解一下有道云笔记桌面版.And ...

  8. 有道云笔记Android app离线缓存,有道云笔记文件保存在哪里在哪个路径下

    有道云笔记是一款非常好用的云共享笔记,经常有网友使用有道云笔记进行文件.网页等资料的保存.不过,一些刚使用这款软件的网友,还不是很清楚这款软件的保存路径.今天小编就分别讲解一下有道云笔记桌面版.And ...

  9. python获取文件路径下的文件_python 获取文件下所有文件或目录os.walk()的实例

    在python3.6版本中去掉了os.path.walk()函数 os.walk() 函数声明:walk(top,topdown=True,oneerror=None) 1.参数top表示需要遍历的目 ...

最新文章

  1. 量子计算机不会“秒杀”经典计算机
  2. 设计中最常用的CSS选择器
  3. PHP中对数据库操作的封装
  4. Facebook宕机背后,我们该如何及时发现DNS问题
  5. 维护win10注册表
  6. 如何设置浏览器禁止使用UC浏览器
  7. 计算机单招语文试题,2019年高职单招语文模拟试题
  8. 疑似锤子新机谍照曝光,后置“拐角”四摄,前CEO犀利点评...
  9. 学习Java笔记2018.3.31
  10. Codeforces 402 and 403 (Div. 2 and 1)
  11. 获取指定进程所对应的可执行(EXE)文件全路径(代码)
  12. __proto__VS。 JavaScript原型
  13. 图解FPGrowth 算法
  14. 爱普生EPSON打印机 ME1+ (ME1)清零软件及方法
  15. dxp交流电源怎么找_常见dxp元件搜索方法
  16. 基于MATLAB的数字水印系统研究
  17. java soaoffice_SOAOFFICE是什么?
  18. jmeter连接数据库查询获取多个参数, 并通过参数化传值,实现jmeter造数
  19. HIVE基本查询操作(二)——第1关:Hive排序
  20. 免费午餐时代的结束 - Docker Hub 新的服务条款

热门文章

  1. android中sharedPreferences的用法
  2. matex2推送鸿蒙系统,拜拜了,Powered by Android!
  3. 网站对战服务器,PVP核心精华:三大服务器对战
  4. 剑指offer:对称的二叉树(镜像,递归,非递归DFS栈+BFS队列)
  5. 移动端UL列表无法平滑向下滚动问题
  6. 记一次酷派尚锋Y75刷机
  7. 数据类型、变量、常量
  8. 求一个二维数组的最大子矩阵的和
  9. 人际沟通最忌讳一脸死相【转】
  10. TechEd 2008 Developers: 新闻汇总