この質問は、nnGraph ネットワークを複数の GPU で実行することに関するものであり、次のネットワーク インスタンスに固有のものではありません。
nnGraph で構築されたネットワークをトレーニングしようとしています。後方図を添付します。マルチ GPU 設定で parallelModel (コードまたは図ノード 9 を参照) を実行しようとしています。並列モデルを nn.Sequential コンテナーにアタッチしてから DataParallelTable を作成すると、マルチ GPU 設定 (nnGraph なし) で動作します。ただし、それを nnGraph にアタッチすると、エラーが発生します。単一の GPU でトレーニングする (if ステートメントで true を false に設定する) 場合、バックワード パスは機能しますが、マルチ GPU 設定では、「gmodule.lua:418: ローカル 'gradInput' (a nil価値)"。バックワード パスのノード 9 は複数の GPU で実行する必要があると思いますが、そうはなっていません。nnGraph で DataParallelTable を作成してもうまくいきませんでした。ただし、少なくとも内部 Sequential ネットワークを DataParallelTable に配置するとうまくいくと思いました。複数の GPU で実行できるように、nnGraph に渡される初期データを分割する他の方法はありますか?
require 'torch'
require 'nn'
require 'cudnn'
require 'cunn'
require 'cutorch'
require 'nngraph'
data1 = torch.ones(4,20):cuda()
data2 = torch.ones(4,10):cuda()
tmodel = nn.Sequential()
tmodel:add(nn.Linear(20,10))
tmodel:add(nn.Linear(10,10))
parallelModel = nn.ParallelTable()
parallelModel:add(tmodel)
parallelModel:add(nn.Identity())
parallelModel:add(nn.Identity())
model = parallelModel
if true then
local function sharingKey(m)
local key = torch.type(m)
if m.__shareGradInputKey then
key = key .. ':' .. m.__shareGradInputKey
end
return key
end
-- Share gradInput for memory efficient backprop
local cache = {}
model:apply(function(m)
local moduleType = torch.type(m)
if torch.isTensor(m.gradInput) and moduleType ~= 'nn.ConcatTable' then
local key = sharingKey(m)
if cache[key] == nil then
cache[key] = torch.CudaStorage(1)
end
m.gradInput = torch.CudaTensor(cache[key], 1, 0)
end
end)
end
if true then
cudnn.fastest = true
cudnn.benchmark = true
-- Wrap the model with DataParallelTable, if using more than one GPU
local gpus = torch.range(1, 2):totable()
local fastest, benchmark = cudnn.fastest, cudnn.benchmark
local dpt = nn.DataParallelTable(1, true, true)
:add(model, gpus)
:threads(function()
local cudnn = require 'cudnn'
cudnn.fastest, cudnn.benchmark = fastest, benchmark
end)
dpt.gradInput = nil
model = dpt:cuda()
end
newmodel = nn.Sequential()
newmodel:add(model)
input1 = nn.Identity()()
input2 = nn.Identity()()
input3 = nn.Identity()()
out = newmodel({input1,input2,input3})
r1 = nn.NarrowTable(1,2)(out)
r2 = nn.NarrowTable(2,2)(out)
f1 = nn.JoinTable(2)(r1)
f2 = nn.JoinTable(2)(r2)
n1 = nn.Sequential()
n1:add(nn.Linear(20,5))
n2 = nn.Sequential()
n2:add(nn.Linear(20,5))
f11 = n1(f1)
f12 = n2(f2)
foutput = nn.JoinTable(2)({f11,f12})
g = nn.gModule({input1,input2,input3},{foutput})
g = g:cuda()
g:forward({data1, data2, data2})
g:backward({data1, data2, data2}, torch.rand(4,10):cuda())
「if」ステートメントのコードは、Facebook の ResNet 実装から取得されます
