Executor

class paddle.static.Executor ( place=None ) [源代码]

Executor支持单GPU、多GPU以及CPU运行。

参数:

  • place (paddle.CPUPlace()|paddle.CUDAPlace(N)|None) – 该参数表示Executor执行所在的设备,这里的N为GPU对应的ID。当该参数为 None 时,PaddlePaddle会根据其安装版本设置默认的运行设备。当安装的Paddle为CPU版时,默认运行设置会设置成 CPUPlace() ,而当Paddle为GPU版时,默认运行设备会设置成 CUDAPlace(0) 。默认值为None。

返回:初始化后的 Executor 对象

示例代码

  1. import paddle
  2. import numpy
  3. import os
  4. # Executor 只能在静态图模式使用
  5. paddle.enable_static()
  6. # 显式设置运行设备
  7. # use_cuda = True
  8. # place = paddle.CUDAPlace(0) if use_cuda else paddle.CPUPlace()
  9. # exe = paddle.static.Executor(place)
  10. # 如果不显示设置运行设备,PaddlePaddle会设置默认运行设备
  11. exe = paddle.static.Executor()
  12. train_program = paddle.static.Program()
  13. startup_program = paddle.static.Program()
  14. with paddle.static.program_guard(train_program, startup_program):
  15. data = paddle.static.data(name='X', shape=[None, 1], dtype='float32')
  16. hidden = paddle.static.nn.fc(data, 10)
  17. loss = paddle.mean(hidden)
  18. paddle.optimizer.SGD(learning_rate=0.01).minimize(loss)
  19. # 仅运行一次startup program
  20. # 不需要优化/编译这个startup program
  21. startup_program.random_seed=1
  22. exe.run(startup_program)
  23. # 无需编译,直接运行main program
  24. x = numpy.random.random(size=(10, 1)).astype('float32')
  25. loss_data, = exe.run(train_program, feed={"X": x}, fetch_list=[loss.name])
  26. # 另一种方法是,编译这个main program然后运行。
  27. # 参考CompiledProgram以获取更多信息。
  28. # 注意:如果你使用CPU运行程序,需要具体设置CPU_NUM,
  29. # 否则PaddlePaddle会把逻辑核的所有数目设为CPU_NUM,
  30. # 在这种情况下,输入的batch size应大于CPU_NUM,
  31. # 否则程序会异常中断。
  32. # 显式设置运行设备
  33. # if not use_cuda:
  34. # os.environ['CPU_NUM'] = str(2)
  35. # 未显示设置运行设备且安装的Paddle为CPU版本
  36. os.environ['CPU_NUM'] = str(2)
  37. compiled_prog = paddle.static.CompiledProgram(
  38. train_program).with_data_parallel(loss_name=loss.name)
  39. loss_data, = exe.run(compiled_prog, feed={"X": x}, fetch_list=[loss.name])

close ( )

关闭执行器。该接口主要用于对于分布式训练,调用该接口后不可以再使用该执行器。该接口会释放在PServers上和目前Trainer有关联的资源。

返回:无

示例代码

  1. import paddle
  2. cpu = paddle.CPUPlace()
  3. exe = paddle.static.Executor(cpu)
  4. # 执行训练或测试过程
  5. exe.close()

run ( program=None, feed=None, fetch_list=None, feed_var_name=’feed’, fetch_var_name=’fetch’, scope=None, return_numpy=True, use_program_cache=False, return_merged=True, use_prune=False )

执行指定的Program或者CompiledProgram。需要注意的是,执行器会执行Program或CompiledProgram中的所有算子,而不会根据fetch_list对Program或CompiledProgram中的算子进行裁剪。同时,需要传入运行该模型用到的scope,如果没有指定scope,执行器将使用全局scope,即paddle.static.global_scope()。

