Pregunta nnGraph Antorcha multi-GPU


Esta pregunta se trata de hacer que cualquier red nnGraph se ejecute en múltiples GPU y no sea específica para la siguiente instancia de red

Estoy tratando de entrenar una red que está construida con nnGraph. El diagrama hacia atrás está adjunto. Estoy intentando ejecutar parallelModel (ver código o fig Node 9) en una configuración multi-GPU. Si adjunto el modelo paralelo a un contenedor nn.Sequential y luego creo una DataParallelTable, funciona en una configuración multi-GPU (sin nnGraph). Sin embargo, después de adjuntarlo a nnGraph obtengo un error. El pase hacia atrás funciona si entreno en una sola GPU (configurando de verdadero a falso en las sentencias if), pero en una configuración multi-GPU obtengo un error "gmodule.lua: 418: intento de indexar 'gradInput' local (un nil valor)". Creo que el Nodo 9 en el pase hacia atrás debería ejecutarse en múltiples GPU, sin embargo, eso no está sucediendo. Crear DataParallelTable en nnGraph no funcionó para mí, sin embargo pensé que al menos poner redes secuenciales internas en DataParallelTable funcionaría. ¿Hay alguna otra manera de dividir los datos iniciales que se pasan a nnGraph para que se ejecute en múltiples GPU?

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())

Backward Pass

El código en las declaraciones "if" está tomado de Implementación de ResNet en Facebook


7
2017-07-26 18:47


origen


Respuestas: