Ich versuche, einen parallelen Dataloader der torch-dataframe hinzuzufügen, um torchnet compatibility hinzuzufügen.Torch out of memory in Thread bei der Verwendung von torch.serialize zweimal
- Ein Grundansatz wird außerhalb der Fäden
- Der Ansatz wird serialisiert und auf den Faden
- im Gewinde der Stapel geladen wird deserialisiert und wandelt das: Ich habe die tnt.ParallelDatasetIteratorchanged it und so die verwendet Stapeldaten zu Tensoren
- Die Tensoren werden in einer Tabelle mit den Schlüsseln
input
undtarget
zurückgegeben, um die tnt.Engine Einstellung zu entsprechen.
Das Problem tritt zum zweiten Mal der enque
mit einem Fehler aufgerufen wird: .../torch_distro/install/bin/luajit: not enough memory
. Ich arbeite derzeit nur mit mnist mit einem angepassten mnist-example. Die enque
Schleife sieht nun wie folgt (mit Debug-Speicherausgabe):
-- `samplePlaceholder` stands in for samples which have been
-- filtered out by the `filter` function
local samplePlaceholder = {}
-- The enque does the main loop
local idx = 1
local function enqueue()
while idx <= size and threads:acceptsjob() do
local batch, reset = self.dataset:get_batch(batch_size)
if (reset) then
idx = size + 1
else
idx = idx + 1
end
if (batch) then
local serialized_batch = torch.serialize(batch)
-- In the parallel section only the to_tensor is run in parallel
-- this should though be the computationally expensive operation
threads:addjob(
function(argList)
io.stderr:write("\n Start");
io.stderr:write("\n 1: " ..tostring(collectgarbage("count")))
local origIdx, serialized_batch, samplePlaceholder = unpack(argList)
io.stderr:write("\n 2: " ..tostring(collectgarbage("count")))
local batch = torch.deserialize(serialized_batch)
serialized_batch = nil
collectgarbage()
collectgarbage()
io.stderr:write("\n 3: " .. tostring(collectgarbage("count")))
batch = transform(batch)
io.stderr:write("\n 4: " .. tostring(collectgarbage("count")))
local sample = samplePlaceholder
if (filter(batch)) then
sample = {}
sample.input, sample.target = batch:to_tensor()
end
io.stderr:write("\n 5: " ..tostring(collectgarbage("count")))
collectgarbage()
collectgarbage()
io.stderr:write("\n 6: " ..tostring(collectgarbage("count")))
io.stderr:write("\n End \n");
return {
sample,
origIdx
}
end,
function(argList)
sample, sampleOrigIdx = unpack(argList)
end,
{idx, serialized_batch, samplePlaceholder}
)
end
end
end
ich collectgarbage
habe bestreut und auch versucht, alle Objekte zu entfernen, nicht benötigt. Der Speicherausgang ist ziemlich einfach:
Start
1: 374840.87695312
2: 374840.94433594
3: 372023.79101562
4: 372023.85839844
5: 372075.41308594
6: 372023.73632812
End
Die Funktion, die die enque
Schleifen ist die ungeordnete Funktion, die trivial ist (die Speicherfehler beim zweiten enque
und die ausgelöst wird):
iterFunction = function()
while threads:hasjob() do
enqueue()
threads:dojob()
if threads:haserror() then
threads:synchronize()
end
enqueue()
if table.exact_length(sample) > 0 then
return sample
end
end
end