将同一网络的一些节点放在 GPU 上,而将其他节点放在 CPU 上?
Place some nodes of the same network on GPU and others on CPU?
在 Caffe/Caffe2 中定义网络时,可以将一些节点放在 CPU 上,而将其他节点放在 GPU 上吗?如果是这样,如何?
(如果您的回答与 Caffe 的特定版本有关,请说明是哪个版本)
不,这不可能。如果您查看 solver.prototxt
文件,您会注意到您可以将模式指定为 CPU 或 GPU,但不能同时指定两者。之所以保留这种执行结构,是为了保持效率。 CNN 每一层生成的数据可能以兆字节为单位。如果将一部分网络保留在 CPU 上,将一部分保留在 GPU 上,则需要在设备之间来回传输大量数据。这将增加巨大的开销,这将完全抵消 GPU 提供的杠杆作用。因此,在 CPU 而不是 CPU-GPU 组合上训练整个网络更有效。另请注意,GPU 通过 PCIe 接口与 CPU 连接,该接口比内部 CPU 总线慢得多。所以设备之间的数据传输非常昂贵。这就是为什么训练 CNN 时首选大批量大小的原因之一,因为一堆图像可以一次发送到 GPU,避免重复的内存读写。
这在 Caffe2 中实际上是可行的,但我从未测试过。
在 Caffe2 中,每个 blob 和操作符都有一个分配给它的设备。操作员在分配给它的设备上运行。但是您随后需要手动处理初始化和通信,因为 Caffe2 中的 data_parallel_model 仅适用于多 GPU 设置。
一般来说,答案是否:由于 and 所述的原因,您不能为每一层单独配置设备。
但是,如果您查看特定层,您有时可能会得到您要查找的行为。例如,如果您的求解器在 GPU 上配置为 运行,但您的网络中有一个层没有 GPU 实现,那么该层将在 CPU 上 运行( ).
中描述的所有开销
其中一个层是 层:该层 运行 仅在 CPU 上,您可以在那里实现 word2vec
。
或者,您可以在没有 GPU 实现的情况下编写自己的层,确保它们 运行 仅在 CPU 上。
顺便说一句,你用的是caffe2吗?你同意他们的 PATENTS 条款吗?!
更新:fb 似乎决定 soften caffe2 的许可证。做得好!
在创建所需节点及其 Blob 之前,将 DeviceScope 与相关 DeviceOption (CPU / GPU) device_type 结合使用
简单示例:
from caffe2.python import workspace, model_helper
from caffe2.proto import caffe2_pb2
from caffe2.python import core
import numpy as np
m = model_helper.ModelHelper(name="my first net")
data = np.random.rand(16, 100).astype(np.float32)
gpu_device_id = 1
cpu_device_id = -1
with core.DeviceScope(core.DeviceOption(workspace.GpuDeviceType, gpu_device_id)):
with core.DeviceScope(core.DeviceOption(caffe2_pb2.CPU, cpu_device_id)):
# Feed relevant blobs
workspace.FeedBlob("data", data)
weight = m.param_init_net.XavierFill([], 'fc_w', shape=[10, 100])
bias = m.param_init_net.ConstantFill([], 'fc_b', shape=[10, ])
# Create you cpu Node
fc_1 = m.net.FC(["data", "fc_w", "fc_b"], "fc1")
# Create GPU Node
pred = m.net.Sigmoid(fc_1, "pred")
softmax, loss = m.net.SoftmaxWithLoss([pred, "label"], ["softmax", "loss"])
print(m.net.Proto())
- 不要忘记在喂食它的斑点之前做同样的事情,否则,您希望能够接触到它们。
输出为:
name: "my first net"
op {
name: "my first net"
op {
input: "data"
input: "fc_w"
input: "fc_b"
output: "fc1"
name: ""
type: "FC"
device_option {
device_type: 0
device_id: -1
}
}
op {
input: "fc1"
output: "pred"
name: ""
type: "Sigmoid"
device_option {
device_type: 1
device_id: 1
}
}
op {
input: "pred"
input: "label"
output: "softmax"
output: "loss"
name: ""
type: "SoftmaxWithLoss"
device_option {
device_type: 1
device_id: 1
}
}
external_input: "data"
external_input: "fc_w"
external_input: "fc_b"
external_input: "label"
在 Caffe/Caffe2 中定义网络时,可以将一些节点放在 CPU 上,而将其他节点放在 GPU 上吗?如果是这样,如何?
(如果您的回答与 Caffe 的特定版本有关,请说明是哪个版本)
不,这不可能。如果您查看 solver.prototxt
文件,您会注意到您可以将模式指定为 CPU 或 GPU,但不能同时指定两者。之所以保留这种执行结构,是为了保持效率。 CNN 每一层生成的数据可能以兆字节为单位。如果将一部分网络保留在 CPU 上,将一部分保留在 GPU 上,则需要在设备之间来回传输大量数据。这将增加巨大的开销,这将完全抵消 GPU 提供的杠杆作用。因此,在 CPU 而不是 CPU-GPU 组合上训练整个网络更有效。另请注意,GPU 通过 PCIe 接口与 CPU 连接,该接口比内部 CPU 总线慢得多。所以设备之间的数据传输非常昂贵。这就是为什么训练 CNN 时首选大批量大小的原因之一,因为一堆图像可以一次发送到 GPU,避免重复的内存读写。
这在 Caffe2 中实际上是可行的,但我从未测试过。 在 Caffe2 中,每个 blob 和操作符都有一个分配给它的设备。操作员在分配给它的设备上运行。但是您随后需要手动处理初始化和通信,因为 Caffe2 中的 data_parallel_model 仅适用于多 GPU 设置。
一般来说,答案是否:由于
但是,如果您查看特定层,您有时可能会得到您要查找的行为。例如,如果您的求解器在 GPU 上配置为 运行,但您的网络中有一个层没有 GPU 实现,那么该层将在 CPU 上 运行(
中描述的所有开销
其中一个层是 word2vec
。
或者,您可以在没有 GPU 实现的情况下编写自己的层,确保它们 运行 仅在 CPU 上。
顺便说一句,你用的是caffe2吗?你同意他们的 PATENTS 条款吗?!
更新:fb 似乎决定 soften caffe2 的许可证。做得好!
在创建所需节点及其 Blob 之前,将 DeviceScope 与相关 DeviceOption (CPU / GPU) device_type 结合使用
简单示例:
from caffe2.python import workspace, model_helper
from caffe2.proto import caffe2_pb2
from caffe2.python import core
import numpy as np
m = model_helper.ModelHelper(name="my first net")
data = np.random.rand(16, 100).astype(np.float32)
gpu_device_id = 1
cpu_device_id = -1
with core.DeviceScope(core.DeviceOption(workspace.GpuDeviceType, gpu_device_id)):
with core.DeviceScope(core.DeviceOption(caffe2_pb2.CPU, cpu_device_id)):
# Feed relevant blobs
workspace.FeedBlob("data", data)
weight = m.param_init_net.XavierFill([], 'fc_w', shape=[10, 100])
bias = m.param_init_net.ConstantFill([], 'fc_b', shape=[10, ])
# Create you cpu Node
fc_1 = m.net.FC(["data", "fc_w", "fc_b"], "fc1")
# Create GPU Node
pred = m.net.Sigmoid(fc_1, "pred")
softmax, loss = m.net.SoftmaxWithLoss([pred, "label"], ["softmax", "loss"])
print(m.net.Proto())
- 不要忘记在喂食它的斑点之前做同样的事情,否则,您希望能够接触到它们。
输出为:
name: "my first net"
op {
name: "my first net"
op {
input: "data"
input: "fc_w"
input: "fc_b"
output: "fc1"
name: ""
type: "FC"
device_option {
device_type: 0
device_id: -1
}
}
op {
input: "fc1"
output: "pred"
name: ""
type: "Sigmoid"
device_option {
device_type: 1
device_id: 1
}
}
op {
input: "pred"
input: "label"
output: "softmax"
output: "loss"
name: ""
type: "SoftmaxWithLoss"
device_option {
device_type: 1
device_id: 1
}
}
external_input: "data"
external_input: "fc_w"
external_input: "fc_b"
external_input: "label"