我们什么时候应该使用place_pruned_graph配置?

时间:2017-03-15 03:10:27

标签: tensorflow

问题:当标题出现时,我徘徊我们何时应该使用GraphOptions中的config place_pruned_graph。这个配置的目的是什么?

我不清楚有关此配置的评论:

  // Only place the subgraphs that are run, rather than the entire graph.
  //
  // This is useful for interactive graph building, where one might
  // produce graphs that cannot be placed during the debugging
  // process.  In particular, it allows the client to continue work in
  // a session after adding a node to a graph whose placement
  // constraints are unsatisfiable.

我们知道Tensorflow会将整个图表分成几个正常的子图。并且来自direct_session.cc的CreateGraphs的the following code正常地使用了else分支。(据我所知,我从未发现过if分支的情况(因此我不知道何时应该触发它) )。

  if (options_.config.graph_options().place_pruned_graph()) {
    // Because we are placing pruned graphs, we need to create a
    // new SimpleGraphExecutionState for every new unseen graph,
    // and then place it.
    SimpleGraphExecutionStateOptions prune_options;
    prune_options.device_set = &device_set_;
    prune_options.session_options = &options_;
    prune_options.stateful_placements = stateful_placements_;
    TF_RETURN_IF_ERROR(SimpleGraphExecutionState::MakeForPrunedGraph(
        execution_state_->original_graph_def().library(), prune_options,
        execution_state_->original_graph_def(), subgraph_options,
        &temp_exec_state_holder, &client_graph));
    execution_state = temp_exec_state_holder.get();
  } else {
    execution_state = execution_state_.get();
    TF_RETURN_IF_ERROR(
        execution_state->BuildGraph(subgraph_options, &client_graph));
  }

1 个答案:

答案 0 :(得分:1)

简短的回答? 从不。更长的答案要求我解释为什么存在此选项。

那么为什么TensorFlow包含这个复杂的配置选项和逻辑来处理它呢?当tensorflow::DirectSessiontensorflow::GrpcSession具有不同的内部实施时,这是一个历史性事故:

  1. tensorflow::GrpcSession在会话中对整个图表使用了一个SimpleGraphExecutionState。这样做的最终结果是,负责为图表中的每个节点分配设备的砂布将在>图形被修剪之前运行

  2. tensorflow::DirectSession最初为每个已修剪的子图使用了一个SimpleGraphExecutionState,并使用一些特殊逻辑来共享调用之间的有状态节点的放置。因此,在图表被修剪之后,布局器将运行,并且可以对有状态节点的放置位置做出不同的决定。

  3. tensorflow::GrpcSession方法(place_pruned_graph = false)的好处是它在运行放置算法时会考虑图中的所有共置约束,即使子图中没有出现这些约束也是如此被执行。例如,如果你有一个嵌入矩阵,并希望使用SparseApplyAdagrad op(only has a CPU implementation)来优化它,TensorFlow会发现嵌入矩阵应放在CPU上。

    相比之下,如果您没有为嵌入矩阵指定任何设备并设置placed_pruned_graph = true,那么当您运行其initializer时,矩阵(很可能)会被放置在GPU上,因为所有的操作都在初始化子图将在GPU上运行。而且,由于变量无法在设备之间移动,因此TensorFlow无法发出在矩阵上运行SparseApplyAdagrad的子图。这是最早版本的TensorFlow中的real issue

    那么为什么要支持place_pruned_graph = true呢?事实证明,在交互式使用TensorFlow时它非常有用。 placed_pruned_graph = false选项是不可原谅的:一旦会话的图形包含一个无法放置的节点,该会话就没用了,因为放置算法在整个图形上运行,每次调用它都会失败,因此没有步骤可以运行。当您使用tf.InteractiveSession时,我们假设您使用的是REPL(或Jupyter笔记本),并且在发生此类错误后允许您继续使用是有益的。因此,在tf.InteractiveSession我们设置place_pruned_graph = true,以便您可以在添加不可替换的节点后继续使用会话(只要您不尝试在已修剪的子图中运行该节点)。

    对于交互式使用,可能有比place_pruned_graph = true更好的方法,但我们没有调查添加一个。欢迎在GitHub issues page上提出建议。