在Caffe / Caffe2中定义网络时,您是否可以在CPU上放置一些节点,在GPU上放置其他节点?如果是这样,怎么样?
(如果您的答案与Caffe的特定版本相关,请指明哪个)
答案 0 :(得分:1)
不,这是不可能的。如果查看solver.prototxt
文件,您会注意到您可以将模式指定为CPU或GPU,但不能同时指定两者。保持这种执行结构的原因是为了保持效率。 CNN的每一层生成的数据可能以兆字节为单位。如果您将部分网络保留在CPU上并将其中的一部分保留在GPU上,则需要在设备之间来回传输大量数据。这将增加巨大的开销,这将完全取消GPU给出的杠杆作用。因此,在CPU上训练整个网络而不是CPU-GPU组合更有效。另请注意,GPU通过PCIe接口与CPU连接,该接口明显慢于内部CPU总线。因此,设备之间的数据传输非常昂贵。这就是为什么更大的批量大小是训练CNN的首选原因之一,因为一堆图像可以立即发送到GPU,避免重复的内存读写。
答案 1 :(得分:1)
这可能在Caffe2中实际可行,但我从未测试过它。 在Caffe2中,每个blob和operator都有一个分配给它的设备。操作员在分配给它的设备上运行。但是,您需要手动处理初始化和通信,因为Caffe2中的data_parallel_model仅适用于多GPU设置。
答案 2 :(得分:1)
一般来说,答案是否:由于Pooya Davoodi和Harsh Wardhan描述的原因,您无法单独为每个图层配置设备。
但是,如果您查看特定图层,有时可能会获得您要查找的行为。例如,如果您的求解器配置为在GPU上运行,但您的网络中有一个没有GPU实现的层,那么该层将在CPU上运行(具有Harsh Wardhan's answer中描述的所有开销) 。
一个这样的图层是"Python"
图层:此图层仅在CPU上运行,您可以在那里执行word2vec
。
或者,您可以在没有GPU实现的情况下编写自己的图层,确保它们仅在CPU上运行。
BTW,你在使用caffe2吗?你对他们的PATENTS条款没问题吗?!
更新:似乎fb决定soften caffe2的许可证。做得好!
答案 3 :(得分:0)
在创建所需的节点及其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"