参数:

  • program (Program|CompiledProgram) – 该参数为被执行的Program或CompiledProgram,如果未提供该参数,即该参数为None,在该接口内,main_program将被设置为paddle.static.default_main_program()。默认为:None。

  • feed (list|dict) – 该参数表示模型的输入变量。如果是单卡训练,feeddict 类型,如果是多卡训练,参数 feed 可以是 dict 或者 list 类型变量,如果该参数类型为 dict ,feed中的数据将会被分割(split)并分送给多个设备(CPU/GPU),即输入数据被均匀分配到不同设备上;如果该参数类型为 list ,则列表中的各个元素都会直接分别被拷贝到各设备中。默认为:None。

  • fetch_list (list) – 该参数表示模型运行之后需要返回的变量。默认为:None。

  • feed_var_name (str) – 该参数表示数据输入算子(feed operator)的输入变量名称。默认为:”feed”。

  • fetch_var_name (str) – 该参数表示结果获取算子(fetch operator)的输出变量名称。默认为:”fetch”。

  • scope (Scope) – 该参数表示执行当前program所使用的作用域,用户可以为不同的program指定不同的作用域。默认值:paddle.static.global_scope()。

  • return_numpy (bool) – 该参数表示是否将返回的计算结果(fetch list中指定的变量)转化为numpy;如果为False,则每个变量返回的类型为LoDTensor,否则返回变量的类型为numpy.ndarray。默认为:True。

  • use_program_cache (bool) – 该参数表示是否对输入的Program进行缓存。如果该参数为True,在以下情况时,模型运行速度可能会更快:输入的program为 paddle.static.Program ,并且模型运行过程中,调用该接口的参数(program、 feed变量名和fetch_list变量)名始终不变。默认为:False。

  • return_merged (bool) – 该参数表示是否按照执行设备维度将返回的计算结果(fetch list中指定的变量)进行合并。如果 return_merged 设为False,返回值类型是一个Tensor的二维列表( return_numpy 设为Fasle时)或者一个numpy.ndarray的二维列表( return_numpy 设为True时)。如果 return_merged 设为True,返回值类型是一个Tensor的一维列表( return_numpy 设为Fasle时)或者一个numpy.ndarray的一维列表( return_numpy 设为True时)。更多细节请参考示例代码2。如果返回的计算结果是变长的,请设置 return_merged 为False,即不按照执行设备维度合并返回的计算结果。该参数的默认值为True,但这仅是为了兼容性考虑,在未来的版本中默认值可能会更改为False。

  • use_prune (bool) - 该参数表示输入Program是否会被裁剪。如果该参数为True,会根据feed和fetch_list裁剪Program,这意味着对生成fetch_list没有必要的算子和变量会被裁剪掉。默认为False,即算子和变量在运行过程不会被裁剪。注意如果Optimizer.minimize()返回的tuple被作为fetch_list参数,那么use_prune会被重载为True并且Program会被裁剪。

返回:返回fetch_list中指定的变量值

注解

  1. 如果是多卡训练,并且feed参数为dict类型,输入数据将被均匀分配到不同的卡上,例如:使用2块GPU训练,输入样本数为3,即[0, 1, 2],经过拆分之后,GPU0上的样本数为1,即[0],GPU1上的样本数为2,即[1, 2]。如果样本数少于设备数,程序会报错,因此运行模型时,应额外注意数据集的最后一个batch的样本数是否少于当前可用的CPU核数或GPU卡数,如果是少于,建议丢弃该batch。

  2. 如果可用的CPU核数或GPU卡数大于1,则fetch出来的结果为不同设备上的相同变量值(fetch_list中的变量)在第0维拼接在一起。

示例代码1

  1. import paddle
  2. import numpy
  3. #首先创建执行引擎
  4. paddle.enable_static()
  5. place = paddle.CPUPlace() # paddle.CUDAPlace(0)
  6. exe = paddle.static.Executor(place)
  7. data = paddle.static.data(name='X', shape=[None, 1], dtype='float32')
  8. hidden = paddle.static.nn.fc(data, 10)
  9. loss = paddle.mean(hidden)
  10. adam = paddle.optimizer.Adam()
  11. adam.minimize(loss)
  12. i = paddle.zeros(shape=[1], dtype='int64')
  13. array = paddle.fluid.layers.array_write(x=loss, i=i)
  14. #仅运行startup程序一次
  15. exe.run(paddle.static.default_startup_program())
  16. x = numpy.random.random(size=(10, 1)).astype('float32')
  17. loss_val, array_val = exe.run(feed={'X': x},
  18. fetch_list=[loss.name, array.name])
  19. print(array_val)
  20. # [array([0.02153828], dtype=float32)]

