Created by: Aurelius84
1.背景
目前Paddle框架支持动态图组网训练,为了更易于部署,可以将动态图转为静态图,更方便基于图做进一步的优化和上线。动态图下的if/else
语法为python原生语法,转静态图时,需要解析判断、并适应转为paddle的控制流API fluid.layers.cond
。
2.功能支持
2.1 支持简单if/else语句转写
动态图代码:
@dygraph_to_static_output
def dyfunc_with_ifElse(x_v):
if (x_v).numpy()[0] > 5:
x_v = x_v - 1
else:
x_v = x_v + 1
return x_v
转换后的静态图代码:
def true_fn(x_v):
x_v = x_v - 1
return ()
def false_fn(x_v):
x_v = x_v + 1
return ()
def dyfunc_with_ifElse2(x_v):
x_v = fluid.layers.cond((x_v[0]) > 5), lambda : true_fn(x_v), lambda : false_fn(x_v))
return x_v
2.2 支持嵌套的if/else
动态图代码:
@dygraph_to_static_output
def dyfunc_with_ifElse(x_v):
batch_size = 10
shape = [batch_size, 16]
bias = fluid.layers.fill_constant([shape[-1]], dtype='float32', value=1)
if fluid.layers.mean(x_v).numpy()[0] < 0:
x_v = x_v + bias
w = fluid.layers.fill_constant([shape[-1]], dtype='float32', value=10)
new_var = True
# 嵌套的if,且缺省了else
if x_v.numpy()[0] < 10:
tmp = x_v * w
x_v = fluid.layers.relu(tmp)
else:
new_var = False
x_v = x_v - bias
return x_v
转换后的静态图代码:
# 对应最内层的if
def true_fn_0(w, x_v):
tmp = x_v * w
x_v = fluid.layers.relu(tmp)
return x_v
# 对应最内层缺省else,函数内部没有实际处理逻辑
# 但由于layers.cond对返回值嵌套结构需一致,故需要返回与true_fn一致的变量
def false_fn_0(x_v):
return x_v
# 对应最外层的if
def true_fn_1(True, bias, shape, x_v):
x_v = x_v + bias
w = fluid.layers.fill_constant([shape[-1]], dtype='float32', value=10)
new_var = True
x_v = fluid.layers.cond((x_v[0] < 10), lambda : true_fn_0(w, x_v), lambda : false_fn_0(x_v))
return (new_var, x_v)
# 对应最外层的else
def false_fn_1(False, bias, x_v):
new_var = False
x_v = x_v - bias
return (new_var, x_v)
def dyfunc_with_ifElse(x_v):
batch_size = 10
shape = [batch_size, 16]
bias = fluid.layers.fill_constant([shape[-1]], dtype='float32', value=1)
(new_var, x_v) = fluid.layers.cond((fluid.layers.mean(x_v)[0] < 0), lambda : true_fn_1(True, bias, shape, x_v), lambda : false_fn_1(False, bias, x_v))
return x_v
2.3 支持控制流分支函数输入和输出参数自动解析
见2.2中构建true_fn
和false_fn
时对输入参数和输出参数的解析
3. What's Next?
- 分支函数名的友好管理方案
- AST转回可调用python函数的功能实现
- 各子逻辑函数的单元测试