问题:当标题出现时,我徘徊我们何时应该使用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));
}
答案 0 :(得分:1)
简短的回答? 从不。更长的答案要求我解释为什么存在此选项。
那么为什么TensorFlow包含这个复杂的配置选项和逻辑来处理它呢?当tensorflow::DirectSession
和tensorflow::GrpcSession
具有不同的内部实施时,这是一个历史性事故:
tensorflow::GrpcSession
在会话中对整个图表使用了一个SimpleGraphExecutionState
。这样做的最终结果是,负责为图表中的每个节点分配设备的砂布将在>>图形被修剪之前运行。
tensorflow::DirectSession
最初为每个已修剪的子图使用了一个SimpleGraphExecutionState
,并使用一些特殊逻辑来共享调用之间的有状态节点的放置。因此,在图表被修剪之后,布局器将运行,并且可以对有状态节点的放置位置做出不同的决定。
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上提出建议。