示例代码2

  1. import paddle
  2. import numpy as np
  3. # 创建Executor对象
  4. paddle.enable_static()
  5. place = paddle.CUDAPlace(0)
  6. exe = paddle.static.Executor(place)
  7. data = paddle.static.data(name='X', shape=[None, 1], dtype='float32')
  8. class_dim = 2
  9. prediction = paddle.static.nn.fc(data, class_dim)
  10. loss = paddle.mean(prediction)
  11. adam = paddle.optimizer.Adam()
  12. adam.minimize(loss)
  13. # 运行且仅运行一次startup program
  14. exe.run(paddle.static.default_startup_program())
  15. build_strategy = paddle.static.BuildStrategy()
  16. binary = paddle.static.CompiledProgram(
  17. paddle.static.default_main_program()).with_data_parallel(
  18. loss_name=loss.name, build_strategy=build_strategy)
  19. batch_size = 6
  20. x = np.random.random(size=(batch_size, 1)).astype('float32')
  21. # 1) 设置 return_merged 参数为False以获取不合并的计算结果:
  22. unmerged_prediction, = exe.run(binary,
  23. feed={'X': x},
  24. fetch_list=[prediction.name],
  25. return_merged=False)
  26. # 如果用户使用两个GPU卡来运行此python代码示例,输出结果将为(2, 3, class_dim)。
  27. # 输出结果中第一个维度值代表所使用的GPU卡数,而第二个维度值代表batch_size和所使用
  28. # 的GPU卡数之商。
  29. print("The unmerged prediction shape: {}".format(
  30. np.array(unmerged_prediction).shape))
  31. print(unmerged_prediction)
  32. # 2) 设置 return_merged 参数为True以获取合并的计算结果:
  33. merged_prediction, = exe.run(binary,
  34. feed={'X': x},
  35. fetch_list=[prediction.name],
  36. return_merged=True)
  37. # 如果用户使用两个GPU卡来运行此python代码示例,输出结果将为(6, class_dim)。输出结果
  38. # 中第一个维度值代表batch_size值。
  39. print("The merged prediction shape: {}".format(
  40. np.array(merged_prediction).shape))
  41. print(merged_prediction)
  42. # 输出:
  43. # The unmerged prediction shape: (2, 3, 2)
  44. # [array([[-0.37620035, -0.19752218],
  45. # [-0.3561043 , -0.18697084],
  46. # [-0.24129935, -0.12669306]], dtype=float32), array([[-0.24489994, -0.12858354],
  47. # [-0.49041364, -0.25748932],
  48. # [-0.44331917, -0.23276259]], dtype=float32)]
  49. # The merged prediction shape: (6, 2)
  50. # [[-0.37789783 -0.19921964]
  51. # [-0.3577645 -0.18863106]
  52. # [-0.24274671 -0.12814042]
  53. # [-0.24635398 -0.13003758]
  54. # [-0.49232286 -0.25939852]
  55. # [-0.44514108 -0.2345845 ]]

infer_from_dataset ( program=None, dataset=None, scope=None, thread=0, debug=False, fetch_list=None, fetch_info=None, print_period=100 )

infer_from_dataset的文档与train_from_dataset几乎完全相同,只是在分布式训练中,推进梯度将在infer_from_dataset中禁用。 infer_from_dataset()可以非常容易地用于多线程中的评估。

