4

在 Caffe/Caffe2 中定义网络时,可以将一些节点放在 CPU 上,而将其他节点放在 GPU 上吗?如果是这样,怎么做?

(如果您的答案与特定版本的 Caffe 相关,请说明是哪一个)

4

4 回答 4

1

不,这是不可能的。如果你看solver.prototxt您会注意到您可以将模式指定为 CPU 或 GPU,但不能同时指定两者。保持这种执行结构的原因是为了保持效率。CNN 的每一层生成的数据可能以兆字节为单位。如果您将网络的一部分保留在 CPU 上,而将部分网络保留在 GPU 上,则需要在设备之间来回传输大量数据。这将增加巨大的开销,这将完全抵消 GPU 提供的杠杆作用。因此,在 CPU 上训练整个网络比 CPU-GPU 组合更有效。另请注意,GPU 通过 PCIe 接口与 CPU 连接,该接口比内部 CPU 总线慢得多。因此设备之间的数据传输非常昂贵。那'

于 2017-06-05T13:00:21.757 回答
1

这在 Caffe2 中可能实际上是可能的,但我从未测试过它。在 Caffe2 中,每个 blob 和 operator 都有一个分配给它的设备。操作员在分配给它的设备上运行。但是您需要手动处理初始化和通信,因为 Caffe2 中的 data_parallel_model 仅适用于多 GPU 设置。

于 2017-06-06T04:17:00.730 回答
1

一般来说,答案是否定的:由于Pooya DavoodiHarsh Wardhan所描述的原因,您不能为每一层独立配置设备。

但是,如果您查看特定层,您有时可能会得到您所寻找的行为。例如,如果您的求解器配置为在 GPU 上运行,但您的网络中有一个没有 GPU 实现的层,那么该层将在 CPU 上运行(所有开销都在Harsh Wardhan 的回答中描述)。
一个这样的层是一个"Python"层:这个层只在 CPU 上运行,你可能在word2vec那里有你的实现。
或者,您可以编写自己的层而无需 GPU 实现,确保它们仅在 CPU 上运行。


顺便说一句,您使用的是 caffe2 吗?你同意他们的专利条款吗?!
更新:似乎 fb 决定软化caffe2 的许可证。做得好!

于 2017-06-06T05:57:38.103 回答
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())
  • 不要忘记在喂它的 blob 之前做同样的事情,否则你希望能够接触到它们。

输出是:

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"
于 2020-04-22T11:56:48.500 回答