参数:

  • program (Program|CompiledProgram) – 需要执行的program,如果没有给定那么默认使用default_main_program (未编译的)

  • dataset (paddle.fluid.Dataset) – 在此函数外创建的数据集,用户应当在调用函数前提供完整定义的数据集。必要时请检查Dataset文件。默认为None

  • scope (Scope) – 执行这个program的域,用户可以指定不同的域。默认为全局域

  • thread (int) – 用户想要在这个函数中运行的线程数量。线程的实际数量为min(Dataset.thread_num, thread),如果thread > 0,默认为0

  • debug (bool) – 是否开启debug模式,默认为False

  • fetch_list (Tensor List) – 返回变量列表,每个变量都会在预测过程中被打印出来,默认为None

  • fetch_info (String List) – 每个变量的打印信息,默认为None

  • print_period (int) – 每两次打印之间间隔的mini-batches的数量,默认为100

返回:None

示例代码

  1. import paddle
  2. paddle.enable_static()
  3. place = paddle.CPUPlace() # 使用GPU时可设置place = paddle.CUDAPlace(0)
  4. exe = paddle.static.Executor(place)
  5. x = paddle.static.data(name="x", shape=[None, 10, 10], dtype="int64")
  6. y = paddle.static.data(name="y", shape=[None, 1], dtype="int64", lod_level=1)
  7. dataset = paddle.fluid.DatasetFactory().create_dataset()
  8. dataset.set_use_var([x, y])
  9. dataset.set_thread(1)
  10. # 您可以设置您自己的filelist,如filelist = ["dataA.txt"]
  11. filelist = []
  12. dataset.set_filelist(filelist)
  13. exe.run(paddle.static.default_startup_program())
  14. exe.infer_from_dataset(program=paddle.static.default_main_program(),
  15. dataset=dataset)

train_from_dataset ( program=None, dataset=None, scope=None, thread=0, debug=False, fetch_list=None, fetch_info=None, print_period=100 )

从预定义的数据集中训练。 数据集在paddle.fluid.dataset中定义。 给定程序(或编译程序),train_from_dataset将使用数据集中的所有数据样本。 输入范围可由用户给出。 默认情况下,范围是global_scope()。训练中的线程总数是thread。 训练中使用的线程数将是数据集中threadnum的最小值,同时也是此接口中线程的值。 可以设置debug,以便执行器显示所有算子的运行时间和当前训练任务的吞吐量。

注意:train_from_dataset将销毁每次运行在executor中创建的所有资源。

参数:

  • program (Program|CompiledProgram) – 需要执行的program,如果没有给定那么默认使用default_main_program (未编译的)

  • dataset (paddle.fluid.Dataset) – 在此函数外创建的数据集,用户应当在调用函数前提供完整定义的数据集。必要时请检查Dataset文件。默认为None

  • scope (Scope) – 执行这个program的域,用户可以指定不同的域。默认为全局域

  • thread (int) – 用户想要在这个函数中运行的线程数量。线程的实际数量为min(Dataset.thread_num, thread),如果thread > 0,默认为0

  • debug (bool) – 是否开启debug模式,默认为False

  • fetch_list (Tensor List) – 返回变量列表,每个变量都会在训练过程中被打印出来,默认为None

  • fetch_info (String List) – 每个变量的打印信息,默认为None

  • print_period (int) – 每两次打印之间间隔的mini-batches的数量,默认为100

返回:None

示例代码

  1. import paddle
  2. paddle.enable_static()
  3. place = paddle.CPUPlace() # 使用GPU时可设置place = paddle.CUDAPlace(0)
  4. exe = paddle.static.Executor(place)
  5. x = paddle.static.data(name="x", shape=[None, 10, 10], dtype="int64")
  6. y = paddle.static.data(name="y", shape=[None, 1], dtype="int64", lod_level=1)
  7. dataset = paddle.fluid.DatasetFactory().create_dataset()
  8. dataset.set_use_var([x, y])
  9. dataset.set_thread(1)
  10. # 您可以设置您自己的filelist,如filelist = ["dataA.txt"]
  11. filelist = []
  12. dataset.set_filelist(filelist)
  13. exe.run(paddle.static.default_startup_program())
  14. exe.train_from_dataset(program=paddle.static.default_main_program(),
  15. dataset=dataset)