Pytorch: möglicher Deadlock im Dataloader

Erstellt am 25. Apr. 2017  ·  189Kommentare  ·  Quelle: pytorch/pytorch

der Fehler ist unter pytorch/examples#148 beschrieben. Ich frage mich nur, ob dies ein Fehler in PyTorch selbst ist, da der Beispielcode für mich sauber aussieht. Außerdem frage ich mich, ob dies mit #1120 zusammenhängt.

Hilfreichster Kommentar

Ich bin auf ein ähnliches Problem gestoßen: Der Datenlader stoppt, wenn ich eine Epoche beende und eine neue Epoche beginnen wird.

Alle 189 Kommentare

Wie viel freien Speicher haben Sie, wenn der Loader stoppt?

@apaszke Wenn ich top ankreuze, beträgt der verbleibende Speicher (der zwischengespeicherte Speicher zählt auch als verwendet) normalerweise 2 GB. Aber wenn Sie den Cache nicht als verwendet zählen, ist es immer eine Menge, sagen wir 30 GB+.

Ich verstehe auch nicht, warum es immer zu Beginn der Validierung aufhört, aber nicht überall sonst.

Möglicherweise, weil für die Validierung ein separater Loader verwendet wird, der die Verwendung von Shared Memory über die Grenze treibt.

@ngimel

Ich habe das Programm gerade nochmal ausgeführt. Und blieb hängen.

Ausgabe von top :

~~~
top - 17:51:18 up 2 Tage, 21:05, 2 User, Load Average: 0.49, 3.00, 5.41
Aufgaben: 357 insgesamt, 2 rennend, 355 schlafend, 0 gestoppt, 0 Zombie
%Cpu(s): 1,9 us, 0,1 sy, 0,7 ni, 97,3 id, 0,0 wa, 0,0 hi, 0,0 si, 0,0 st
KiB Mem: 65863816 gesamt, 60115084 gebraucht, 5748732 frei, 1372688 Puffer
KiB Swap: 5917692 gesamt, 620 gebraucht, 5917072 kostenlos. 51154784 zwischengespeichertes Mem

PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 3067 aalreja 20 0 143332 101816 21300 R 46,1 0,2 1631:44 Xvnc
16613 aalreja 30 10 32836 4880 3912 S 16,9 0,0 1:06,92 Fiberlamp 3221 aalreja 20 0 8882348 1,017 g 110120 S 1,3 1,6 579:06,87 MATLAB
1285 root 20 0 1404848 48252 25580 S 0,3 0,1 6:00,12 dockerd 16597 yimengz+ 20 0 25084 3252 2572 R 0,3 0,0 0:04,56 top
1 Wurzel 20 0 33616 4008 2624 S 0.0 0.0 0.01.43 init
~~~

Ausgabe von free

~yimengzh_everyday@yimengzh :~$ kostenlosinsgesamt verwendete freie gemeinsam genutzte Puffer im CacheMem: 65863816 60122060 5741756 9954628 1372688 51154916-/+ Puffer/Cache: 7594456 58269360Tausch: 5917692 620 5917072~

Ausgabe von nvidia-smi

~~~
yimengzh_everyday@yimengzh :~$ nvidia-smi
Di 25 Apr 17:52:38 2017
+------------------------------------------------- ----------------------------------------+
| NVIDIA-SMI 375.39 Treiberversion: 375.39 |
|------------------------------------------+----------------- -----+------------------------+
| GPU-Name Persistenz-M| Bus-Id Disp.A | Flüchtige Entkorr. ECC |
| Lüftertemp. Perf.
|===============================+================= =====+======================|
| 0 GeForce GTX TIT... Aus | 0000:03:00.0 Aus | k.A. |
| 30% 42C P8 14W / 250W | 3986MiB / 6082MiB | 0% Standard |
+-------------------------------+----------------- -----+------------------------+
| 1 Tesla K40c Aus | 0000:81:00.0 Aus | Aus |
| 0% 46C P0 57W / 235W | 0MiB / 12205MiB | 0% Standard |
+-------------------------------+----------------- -----+------------------------+

+------------------------------------------------- ----------------------------------------+
| Prozesse: GPU-Speicher |
| GPU PID-Typ Prozessname Verwendung |
|================================================ ============================|
| 0 16509 C-Python 3970MiB |
+------------------------------------------------- ----------------------------------------+
~~~

Ich glaube nicht, dass es ein Speicherproblem ist.

Für gemeinsam genutzten Speicher gibt es separate Grenzen. Können Sie ipcs -lm oder cat /proc/sys/kernel/shmall und cat /proc/sys/kernel/shmmax ausprobieren? Kommt es auch zu einem Deadlock, wenn Sie weniger Arbeiter einsetzen (zB Test mit dem Extremfall von 1 Arbeiter)?

@apaszke

~~~
yimengzh_everyday@yimengzh :~$ ipcs -lm

------ Gemeinsame Speichergrenzen --------
maximale Anzahl von Segmenten = 4096
maximale Segmentgröße (kbytes) = 18014398509465599
maximaler gemeinsamer Speicher (kbytes) = 18446744073642442748
Min. Seg-Größe (Byte) = 1

yimengzh_everyday@yimengzh :~$ cat /proc/sys/kernel/shmall
18446744073692774399
yimengzh_everyday@yimengzh :~$ cat /proc/sys/kernel/shmmax
18446744073692774399
~~~

wie sehen sie bei dir aus?

Was weniger Arbeiter angeht, glaube ich, dass dies nicht so oft passieren wird. (kann ich jetzt versuchen). Aber ich denke, in der Praxis brauche ich so viele Arbeiter.

Sie haben maximal 4096 freigegebene Speichersegmente erlaubt, vielleicht ist das ein Problem. Sie können versuchen, dies zu erhöhen, indem Sie in /proc/sys/kernel/shmmni schreiben (vielleicht versuchen Sie 8192). Möglicherweise benötigen Sie Superuser-Berechtigungen.

@apaszke Nun, das sind Standardwerte von Ubuntu und CentOS 6 ... Ist das wirklich ein Problem?

@apaszke beim Ausführen des Trainingsprogramms zeigt ipcs -a tatsächlich an, dass kein gemeinsamer Speicher verwendet wird. Ist das zu erwarten?

@apaszke hat versucht, das Programm (immer noch 22 Arbeiter) mit der folgenden Einstellung für das freigegebene Mem auszuführen, und blieb erneut

~~~
yimengzh_everyday@yimengzh :~$ ipcs -lm

------ Gemeinsame Speichergrenzen --------
maximale Anzahl von Segmenten = 8192
maximale Segmentgröße (kbytes) = 18014398509465599
maximaler gemeinsamer Speicher (kbytes) = 18446744073642442748
Min. Seg-Größe (Byte) = 1
~~~

versuchte nicht einen Arbeiter. erstens wäre das langsam; zweitens, wenn das Problem wirklich fest verriegelt ist, würde es definitiv verschwinden.

@zym1010 Standardeinstellungen müssen nicht mit Blick auf solche Workloads erstellt werden, also ja, es könnte ein Problem gewesen sein. ipcs ist für gemeinsam genutzten Speicher von System V, den wir nicht verwenden, aber ich wollte sicherstellen, dass nicht dieselben Beschränkungen für gemeinsam genutzten Speicher von POSIX gelten.

Es würde nicht definitiv verschwinden , denn wenn das Problem wirklich besteht, dann ist es wahrscheinlich ein Deadlock zwischen dem Worker und dem Hauptprozess, und ein Worker könnte ausreichen, um dies auszulösen. Jedenfalls kann ich das Problem nicht beheben, bis ich es reproduzieren kann. Welche Parameter verwenden Sie zum Ausführen des Beispiels und haben Sie den Code in irgendeiner Weise geändert? Und was ist der Wert von torch.__version__ ? Läufst du im Docker?

@apaszke Danke. Ich verstehe deine Analyse jetzt viel besser.

Alle anderen Ergebnisse, die Ihnen bis auf das Wie gezeigt werden, werden auf einem Ubuntu 14.04-Rechner mit 64 GB RAM, Dual-Xeon und Titan Black durchgeführt (es gibt auch einen K40, aber ich habe ihn nicht verwendet).

Der Befehl zum Generieren des Problems lautet CUDA_VISIBLE_DEVICES=0 PYTHONUNBUFFERED=1 python main.py -a alexnet --print-freq 20 --lr 0.01 --workers 22 --batch-size 256 /mnt/temp_drive_3/cv_datasets/ILSVRC2015/Data/CLS-LOC . Ich habe den Code überhaupt nicht geändert.

Ich habe pytorch über pip auf Python 3.5 installiert. pytorch-Version ist 0.1.11_5 . Läuft nicht in Docker.

Übrigens, ich habe auch versucht, 1 Arbeiter zu verwenden. Aber ich habe es auf einem anderen Rechner gemacht (128GB RAM, Dual Xeon, 4 Pascal Titan X, CentOS 6). Ich habe es mit CUDA_VISIBLE_DEVICES=0 PYTHONUNBUFFERED=1 python main.py -a alexnet --print-freq 1 --lr 0.01 --workers 1 --batch-size 256 /ssd/cv_datasets/ILSVRC2015/Data/CLS-LOC und das Fehlerprotokoll lautet wie folgt.

Epoch: [0][5003/5005]   Time 2.463 (2.955)      Data 2.414 (2.903)      Loss 5.9677 (6.6311)    Prec<strong i="14">@1</strong> 3.516 (0.545)    Prec<strong i="15">@5</strong> 8.594 (2.262)
Epoch: [0][5004/5005]   Time 1.977 (2.955)      Data 1.303 (2.903)      Loss 5.9529 (6.6310)    Prec<strong i="16">@1</strong> 1.399 (0.545)    Prec<strong i="17">@5</strong> 7.692 (2.262)
^CTraceback (most recent call last):
  File "main.py", line 292, in <module>
    main()
  File "main.py", line 137, in main
    prec1 = validate(val_loader, model, criterion)
  File "main.py", line 210, in validate
    for i, (input, target) in enumerate(val_loader):
  File "/home/yimengzh/miniconda2/envs/pytorch/lib/python3.5/site-packages/torch/utils/data/dataloader.py", line 168, in __next__
    idx, batch = self.data_queue.get()
  File "/home/yimengzh/miniconda2/envs/pytorch/lib/python3.5/queue.py", line 164, in get
    self.not_empty.wait()
  File "/home/yimengzh/miniconda2/envs/pytorch/lib/python3.5/threading.py", line 293, in wait
    waiter.acquire()

das top zeigte folgendes, wenn es mit 1 Arbeiter feststeckte.

~top - 08:34:33 up 15 Tage, 20:03, 0 Benutzer, Lastdurchschnitt: 0.37, 0.39, 0.36Aufgaben: 894 insgesamt, 1 läuft, 892 schlafend, 0 gestoppt, 1 ZombieCPU(s): 7,2%us, 2,8%sy, 0,0%ni, 89,7%id, 0,3%wa, 0,0%hi, 0,0%si, 0,0%stMem: 132196824k insgesamt, 131461528k gebraucht, 735296k frei, 347448k PufferSwap: 2047996k insgesamt, 22656k gebraucht, 2025340k kostenlos, 125226796k zwischengespeichert~

Eine andere Sache, die ich gefunden habe, ist, dass, wenn ich den Trainingscode so geändert habe, dass er nicht alle Batches durchläuft, sagen wir, nur 50 Batches trainieren

if i >= 50:
    break

dann scheint der Stillstand zu verschwinden.

Weitere Tests scheinen darauf hinzudeuten, dass dieses Einfrieren viel häufiger auftritt, wenn ich das Programm direkt nach dem Neustart des Computers ausgeführt habe. Nachdem sich etwas Cache im Computer befindet, scheint die Häufigkeit dieses Einfrierens geringer zu sein.

Ich habe es versucht, aber ich kann diesen Fehler in keiner Weise reproduzieren.

Ich bin auf ein ähnliches Problem gestoßen: Der Datenlader stoppt, wenn ich eine Epoche beende und eine neue Epoche beginnen wird.

Das Setzen von num_workers = 0 funktioniert. Aber das Programm wird langsamer.

@apaszke haben Sie versucht, den Computer zuerst neu zu auszuführen ? Für mich garantiert das das Einfrieren. Ich habe gerade die Version 0.12 ausprobiert, und es ist immer noch dasselbe.

Eine Sache, auf die ich hinweisen möchte, ist, dass ich die Pytorch mit pip installiert habe, da ich eine OpenBLAS-verknüpfte Numpy installiert habe und die MKL aus der Anaconda-Cloud von @soumith nicht gut damit spielen würde.

Im Wesentlichen verwendet pytorch MKL und numpy verwendet OpenBLAS. Das ist vielleicht nicht ideal, aber ich denke, das sollte hier nichts mit dem Thema zu tun haben.

Ich habe es mir angeschaut, aber ich konnte es nie reproduzieren. MKL/OpenBLAS sollte nichts mit diesem Problem zu tun haben. Es ist wahrscheinlich ein Problem mit einer Systemkonfiguration

@apaszke danke. Ich habe gerade das Python von Anaconda Official Repo und MKL-basiertem Pytorch ausprobiert. Immer noch das gleiche Problem.

habe versucht, den Code in Docker auszuführen. Immer noch stecken.

Wir haben das gleiche Problem, indem wir das pytorch/examples-Imagenet-Trainingsbeispiel (resnet18, 4 Worker) in einem nvidia-Docker mit 1 von 4 GPUs ausführen. Ich werde versuchen, einen gdb-Backtrace zu sammeln, wenn ich es schaffe, zum Prozess zu gelangen .

Zumindest OpenBLAS hat bekanntlich ein Deadlock-Problem bei der Matrixmultiplikation, das relativ selten auftritt: https://github.com/xianyi/OpenBLAS/issues/937. Dieser Fehler war zumindest in OpenBLAS vorhanden, das in numpy 1.12.0 verpackt war.

@jsainio Ich habe auch reines MKL-basiertes PyTorch ausprobiert (numpy ist auch mit MKL verknüpft) und das gleiche Problem.

Auch dieses Problem ist (zumindest bei mir) gelöst, wenn ich pin_memory für Dataloader ausschalte.

Es sieht so aus, als ob zwei der Arbeiter aussterben.

Im Normalbetrieb:

root<strong i="7">@b06f896d5c1d</strong>:~/mnt# ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
user+        1 33.2  4.7 91492324 3098288 ?    Ssl  10:51   1:10 python -m runne
user+       58 76.8  2.3 91079060 1547512 ?    Rl   10:54   1:03 python -m runne
user+       59 76.0  2.2 91006896 1484536 ?    Rl   10:54   1:02 python -m runne
user+       60 76.4  2.3 91099448 1559992 ?    Rl   10:54   1:02 python -m runne
user+       61 79.4  2.2 91008344 1465292 ?    Rl   10:54   1:05 python -m runne

nach dem abschließen:

root<strong i="11">@b06f896d5c1d</strong>:~/mnt# ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
user+        1 24.8  4.4 91509728 2919744 ?    Ssl  14:25  13:01 python -m runne
user+       58 51.7  0.0      0     0 ?        Z    14:27  26:20 [python] <defun
user+       59 52.1  0.0      0     0 ?        Z    14:27  26:34 [python] <defun
user+       60 52.0  2.4 91147008 1604628 ?    Sl   14:27  26:31 python -m runne
user+       61 52.0  2.3 91128424 1532088 ?    Sl   14:27  26:29 python -m runne

Für einen noch verbleibenden Worker sieht der Anfang des gdb-Stacktrace so aus:

root<strong i="15">@b06f896d5c1d</strong>:~/mnt# gdb --pid 60
GNU gdb (GDB) 8.0
Attaching to process 60
[New LWP 65]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
0x00007f36f52af827 in do_futex_wait.constprop ()
   from /lib/x86_64-linux-gnu/libpthread.so.0

(gdb) bt
#0  0x00007f36f52af827 in do_futex_wait.constprop ()
   from /lib/x86_64-linux-gnu/libpthread.so.0
#1  0x00007f36f52af8d4 in __new_sem_wait_slow.constprop.0 ()
   from /lib/x86_64-linux-gnu/libpthread.so.0
#2  0x00007f36f52af97a in sem_wait@@GLIBC_2.2.5 ()
   from /lib/x86_64-linux-gnu/libpthread.so.0
#3  0x00007f36f157efb1 in semlock_acquire (self=0x7f3656296458,
    args=<optimized out>, kwds=<optimized out>)
    at /home/ilan/minonda/conda-bld/work/Python-3.5.2/Modules/_multiprocessing/semaphore.c:307
#4  0x00007f36f5579621 in PyCFunction_Call (func=
    <built-in method __enter__ of _multiprocessing.SemLock object at remote 0x7f3656296458>, args=(), kwds=<optimized out>) at Objects/methodobject.c:98
#5  0x00007f36f5600bd5 in call_function (oparg=<optimized out>,
    pp_stack=0x7f36c7ffbdb8) at Python/ceval.c:4705
#6  PyEval_EvalFrameEx (f=<optimized out>, throwflag=<optimized out>)
    at Python/ceval.c:3236
#7  0x00007f36f5601b49 in _PyEval_EvalCodeWithName (_co=<optimized out>,
    globals=<optimized out>, locals=<optimized out>, args=<optimized out>,
    argcount=1, kws=0x0, kwcount=0, defs=0x0, defcount=0, kwdefs=0x0,
    closure=0x0, name=0x0, qualname=0x0) at Python/ceval.c:4018
#8  0x00007f36f5601cd8 in PyEval_EvalCodeEx (_co=<optimized out>,
    globals=<optimized out>, locals=<optimized out>, args=<optimized out>,
    argcount=<optimized out>, kws=<optimized out>, kwcount=0, defs=0x0,
    defcount=0, kwdefs=0x0, closure=0x0) at Python/ceval.c:4039
#9  0x00007f36f5557542 in function_call (
    func=<function at remote 0x7f36561c7d08>,
    arg=(<Lock(release=<built-in method release of _multiprocessing.SemLock object at remote 0x7f3656296458>, acquire=<built-in method acquire of _multiprocessing.SemLock object at remote 0x7f3656296458>, _semlock=<_multiprocessing.SemLock at remote 0x7f3656296458>) at remote 0x7f3656296438>,), kw=0x0)
    at Objects/funcobject.c:627
#10 0x00007f36f5524236 in PyObject_Call (
    func=<function at remote 0x7f36561c7d08>, arg=<optimized out>,
    kw=<optimized out>) at Objects/abstract.c:2165
#11 0x00007f36f554077c in method_call (
    func=<function at remote 0x7f36561c7d08>,
    arg=(<Lock(release=<built-in method release of _multiprocessing.SemLock object at remote 0x7f3656296458>, acquire=<built-in method acquire of _multiprocessing.SemLock object at remote 0x7f3656296458>, _semlock=<_multiprocessing.SemLock at remote 0x7f3656296458>) at remote 0x7f3656296438>,), kw=0x0)
    at Objects/classobject.c:330
#12 0x00007f36f5524236 in PyObject_Call (
    func=<method at remote 0x7f36556f9248>, arg=<optimized out>,
    kw=<optimized out>) at Objects/abstract.c:2165
#13 0x00007f36f55277d9 in PyObject_CallFunctionObjArgs (
    callable=<method at remote 0x7f36556f9248>) at Objects/abstract.c:2445
#14 0x00007f36f55fc3a9 in PyEval_EvalFrameEx (f=<optimized out>,
    throwflag=<optimized out>) at Python/ceval.c:3107
#15 0x00007f36f5601166 in fast_function (nk=<optimized out>, na=1,
    n=<optimized out>, pp_stack=0x7f36c7ffc418,
    func=<function at remote 0x7f36561c78c8>) at Python/ceval.c:4803
#16 call_function (oparg=<optimized out>, pp_stack=0x7f36c7ffc418)
    at Python/ceval.c:4730
#17 PyEval_EvalFrameEx (f=<optimized out>, throwflag=<optimized out>)
    at Python/ceval.c:3236
#18 0x00007f36f5601b49 in _PyEval_EvalCodeWithName (_co=<optimized out>,
    globals=<optimized out>, locals=<optimized out>, args=<optimized out>,
    argcount=4, kws=0x7f36f5b85060, kwcount=0, defs=0x0, defcount=0,
    kwdefs=0x0, closure=0x0, name=0x0, qualname=0x0) at Python/ceval.c:4018
#19 0x00007f36f5601cd8 in PyEval_EvalCodeEx (_co=<optimized out>,
    globals=<optimized out>, locals=<optimized out>, args=<optimized out>,
    argcount=<optimized out>, kws=<optimized out>, kwcount=0, defs=0x0,
    defcount=0, kwdefs=0x0, closure=0x0) at Python/ceval.c:4039
#20 0x00007f36f5557661 in function_call (
    func=<function at remote 0x7f36e14170d0>,
    arg=(<ImageFolder(class_to_idx={'n04153751': 783, 'n02051845': 144, 'n03461385': 582, 'n04350905': 834, 'n02105056': 224, 'n02112137': 260, 'n03938244': 721, 'n01739381': 59, 'n01797886': 82, 'n04286575': 818, 'n02113978': 268, 'n03998194': 741, 'n15075141': 999, 'n03594945': 609, 'n04099969': 765, 'n02002724': 128, 'n03131574': 520, 'n07697537': 934, 'n04380533': 846, 'n02114712': 271, 'n01631663': 27, 'n04259630': 808, 'n04326547': 825, 'n02480855': 366, 'n02099429': 206, 'n03590841': 607, 'n02497673': 383, 'n09332890': 975, 'n02643566': 396, 'n03658185': 623, 'n04090263': 764, 'n03404251': 568, 'n03627232': 616, 'n01534433': 13, 'n04476259': 868, 'n03495258': 594, 'n04579145': 901, 'n04266014': 812, 'n01665541': 34, 'n09472597': 980, 'n02095570': 189, 'n02089867': 166, 'n02009229': 131, 'n02094433': 187, 'n04154565': 784, 'n02107312': 237, 'n04372370': 844, 'n02489166': 376, 'n03482405': 588, 'n04040759': 753, 'n01774750': 76, 'n01614925': 22, 'n01855032': 98, 'n03903868': 708, 'n02422699': 352, 'n01560419': 1...(truncated), kw={}) at Objects/funcobject.c:627
#21 0x00007f36f5524236 in PyObject_Call (
    func=<function at remote 0x7f36e14170d0>, arg=<optimized out>,
    kw=<optimized out>) at Objects/abstract.c:2165
#22 0x00007f36f55fe234 in ext_do_call (nk=1444355432, na=0,
    flags=<optimized out>, pp_stack=0x7f36c7ffc768,
    func=<function at remote 0x7f36e14170d0>) at Python/ceval.c:5034
#23 PyEval_EvalFrameEx (f=<optimized out>, throwflag=<optimized out>)
    at Python/ceval.c:3275
--snip--

Ich hatte ein ähnliches Fehlerprotokoll, wobei der Hauptprozess hängen blieb: self.data_queue.get()
Für mich war das Problem, dass ich opencv als Imageloader verwendet habe. Und die Funktion cv2.imread hing auf unbestimmte Zeit ohne Fehler an einem bestimmten Image von imagenet ("n01630670/n01630670_1010.jpeg")

Wenn Sie sagten, dass es für Sie mit num_workers = 0 funktioniert, ist es das nicht. Aber ich dachte, es könnte einigen Leuten mit ähnlicher Fehlerverfolgung helfen.

Ich führe derzeit einen Test mit num_workers = 0 , noch keine Hänger. Ich führe den Beispielcode von https://github.com/pytorch/examples/blob/master/imagenet/main.py aus. pytorch/vision ImageFolder scheint PIL oder pytorch/accimage intern zu verwenden, um die Bilder zu laden, also ist kein OpenCV beteiligt.

Mit num_workers = 4 kann ich gelegentlich den Zug der ersten Epoche erhalten und vollständig validieren, und er sperrt sich in der Mitte der zweiten Epoche. Es ist also unwahrscheinlich, dass ein Problem in der Dataset-/Ladefunktion vorliegt.

Es sieht so aus wie eine Race Condition in ImageLoader, die relativ selten durch eine bestimmte Hardware/Software-Kombination ausgelöst wird.

@zym1010 danke für den pin_memory = False für den DataLoader einzustellen.

Interessant. In meinem Setup hängt das Imagenet-Beispiel beim Setzen von pin_memory = False und num_workers = 4 fast sofort und drei der Arbeiter enden als Zombie-Prozesse:

root<strong i="8">@034c4212d022</strong>:~/mnt# ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
user+        1  6.7  2.8 92167056 1876612 ?    Ssl  13:50   0:36 python -m runner
user+       38  1.9  0.0      0     0 ?        Z    13:51   0:08 [python] <defunct>
user+       39  4.3  2.3 91069804 1550736 ?    Sl   13:51   0:19 python -m runner
user+       40  2.0  0.0      0     0 ?        Z    13:51   0:09 [python] <defunct>
user+       41  4.1  0.0      0     0 ?        Z    13:51   0:18 [python] <defunct>

In meinem Setup liegt der Datensatz auf einer vernetzten Festplatte, die über NFS gelesen wird. Mit pin_memory = False und num_workers = 4 kann ich das System ziemlich schnell zum Ausfall bringen.

=> creating model 'resnet18'
- training epoch 0
Epoch: [0][0/5005]  Time 10.713 (10.713)    Data 4.619 (4.619)  Loss 6.9555 (6.9555)    Prec<strong i="8">@1</strong> 0.000 (0.000)    Prec<strong i="9">@5</strong> 0.000 (0.000)
Traceback (most recent call last):
--snip--
imagenet_pytorch.main.main([data_dir, "--transient_dir", context.transient_dir])
  File "/home/user/mnt/imagenet_pytorch/main.py", line 140, in main

train(train_loader, model, criterion, optimizer, epoch, args)
  File "/home/user/mnt/imagenet_pytorch/main.py", line 168, in train

for i, (input, target) in enumerate(train_loader):
  File "/home/user/anaconda/lib/python3.5/site-packages/torch/utils/data/dataloader.py", line 206, in __next__

idx, batch = self.data_queue.get()
  File "/home/user/anaconda/lib/python3.5/multiprocessing/queues.py", line 345, in get

return ForkingPickler.loads(res)
  File "/home/user/anaconda/lib/python3.5/site-packages/torch/multiprocessing/reductions.py", line 70, in rebuild_storage_fd

fd = df.detach()
  File "/home/user/anaconda/lib/python3.5/multiprocessing/resource_sharer.py", line 57, in detach

with _resource_sharer.get_connection(self._id) as conn:
  File "/home/user/anaconda/lib/python3.5/multiprocessing/resource_sharer.py", line 87, in get_connection

c = Client(address, authkey=process.current_process().authkey)
  File "/home/user/anaconda/lib/python3.5/multiprocessing/connection.py", line 493, in Client

answer_challenge(c, authkey)
  File "/home/user/anaconda/lib/python3.5/multiprocessing/connection.py", line 732, in answer_challenge

message = connection.recv_bytes(256)         # reject large message
  File "/home/user/anaconda/lib/python3.5/multiprocessing/connection.py", line 216, in recv_bytes

buf = self._recv_bytes(maxlength)
  File "/home/user/anaconda/lib/python3.5/multiprocessing/connection.py", line 407, in _recv_bytes

buf = self._recv(4)
  File "/home/user/anaconda/lib/python3.5/multiprocessing/connection.py", line 379, in _recv

chunk = read(handle, remaining)
ConnectionResetError
: 
[Errno 104] Connection reset by peer

@zym1010 haben Sie zufällig auch eine Netzwerkfestplatte oder eine herkömmliche sich drehende Festplatte, die in Latenz / etc. langsamer sein könnte?

@jsainio

Ich verwende eine lokale SSD auf dem Compute-Knoten des Clusters. Der Code befindet sich auf einem NFS-Laufwerk, aber die Daten befinden sich auf der lokalen SSD, um eine maximale Ladegeschwindigkeit zu erzielen. Nie versucht, Daten auf NFS-Laufwerke zu laden.

@zym1010 Danke für die Info. Ich führe dies auch auf einem Compute-Knoten eines Clusters aus.

Tatsächlich führe ich das num_workers = 0 Experiment auf demselben Knoten gleichzeitig aus, während ich die num_workers = 4 Variationen ausprobiere. Es könnte sein, dass das erste Experiment genug Last erzeugt, damit sich mögliche Race-Bedingungen in letzterem schneller manifestieren.

@apaszke Als Sie zuvor versucht haben, dies zu reproduzieren, haben Sie zufällig versucht, zwei Instanzen nebeneinander oder mit einer erheblichen anderen Last auf dem System auszuführen?

@jsainio Danke für die Untersuchung! Das ist seltsam, Arbeiter sollten nur zusammen austreten und wenn der Hauptprozess abgeschlossen ist, die Daten gelesen. Können Sie versuchen zu untersuchen, warum sie vorzeitig aussteigen? Vielleicht das Kernel-Log überprüfen ( dmesg )?

Nein, das habe ich nicht versucht, aber es schien zu erscheinen, auch wenn das nicht der Fall war IIRC

@apaszke Ok, gut zu wissen, dass die Arbeiter nicht hätten gehen sollen.

Ich habe es versucht, aber ich kenne keinen guten Weg, um zu überprüfen, warum sie aussteigen. dmesg zeigt nichts Relevantes an. (Ich laufe in einem von Ubuntu 16.04 abgeleiteten Docker mit Anaconda-Paketen)

Eine Möglichkeit wäre, eine Reihe von Drucken innerhalb der Worker-Schleife hinzuzufügen. Ich habe keine Ahnung, warum sie lautlos verschwinden. Dies ist wahrscheinlich keine Ausnahme, da es auf stderr gedruckt worden wäre, sodass sie entweder aus der Schleife ausbrechen oder vom Betriebssystem getötet werden (vielleicht durch ein Signal?)

@jsainio , nur um sicherzugehen, dass du Docker mit --ipc=host ausführst (du erwähnst das nicht)? Können Sie die Größe Ihres Shared Memory-Segments überprüfen (df -h | grep shm)?

@ngimel Ich verwende --shm-size=1024m . df -h | grep shm meldet entsprechend:

root<strong i="9">@db92462e8c19</strong>:~/mnt# df -h | grep shm
shm                                                          1.0G  883M  142M  87% /dev/shm

Diese Verwendung scheint ziemlich hoch hart zu sein. Dies ist auf einem Docker mit zwei Zombie-Arbeitern.

Können Sie versuchen, die Shm-Größe zu erhöhen? Ich habe gerade nachgesehen und auf dem Server, auf dem ich versucht habe, die Probleme zu reproduzieren, waren es 16 GB. Du änderst entweder das Docker-Flag oder führst aus

mount -o remount,size=8G /dev/shm

Ich habe gerade versucht, die Größe auf 512 MB zu verringern, aber ich habe einen klaren Fehler anstelle eines Deadlocks erhalten. Kann immer noch nicht reproduzieren 😕

Bei Docker bekommen wir eher Deadlocks, wenn shm nicht ausreicht, anstatt klare Fehlermeldungen, weiß nicht warum. Aber es wird normalerweise geheilt, indem man shm erhöht (und ich habe Deadlocks mit 1G bekommen).

Ok, es scheint, dass bei 10 Workern ein Fehler ausgegeben wird, aber wenn ich 4 Worker verwende, erhalte ich einen Deadlock bei 58% der /dev/shm-Nutzung! Ich habe es endlich reproduziert

Das ist großartig, dass Sie eine Form dieses Problems reproduzieren können. Ich habe in #1579 ein Skript gepostet, das einen Aufhänger auslöst, und Sie haben geantwortet, dass es auf Ihrem System nicht hängen geblieben ist. Ich hatte es eigentlich nur auf meinem MacBook getestet. Ich habe es gerade unter Linux versucht, und es hat sich nicht aufgehängt. Wenn Sie es also nur unter Linux versucht haben, lohnt es sich möglicherweise auch, es auf einem Mac auszuprobieren.

Ok, nach der Untersuchung des Problems scheint es ein seltsames Problem zu sein. Selbst wenn ich /dev/shm auf nur 128 MB beschränke, lässt Linux uns gerne 147 MB ​​Dateien dort erstellen, sie vollständig in den Speicher kopieren, sendet aber einen tödlichen SIGBUS an den Arbeiter, sobald es tatsächlich versucht, auf die Seiten zuzugreifen ... Ich kann mir keinen Mechanismus vorstellen, der es uns ermöglichen würde, die Gültigkeit der Seiten zu überprüfen, außer sie zu durchlaufen und jede einzelne mit einem registrierten SIGBUS-Handler zu berühren ...

Eine Problemumgehung für den Moment besteht darin, /dev/shm mit dem Befehl mount wie ich oben gezeigt habe. Versuchen Sie es mit 16 GB (ofc, wenn Sie genug RAM haben).

Es ist schwer, eine Erwähnung davon zu finden, aber hier ist eine .

Vielen Dank für Ihre Zeit zu diesem Thema, es hat mich schon lange wahnsinnig gemacht! Wenn ich das richtig verstehe, muss ich /dev/shm auf 16G statt auf 8G erweitern. Es macht Sinn, aber wenn ich df -h versuche, kann ich sehen, dass mein gesamter RAM tatsächlich als solcher zugewiesen ist: (Ich habe 16G)

tmpfs              7,8G    393M  7,4G   5% /dev/shm
tmpfs              5,0M    4,0K  5,0M   1% /run/lock
tmpfs              7,8G       0  7,8G   0% /sys/fs/cgroup
tmpfs              1,6G     60K  1,6G   1% /run/user/1001

Dies ist die Ausgabe von df -h während eines Deadlocks. Soweit ich weiß, kann ich, wenn ich eine SWAP-Partition von 16G habe, tmpfs bis zu 32G mounten, also sollte es kein Problem sein, /dev/shm , oder?

Noch wichtiger ist, dass ich über die cgroup-Partition und ihren Zweck verwirrt bin, da sie fast die Hälfte meines Arbeitsspeichers beansprucht. Anscheinend ist es darauf ausgelegt, Multi-Prozessor-Aufgaben effizient zu verwalten, aber ich bin wirklich nicht damit vertraut, was es tut und warum wir es brauchen setze es in SWAP (obwohl ich glaube, dass beide teilweise gleichzeitig im RAM und SWAP sein werden)

@apaszke Danke! Schön, dass Sie die Ursache gefunden haben. Ich bekam gelegentlich sowohl verschiedene "ConnectionReset"-Fehler als auch Deadlocks mit Docker --shm-size=1024m je nachdem, welche andere Last die Maschine hatte. Teste jetzt mit --shm-size=16384m und 4 Arbeitern.

@jsainio ConnectionReset könnte durch dasselbe verursacht worden sein. Die Prozesse begannen mit dem Austausch einiger Daten, aber sobald der Speicherplatz von shm aufgebraucht war, wurde ein SIGBUS an den Arbeiter gesendet und tötete ihn.

@ClementPinard Soweit ich /sys/fs/cgroup . tmpfs Partitionen weisen Speicher träge zu, so lange die Nutzung bei 0B bleibt, kostet es Sie nichts (einschließlich Limits). Ich denke nicht, dass die Verwendung von Swap eine gute Idee ist, da dies das Laden der Daten viel langsamer macht. Sie können also versuchen, die Größe von shm auf 12 GB zu erhöhen und die Anzahl der Arbeiter zu begrenzen (wie gesagt, Verwenden Sie nicht Ihren gesamten RAM für shm!). Hier ist eine nette Zusammenfassung zu tmpfs aus der Kernel-Dokumentation.

Ich weiß nicht, warum der Deadlock auftritt, selbst wenn die Nutzung von /dev/shm sehr gering ist (geschieht bei 20kB auf meinem Computer). Vielleicht ist der Kernel zu optimistisch, wartet aber nicht, bis Sie alles gefüllt haben, und beendet den Prozess, sobald er beginnt, irgendetwas aus dieser Region zu verwenden.

Teste jetzt mit 12G und der Hälfte der Arbeiter, die ich hatte, und es ist fehlgeschlagen :(
Es funktionierte wie ein Zauber in der Lua-Fackel-Version (gleiche Geschwindigkeit, gleiche Anzahl von Arbeitern), was mich fragen lässt, ob das Problem nur mit /dev/shm zusammenhängt und nicht näher an Python-Multiprocessing ist ...

Das Seltsame daran (wie Sie bereits erwähnt haben) ist, dass /dev/shm nie annähernd voll ist. Während der ersten Trainingsepoche ging es nie über 500Mo. Und es wird auch während der ersten Epoche nie gesperrt, und wenn ich das Testen von Trainloader herunterfahre, schlägt es in allen Epochen nie fehl. Der Deadlock scheint nur zu Beginn der Testepoche aufzutreten. Ich sollte /dev/shm im Auge behalten, wenn ich vom Zug zum Test gehe, vielleicht gibt es eine Spitzenauslastung während des Dataloader-Wechsels.

@ClementPinard selbst mit höherem Shared Memory und ohne Docker kann es immer noch fehlschlagen.

Wenn Fackelversion == Lua Torch, dann könnte es immer noch mit /dev/shm . Lua Torch kann Threads verwenden (es gibt keine GIL), daher muss es nicht durch ein gemeinsames Mem gehen (sie alle teilen sich einen einzigen Adressraum).

Ich hatte das gleiche Problem, bei dem der Dataloader abstürzt, nachdem ich mich beschwert hatte, dass er zu Beginn einer neuen Trainings- oder Validierungsepoche keinen Speicher zuweisen konnte. Die obigen Lösungen haben bei mir nicht funktioniert (i) mein /dev/shm ist 32 GB und es wurde nie mehr als 2,5 GB verwendet, und (ii) das Setzen von pin_memory=False hat nicht funktioniert.

Hat das vielleicht etwas mit der Müllabfuhr zu tun? Mein Code sieht ungefähr wie folgt aus. Ich brauche einen unendlichen Iterator und daher versuche ich es / außer um die next() unten :-)

def train():
    train_iter = train_loader.__iter__()
    for i in xrange(max_batches):
        try:
            x, y = next(train_iter)
        except StopIteration:
            train_iter = train_loader.__iter__()
        ...
    del train_iter

train_loader ist ein DataLoader Objekt. Ohne die explizite del train_iter Zeile am Ende der Funktion stürzt der Prozess immer nach 2-3 Epochen ab ( /dev/shm zeigt immer noch 2,5 GB an). Hoffe das hilft!

Ich verwende 4 Arbeiter (Version 0.1.12_2 mit CUDA 8.0 auf Ubuntu 16.04).

Ich bin auch auf den Deadlock gestoßen, besonders wenn die work_number groß ist. Gibt es eine mögliche Lösung für dieses Problem? Meine /dev/shm-Größe beträgt 32 GB, mit cuda 7.5, pytorch 0.1.12 und python 2.7.13. Das Folgende sind verwandte Informationen nach dem Tod. Es scheint mit der Erinnerung zusammenzuhängen. @apaszke

default
image

@zhengyunqq versuche pin_memory=False wenn du es auf True . Ansonsten ist mir keine Lösung bekannt.

Ich habe auch den Deadlock getroffen, wenn num_workers groß ist.

Für mich bestand das Problem darin, dass index_queue.put für immer hängt, wenn ein Worker-Thread aus irgendeinem Grund stirbt. Ein Grund für das Absterben von Arbeitsthreads ist das Versagen des Unpicklers während der Initialisierung. In diesem Fall würde der Worker-Thread bis zu diesem Python- Bugfix in Master im Mai 2017 sterben und das endlose Aufhängen verursachen. In meinem Fall geschah der Hänger in der Batch-Prefetching-Priming-Phase.

Vielleicht ein Ersatz von SimpleQueue das in DataLoaderIter durch Queue was eine Zeitüberschreitung mit einer eleganten Ausnahmemeldung ermöglicht.

UPD: Ich habe mich geirrt, dieser Bugfix patcht Queue , nicht SimpleQueue . Es ist immer noch wahr, dass SimpleQueue gesperrt wird, wenn keine Arbeitsthreads online sind. Eine einfache Möglichkeit, dies zu überprüfen, besteht darin, diese Zeilen durch self.workers = [] ersetzen.

Ich habe das gleiche Problem und kann shm nicht ändern (ohne Erlaubnis), vielleicht ist es besser, Warteschlange oder etwas anderes zu verwenden?

Ich habe ein ähnliches Problem.
Dieser Code friert ein und druckt nie etwas. Wenn ich num_workers=0 setze, funktioniert es jedoch

dataloader = DataLoader(transformed_dataset, batch_size=2, shuffle=True, num_workers=2)
model.cuda()
for i, batch in enumerate(dataloader):
 print(i)

Wenn ich model.cuda() hinter die Schleife stecke, wird alles gut laufen.

dataloader = DataLoader(transformed_dataset, batch_size=2, shuffle=True, num_workers=2)

for i, batch in enumerate(dataloader):
 print(i)
model.cuda()

Hat jemand eine Lösung für dieses Problem?

Ich bin beim Training von ImageNet auch auf ähnliche Probleme gestoßen. Es hängt bei der 1. Iteration der Evaluierung konsistent auf bestimmten Servern mit bestimmter Architektur (und nicht auf anderen Servern mit der gleichen Architektur oder dem gleichen Server mit anderer Architektur), aber immer beim 1. Iter während der Evaluierung auf der Validierung. Als ich Torch benutzte, stellten wir fest, dass nccl einen solchen Deadlock verursachen kann. Gibt es eine Möglichkeit, dies zu deaktivieren?

Ich stehe vor dem gleichen Problem und bleibe zufällig zu Beginn der 1. Epoche hängen. Alle oben genannten Problemumgehungen funktionieren bei mir nicht. Wenn Strg-C gedrückt wird, werden diese gedruckt:

Traceback (most recent call last):
  File "/home/zhangheng_li/applications/anaconda3/lib/python3.6/multiprocessing/process.py", line 249, in _bootstrap
    self.run()
  File "/home/zhangheng_li/applications/anaconda3/lib/python3.6/multiprocessing/process.py", line 93, in run
    self._target(*self._args, **self._kwargs)
  File "/home/zhangheng_li/applications/anaconda3/lib/python3.6/site-packages/torch/utils/data/dataloader.py", line 44, in _worker_loop
    data_queue.put((idx, samples))
  File "/home/zhangheng_li/applications/anaconda3/lib/python3.6/multiprocessing/queues.py", line 354, in put
    self._writer.send_bytes(obj)
  File "/home/zhangheng_li/applications/anaconda3/lib/python3.6/multiprocessing/connection.py", line 200, in send_bytes
    self._send_bytes(m[offset:offset + size])
  File "/home/zhangheng_li/applications/anaconda3/lib/python3.6/multiprocessing/connection.py", line 398, in _send_bytes
    self._send(buf)
  File "/home/zhangheng_li/applications/anaconda3/lib/python3.6/multiprocessing/connection.py", line 368, in _send
    n = write(self._handle, buf)
KeyboardInterrupt
Traceback (most recent call last):
  File "scripts/train_model.py", line 640, in <module>
    main(args)
  File "scripts/train_model.py", line 193, in main
    train_loop(args, train_loader, val_loader)
  File "scripts/train_model.py", line 341, in train_loop
    ee_optimizer.step()
  File "/home/zhangheng_li/applications/anaconda3/lib/python3.6/site-packages/torch/optim/adam.py", line 74, in step
    p.data.addcdiv_(-step_size, exp_avg, denom)
KeyboardInterrupt

Ich hatte ein ähnliches Problem mit einem Deadlock mit einem einzelnen Arbeiter im Docker und ich kann bestätigen, dass es in meinem Fall das Problem mit dem gemeinsamen Speicher war. Standardmäßig scheint Docker nur 64 MB Shared Memory zuzuweisen, ich habe jedoch 440 MB für 1 Worker benötigt, was wahrscheinlich das von @apaszke beschriebene Verhalten verursacht hat.

Ich habe das gleiche Problem, aber ich befinde mich in einer anderen Umgebung als die meisten anderen in diesem Thread, daher können meine Beiträge vielleicht helfen, die zugrunde liegende Ursache zu finden. Mein pytorch wird mit dem ausgezeichneten Conda-Paket installiert, das von peterjc123 unter Windows10 erstellt wurde.

Ich führe einige cnn auf dem cifar10-Datensatz aus. Für die Dataloader ist num_workers auf 1 gesetzt. Obwohl num_workers > 0 bekanntermaßen BrokenPipeError verursacht und in #494 davon abgeraten wird, erlebe ich nicht BrokenPipeError, sondern einen Fehler bei der Speicherzuordnung. Der Fehler trat immer bei etwa 50 Epochen auf, direkt nach der Validierung der letzten Epoche und vor Beginn des Trainings für die nächste Epoche. In 90% der Fälle sind es genau 50 Epochen, manchmal liegt es 1 oder 2 Epochen daneben. Ansonsten ist alles andere ziemlich stimmig. Durch Setzen von num_workers=0 wird dieses Problem behoben.

@paulguerrero hat recht. Ich habe dieses Problem gelöst, indem ich den Shared Memory von 64M auf 2G erhöht habe. Vielleicht ist es nützlich für Docker-Benutzer.

@berzjackson Das ist ein bekannter Fehler im Conda-Paket. In den neuesten CI-Builds behoben.

Wir haben ~600 Leute, die am Montag einen neuen Kurs begonnen haben, der Pytorch verwendet. Viele Leute in unserem Forum berichten von diesem Problem. Einige auf AWS P2, einige auf eigenen Systemen (hauptsächlich GTX 1070, einige Titan X).

Wenn sie das Training unterbrechen, zeigt das Ende des Stack-Trace:

~/anaconda2/envs/fastai/lib/python3.6/multiprocessing/connection.py in _recv_bytes(self, maxsize)
    405 
    406     def _recv_bytes(self, maxsize=None):
--> 407         buf = self._recv(4)
    408         size, = struct.unpack("!i", buf.getvalue())
    409         if maxsize is not None and size > maxsize:

~/anaconda2/envs/fastai/lib/python3.6/multiprocessing/connection.py in _recv(self, size, read)
    377         remaining = size
    378         while remaining > 0:
--> 379             chunk = read(handle, remaining)
    380             n = len(chunk)
    381             if n == 0:

Wir haben num_workers=4, pin_memory=False. Ich habe sie gebeten, ihre Shared Memory-Einstellungen zu überprüfen - aber kann ich etwas tun (oder wir in Pytorch tun), um dieses Problem zu beheben? (Abgesehen von der Reduzierung von num_workers, da dies die Dinge ziemlich verlangsamen würde.)

Ich werde in der Klasse @jph00 (danke Jeremy! :) ) bezeichnet. Ich habe es auch mit "num_workers=0" versucht. Erhalten Sie immer noch den gleichen Fehler, bei dem resnet34 sehr langsam lädt. Die Anpassung ist auch sehr langsam. Aber das Seltsame: Das passiert nur einmal im Leben einer Notebook-Sitzung.

Mit anderen Worten, sobald die Daten geladen und die Anpassung einmal ausgeführt wurde, kann ich mich bewegen und die Schritte wiederholen ... sogar mit 4 num_workern, und alles scheint in einer GPU wie erwartet schnell zu funktionieren.

Ich verwende PyTorch 0.2.0_4, Python 3.6.2, Torchvision 0.1.9, Ubuntu 16.04 LTS. Wenn ich auf meinem Terminal "df -h" ausführe, habe ich 16 GB auf /dev/shm, obwohl die Auslastung sehr gering war.

Hier ist ein Screenshot, wo das Laden fehlschlägt (beachten Sie, dass ich num_workers=0 für die Daten verwendet habe)
(Entschuldigung wegen der Kleinbuchstaben. Ich musste rauszoomen, um alles einzufangen...)

screenshot 2017-11-01 13 55 46

@apiltamang Ich bin mir nicht sicher, ob das das gleiche Problem ist - es klingt überhaupt nicht nach den gleichen Symptomen. Das diagnostizieren wir am besten im fast.ai-Forum, nicht hier.

schau dir das so schnell wie möglich an!

@soumith Ich habe @apaszke Zugriff auf das private Forum des Kurses

@jph00 Hallo Jeremy, hat einer der Schüler versucht, shm wie oben von @apaszke erwähnt zu

@SsnL einer der Studenten hat bestätigt, dass er den gemeinsamen Speicher erhöht hat und das Problem immer noch besteht. Ich habe auch einige andere um Bestätigung gebeten.

@jph00 Danke! Ich habe den Hang aufgrund von geringem Shared Memory erfolgreich reproduziert. Wenn das Problem woanders liegt, muss ich tiefer graben! Macht es Ihnen etwas aus, das Skript mit mir zu teilen?

Sicher - hier ist das Notebook, das wir verwenden: https://github.com/fastai/fastai/blob/master/courses/dl1/lesson1.ipynb . Die Schüler haben festgestellt, dass das Problem nur auftritt, wenn sie alle Zellen in der Reihenfolge ausführen, in der sie sich im Notebook befinden. Hoffentlich ist das Notizbuch selbsterklärend, aber lassen Sie es mich wissen, wenn Sie Probleme beim Ausführen haben - es enthält einen Link zum Herunterladen der erforderlichen Daten.

Gibt es aufgrund des Problems mit gemeinsam genutztem Speicher, das Sie replizieren könnten, irgendeine Art von Problemumgehung, die ich unserer Bibliothek oder unserem Notebook hinzufügen könnte, um dies zu vermeiden?

@jph00 Ich tauche gerade in den Code ein. Ich werde versuchen, Wege zu finden, um die Nutzung des gemeinsam genutzten Speichers zu reduzieren. Es scheint nicht, dass das Skript viel shm verwenden sollte, also besteht Hoffnung!

Ich werde auch eine PR senden, um eine nette Fehlermeldung anzuzeigen, wenn das Shm-Limit erreicht wird, anstatt es einfach hängen zu lassen.

OK, ich habe das Problem auf einer neuen AWS P2-Instance mit ihrem CUDA 9-AMI mit der neuesten Pytorch-Conda-Installation repliziert. Wenn Sie Ihren öffentlichen Schlüssel angeben, kann ich Ihnen den Zugang zum direkten Ausprobieren geben. Meine E-Mail ist der Anfangsbuchstabe meines Vornamens bei fast.ai

@jph00 Habe dir gerade eine E-Mail geschickt :) Danke!

@jph00 Und zu

OK, also habe ich das grundlegende Problem herausgefunden, das darin besteht, dass opencv und Pytorch Multiprocessing manchmal nicht gut zusammenspielen. Keine Probleme auf unserer Box an der Universität, aber viele Probleme auf AWS (auf dem neuen Deep Learning CUDA 9 AMI mit P2-Instance). Das Hinzufügen von Sperren um alle cv2-Aufrufe behebt es nicht, und das Hinzufügen von cv2.setNumThreads(0) behebt es nicht. Dies scheint das Problem zu beheben:

from multiprocessing import set_start_method
set_start_method('spawn')

Dies beeinträchtigt jedoch die Leistung um etwa 15 %. Die Empfehlung in der Opencv-Github-Ausgabe lautet https://github.com/tomMoral/loky . Ich habe dieses Modul schon einmal verwendet und fand es grundsolide. Nicht dringend, da wir eine Lösung haben, die im Moment gut genug funktioniert - aber vielleicht eine Überlegung wert wäre, Loky für Dataloader zu verwenden?

Vielleicht noch wichtiger, es wäre schön, wenn es zumindest eine Art Timeout in der Warteschlange von Pytorch gäbe, damit diese unendlichen Hänger abgefangen würden.

Zu Ihrer Information, ich habe gerade einen anderen Fix ausprobiert, da 'spawn' einige Teile 2-3x langsamer machte - das heißt, ich habe ein paar zufällige Sleeps in Abschnitten hinzugefügt, die den Dataloader schnell durchlaufen. Das hat das Problem auch behoben - wenn auch vielleicht nicht ideal!

Danke, dass du dich darauf eingelassen hast! Schön zu wissen, dass Sie zwei Problemumgehungen gefunden haben. Tatsächlich wäre es gut, Zeitüberschreitungen bei der Indizierung in Datasets hinzuzufügen. Wir werden diese Route morgen besprechen und uns mit Ihnen in Verbindung setzen.

cc @soumith ist etwas, das wir untersuchen möchten?

Für Leute, die für die obige Diskussion zu diesem Thread kommen, wird das opencv-Problem unter https://github.com/opencv/opencv/issues/5150 ausführlicher erörtert

OK, ich scheine jetzt eine richtige Lösung dafür zu haben - ich habe Dataloader auf Benutzer ProcessPoolExecutor.map() umgeschrieben und die Erstellung des Tensors in den übergeordneten Prozess verschoben. Das Ergebnis ist schneller, als ich es mit dem ursprünglichen Dataloader gesehen habe, und es war auf allen Computern stabil, auf denen ich es ausprobiert habe. Der Code ist auch viel einfacher.

Wenn jemand daran interessiert ist, es zu verwenden, können Sie es von https://github.com/fastai/fastai/blob/master/fastai/dataloader.py abrufen .

Die API ist die gleiche wie die Standardversion, außer dass Ihr Dataset keinen Pytorch-Tensor zurückgeben darf - es sollte numpy Arrays oder Python-Listen zurückgeben. Ich habe nicht versucht, es auf älteren Pythons zum Laufen zu bringen, daher wäre ich nicht überrascht, wenn es da einige Probleme geben würde.

(Der Grund, warum ich diesen Weg eingeschlagen habe, ist, dass ich bei vielen Bildverarbeitungen / Bilderweiterungen auf neueren GPUs festgestellt habe, dass ich die Verarbeitung nicht schnell genug abschließen konnte, um die GPU zu beschäftigen, wenn ich die Vorverarbeitung mit Pytorch-CPU durchführte Operationen; die Verwendung von opencv war jedoch viel schneller, und ich konnte die GPU dadurch vollständig nutzen.)

Oh, wenn es ein opencv-Problem ist, können wir nicht viel dagegen tun. Es stimmt, dass Forking gefährlich ist, wenn Sie Thread-Pools haben. Ich glaube nicht, dass wir eine Laufzeitabhängigkeit hinzufügen möchten (derzeit haben wir keine), insbesondere, dass sie PyTorch-Tensoren nicht gut handhabt. Es wäre besser, einfach herauszufinden, was die Deadlocks verursacht und @SsnL ist darauf.

@jph00 hast du Pillow-SIMD ausprobiert? Es sollte mit Torchvision out of the box funktionieren und ich habe viel Gutes darüber gehört.

Ja, ich kenne Kissen-SIMD gut. Es beschleunigt nur die Größenänderung, Unschärfe und RGB-Konvertierung.

Ich stimme nicht zu, dass Sie hier nicht viel tun können. Es ist nicht gerade ein opencv-Problem (sie behaupten nicht, diese Art von Python-Multiprocessing im Allgemeinen zu unterstützen, geschweige denn das spezielle Multi-Processing-Modul von pytorch) und auch nicht gerade ein Pytorch-Problem. Aber die Tatsache, dass Pytorch stumm wartet, ohne irgendwelche Fehler auszugeben, ist (IMO) etwas, das Sie beheben können, und ganz allgemein haben viele kluge Leute in den letzten Jahren hart daran gearbeitet, verbesserte Multiprocessing-Ansätze zu entwickeln, die Probleme einfach vermeiden wie dieser. Sie könnten sich von den Ansätzen borgen, die sie verwenden, ohne eine externe Abhängigkeit einzubringen.

Olivier Grisel, einer der Leute hinter Loky, hat ein großartiges Slide-Deck, das den Stand des Multiprocessing in Python zusammenfasst: http://ogrisel.github.io/decks/2017_euroscipy_parallelism/

Mir macht es nichts aus, da ich jetzt einen neuen Dataloader geschrieben habe, der das Problem nicht hat. Aber ich, FWIW, vermute, dass Interaktionen zwischen dem Multiprocessing von pytorch und anderen Systemen in Zukunft auch für andere ein Problem sein werden.

Für das, was es wert ist, hatte ich dieses Problem mit Python 2.7 unter Ubuntu 14.04. Mein Datenlader las aus einer SQLite-Datenbank und funktionierte perfekt mit num_workers=0 , schien manchmal mit num_workers=1 Ordnung zu sein und war bei jedem höheren Wert sehr schnell festgefahren. Stacktraces zeigten, dass der Prozess in recv_bytes hängen blieb.

Dinge, die nicht funktioniert haben:

  • Übergeben von --shm-size 8G oder --ipc=host beim Starten von Docker
  • Ausführen von echo 16834 | sudo tee /proc/sys/kernel/shmmni , um die Anzahl der Shared Memory-Segmente zu erhöhen (der Standardwert war 4096 auf meinem Computer)
  • Einstellung von pin_memory=True oder pin_memory=False , keiner hat geholfen

Die Sache, die mein Problem zuverlässig behoben hat, war die Portierung meines Codes auf Python 3. Das Starten der gleichen Version von Torch in einer Python 3.6-Instanz (von Anaconda) hat mein Problem vollständig behoben und das Laden von Daten hängt jetzt nicht mehr.

@apaszke hier ist, warum es wichtig ist, gut mit opencv zu arbeiten, FYI (und warum Fackelprobe keine gute Option ist - es kann eine Rotation von <200 Bildern/Sek. verarbeiten!):
image

Hat jemand eine Lösung für dieses Problem gefunden?

@iqbalu Probieren Sie das obige Skript aus: https://github.com/fastai/fastai/blob/master/fastai/dataloader.py
Es hat mein Problem gelöst, aber es unterstützt nicht num_workers=0 .

@elbaro eigentlich habe ich es ausprobiert und in meinem Fall wurden überhaupt nicht mehrere Arbeiter verwendet. Hast du da was geändert?

@iqbalu Fast.ai Data Loader erzeugt nie Arbeitsprozesse. Es verwendet nur Threads, daher werden sie in einigen Tools möglicherweise nicht angezeigt

@apaszke @elbaro @jph00 Der

Es ist wahrscheinlich, dass der Datenlader Pakete verwendet, die die GIL nicht aufgeben

@apaszke keine Ahnung, warum die Nutzung von Shared-Memory nach einigen Epochen weiter zunimmt. In meinem Fall beginnt es mit 400 MB und erhöht sich dann jede ~ 20. Epoche um 400 MB. Danke!

@iqbalu nicht wirklich. Das sollte nicht passieren

Ich habe viele Dinge ausprobiert und cv2.setNumThreads(0) mein Problem endlich gelöst.

Danke @jph00

Dieses Problem beschäftigt mich seit kurzem. cv2.setNumThreads(0) funktioniert bei mir nicht. Ich ändere sogar den gesamten CV2-Code, um stattdessen Scikit-Image zu verwenden, aber das Problem besteht immer noch. Außerdem habe ich 16G für /dev/shm . Ich habe dieses Problem nur, wenn ich mehrere GPUs verwende. Auf einer einzelnen GPU funktioniert alles einwandfrei. Hat jemand neue Ideen zur Lösung?

Gleicher Fehler. Ich habe dieses Problem, wenn ich eine einzelne GPU verwende.

Für mich hat das Deaktivieren von opencv-Threads das Problem gelöst:
cv2.setNumThreads(0)

schlagen Sie es auch mit pytorch 0.3, cuda 8.0, ubuntu 16.04
kein opencv verwendet.

Ich verwende Pytorch 0.3, Cuda 8.0, Ubuntu 14.04. Beobachtete diesen hängen, nachdem ich angefangen habe, cv2.resize() zu verwenden

cv2.setNumThreads(0) hat mein Problem gelöst.

Ich verwende Python 3.6, Pytorch 0.3.0, Cuda 8.0 und Ubuntu 17.04 auf einem System mit zwei 1080Ti und 32 GB RAM.

Wenn ich 8 Worker für mein eigenes Dataset verwende, sehe ich häufig den Deadlock (er tritt in der ersten Epoche auf). Wenn ich die Arbeiter auf 4 reduziere, verschwindet es (ich habe 80 Epochen gefahren).

Wenn ein Deadlock auftritt, habe ich immer noch ~10 GB freien RAM.

screenshot from 2018-03-02 19-57-47

Hier sehen Sie das Log nach dem Beenden des Skripts: https://gist.github.com/milani/42f50c023cdca407115b309237d29c70

UPDATE: Ich bestätige, dass ich das Problem durch Erhöhen von SHMMNI beheben konnte. Unter Ubuntu 17.04 habe ich kernel.shmmni=8192 zu /etc/sysctl.conf hinzugefügt.

Dieses Problem tritt auch bei Ubuntu 17.10, Python 3.6, Pytorch 0.3.1, CUDA 8.0 auf. Es ist viel RAM übrig, wenn der Deadlock auftritt und die Zeit inkonsistent zu sein scheint - kann nach der 1. Epoche oder nach der 200. Epoche passieren.

Die Kombination aus kernel.shmmni=8192 und cv2.setNumThreads(0) scheint Abhilfe zu schaffen, obwohl sie einzeln nicht funktionierten.

In meinem Fall das gleiche. Ich habe einen Deadlock erlebt, wenn ich num_workers=4 eingerichtet habe. Ich verwende Ubuntu 17.10, Pytorch 0.3.1, CUDA 9.1, Python 3.6. Es ist zu beobachten, dass es 4 Python-Threads gibt, von denen jeder 1,6 GB Speicher belegt, während die CPU (4 Kerne) im Leerlauf bleibt. Das Setzen von num_workers=0 hilft, dieses Problem zu lösen.

Ich habe das gleiche Problem, friert nach genau einer Epoche ein, aber für kleinere Datensätze nicht wirklich reproduzierbar. Ich verwende CUDA 9.1, Pytorch 0.3.1, Python 3.6 in einer Docker-Umgebung.
Ich habe den Dataloader von @jph00 ausprobiert, fand jedoch, dass er für meinen Anwendungsfall viel langsamer war. Meine Problemumgehung besteht derzeit darin, den Pytorch DataLoader vor jeder Epoche neu zu erstellen. Das scheint zu funktionieren, ist aber wirklich hässlich.

Ich hatte genau das gleiche Problem unter Ubuntu 17.10, CUDA 9.1, Pytorch-Master (kompiliert am 19.04. morgens). Auch OpenCV in meiner Dataset-Unterklasse verwenden.

Dann konnte ich den Deadlock vermeiden, indem ich die Multiprocessing-Startmethode von 'forkserver' auf 'spawn' änderte:

# Set multiprocessing start method - deadlock
set_start_method(forkserver')

# Set multiprocessing start method - runs fine
set_start_method('spawn')

Ich habe fast alle oben genannten Ansätze ausprobiert! Keiner von ihnen hat funktioniert!
Dieses Problem könnte mit einigen Inkompatibilitäten mit der Hardware-Architektur zusammenhängen und ich weiß nicht, wie Pytorch es provozieren kann! Es kann das Pytorch-Problem sein oder nicht!

So wurde mein Problem gelöst:
_Ich aktualisiere das BIOS!

Versuch es einmal. Das löst zumindest mein Problem.

Hier gilt das gleiche. Ubuntu PyTorch 0.4, Python3.6.

Es sieht so aus, als ob das Problem in pytorch 0.4 und python 3.6 noch besteht. Ich bin mir nicht sicher, ob es ein Pytorch-Problem ist. Ich benutze opencv und setze num_workers=8 , pin_memory=True . Ich probiere alle oben genannten Tricks aus und die Einstellung von cv2.setNumThreads(0) löst mein Problem.

(1) Das Setzen von num_workers=0 beim Laden von PyTorch-Daten löst das Problem (siehe oben) ODER
(2) cv2.setNumThreads(0) löst das Problem auch bei einigermaßen großen num_workers

Das sieht nach einer Art Thread-Locking-Problem aus.

Ich habe cv2.setNumThreads(0) irgendwo am Anfang meiner Python-Hauptdatei gesetzt und dieses Problem hatte ich seitdem nie mehr.

Ja, viele dieser Probleme sind darauf zurückzuführen, dass Bibliotheken von Drittanbietern nicht fork-sicher sind. Eine alternative Lösung könnte darin bestehen, die Spawn-Start-Methode zu verwenden.

Für mich tritt das Deadlock-Problem auf, wenn ich mein Modell mit nn.DataParallel umschließe und num_workers > 0 im Dataloader verwende. Durch das Entfernen des nn.DataParallel-Wrappers kann ich mein Skript ohne Sperren ausführen.
CUDA_VISIBLE_DEVICES=0 python myscript.py --split 1
CUDA_VISIBLE_DEVICES=1 python myscript.py --split 2

Ohne mehrere GPUs läuft mein Skript langsamer, aber ich kann mehrere Experimente gleichzeitig mit verschiedenen Teilen des Datasets ausführen.

Ich habe das gleiche Problem mit Python 3.6.2 / Pytorch 0.4.0.
und ich habe vor allem versucht, pin_memory zu wechseln, die Größe des Shared Memory zu ändern, und ich benutze die Skiamge-Bibliothek (ich benutze nicht cv2!!), aber ich habe immer noch ein Problem.

dieses Problem wird nach dem Zufallsprinzip ausgelöst. Die Kontrolle dieses Problems besteht darin, die Konsole zu beobachten und das Training neu zu starten.

@jinh574 Ich habe gerade die Anzahl der Data Loader-Worker auf 0 gesetzt und es funktioniert.

@ Shuailong Ich muss ein großes Bild verwenden, daher kann ich diese Parameter aus Geschwindigkeitsgründen nicht verwenden. Ich muss dieses Problem genauer untersuchen

Ich habe das gleiche Problem mit Python 3.6 / Pytorch 0.4.0. Beeinflusst die Option pin_memory etwas?

Wenn Sie collate_fn und num_workers>0 mit PyTorch-Version < 0.4 verwenden:

STELLEN SIE SICHER, DASS SIE NULL-DIM-TENSOREN VON IHRER __getitem__() FUNKTION NICHT ZURÜCKGEBEN.
ODER GEBEN SIE SIE ALS NUMPY ARRAYS ZURÜCK.

Ich habe dieses Problem auch nach dem Setzen von num_workers=0 oder cv2.setNumThreads(0).

Es schlägt mit einem dieser beiden Probleme fehl. Steht noch jemand vor dem gleichen Problem?

Traceback (letzter Anruf zuletzt):
Datei "/opt/conda/envs/pytorch-py3.6/lib/python3.6/runpy.py", Zeile 193, in _run_module_as_main
"__main__", mod_spec)
Datei "/opt/conda/envs/pytorch-py3.6/lib/python3.6/runpy.py", Zeile 85, in _run_code
exec(code, run_globals)
Datei "/opt/conda/envs/pytorch-py3.6/lib/python3.6/site-packages/torch/distributed/launch.py", Zeile 209, in
hauptsächlich()
Datei "/opt/conda/envs/pytorch-py3.6/lib/python3.6/site-packages/torch/distributed/launch.py", Zeile 205, in main
process.wait()
Datei "/opt/conda/envs/pytorch-py3.6/lib/python3.6/subprocess.py", Zeile 1457, in Wartestellung
(pid, sts) = self._try_wait(0)
Datei "/opt/conda/envs/pytorch-py3.6/lib/python3.6/subprocess.py", Zeile 1404, in _try_wait
(pid, sts) = os.waitpid(self.pid, wait_flags)
KeyboardInterrupt

Datei "/opt/conda/envs/pytorch-py3.6/lib/python3.6/multiprocessing/process.py", Zeile 258, in _bootstrap
self.run()
Datei "/opt/conda/envs/pytorch-py3.6/lib/python3.6/multiprocessing/process.py", Zeile 93, in Ausführung
self._target( self._args, * self._kwargs)
Datei "/opt/conda/envs/pytorch-py3.6/lib/python3.6/site-packages/torch/utils/data/dataloader.py", Zeile 96, in _worker_loop
r = index_queue.get(timeout=MANAGER_STATUS_CHECK_INTERVAL)
Datei "/opt/conda/envs/pytorch-py3.6/lib/python3.6/multiprocessing/queues.py", Zeile 104, in get
wenn nicht self._poll(timeout):
Datei "/opt/conda/envs/pytorch-py3.6/lib/python3.6/multiprocessing/connection.py", Zeile 257, in Umfrage
return self._poll(timeout)
Datei "/opt/conda/envs/pytorch-py3.6/lib/python3.6/multiprocessing/connection.py", Zeile 414, in _poll
r = warten([selbst], Zeitüberschreitung)
Datei "/opt/conda/envs/pytorch-py3.6/lib/python3.6/multiprocessing/connection.py", Zeile 911, in Wartestellung
ready = selector.select(timeout)
Datei "/opt/conda/envs/pytorch-py3.6/lib/python3.6/selectors.py", Zeile 376, in select
fd_event_list = self._poll.poll(timeout)
KeyboardInterrupt

Ich verwende Version '0.5.0a0+f57e4ce' und hatte das gleiche Problem. Entweder das Abbrechen des parallelen Datenladeprogramms (num_workers=0) oder das Setzen von cv2.setNumThreads(0) funktioniert.

Ich bin ziemlich zuversichtlich, dass #11985 alle Hänger beseitigen sollte (es sei denn, Sie unterbrechen zu unglücklichen Zeiten, die wir nicht kontrollieren können). Jetzt, da es zusammengeführt ist, schließe ich dies.

Das Problem mit cv2 liegt auch außerhalb unserer Kontrolle, da cv2 einfach nicht gut mit Multiprocessing spielt.

Ich erlebe dies immer noch ab torch_nightly-1.0.0.dev20181029 , wurde die PR dort noch nicht zusammengeführt?

@Evpok dies wurde dort zusammengeführt. Sie sollten diesen Patch auf jeden Fall haben. Ich frage mich, ob noch weitere Blockaden möglich sind. Haben Sie eine einfache Reproduktion, die wir uns ansehen können?

Ich habe es tatsächlich auf ein unabhängiges Multiprocessing-Chaos auf meiner Seite zurückgeführt, sorry für die Unannehmlichkeiten.

Hallo @Evpok
Ich benutze torch_nightly-1.0.0 und treffe dieses Problem. hast du dieses problem gelöst?

Wenn Sie collate_fn und num_workers>0 mit PyTorch-Version < 0.4 verwenden:

STELLEN SIE SICHER, DASS SIE NULL-DIM-TENSOREN VON IHRER __getitem__() FUNKTION NICHT ZURÜCKGEBEN.
ODER GEBEN SIE SIE ALS NUMPY ARRAYS ZURÜCK.

Ich habe meinen Fehler behoben, bei dem Nulltensoren zurückgegeben wurden, und das Problem besteht immer noch.

@zimenglan-sysu-512 Das Hauptproblem bestand in den Beschränkungen der Mehrfachverarbeitung: Bei Verwendung von spawn oder forkserver (was für die CPU-GPU-Kommunikation benötigt wird) ist die gemeinsame Nutzung von Objekten zwischen den Prozessen eher begrenzt und nicht geeignet für die Art von Objekten, die ich manipulieren muss.

Nichts davon hat bei mir funktioniert. Die neueste opencv funktioniert jedoch ( 3.4.0.12 bis 3.4.3.18 nichts anderes zu ändern):
sudo pip3 install --upgrade opencv-python

@see-- froh zu wissen, dass opencv ihr Ding repariert hat :)

Ich verwende OpenCV 3.4.3.18 mit Python2.7 und sehe immer noch, dass der Deadlock auftritt. :/

Bitte versuche folgendes:

from torch.utils.data.dataloader import DataLoader

anstatt

from torch.utils.data import DataLoader

Ich denke, es gibt ein Problem mit der Typprüfung hier:
https://github.com/pytorch/pytorch/blob/656b565a0f53d9f24547b060bd27aa67ebb89b88/torch/utils/data/dataloader.py#L816

Bitte versuche folgendes:

from torch.utils.data.dataloader import DataLoader

anstatt

from torch.utils.data import DataLoader

Ich denke, es gibt ein Problem mit der Typprüfung hier:

pytorch/torch/utils/data/dataloader.py

Linie 816 in 656b565
super(DataLoader, self).__setattr__(attr, val)

Ist das nicht nur ein Pseudonym? in Torch.utils.data.__init__ importieren sie dataloader.DataLoader

Ich hatte auch das Hängen mit num_workers > 0. Mein Code hat kein opencv und die Speichernutzung von /dev/shm ist kein Problem. Keine der obigen Vorschläge hat bei mir funktioniert. Mein Fix bestand darin, numpy von 1.14.1 auf 1.14.5 zu aktualisieren:
conda install numpy=1.14.5
Hoffe es ist hilfreich.

Hmm, meine numpy-Version ist 1.15.4, also neuer als 1.14.5... Sollte dann in Ordnung sein?

Hmm, meine numpy-Version ist 1.15.4, also neuer als 1.14.5... Sollte dann in Ordnung sein?

Idk, mein Update von numpy hat auch mkl aktualisiert.

Welche mkl-Version hast du? Meins ist 2019.1 (Build 144) und andere Pakete, die mkl in ihrem Namen enthalten, sind:

mkl-service 1.1.2 py37he904b0f_5
mkl_fft 1.0.6 py37hd81dba3_0
mkl_random 1.0.2 py37hd81dba3_0

Welche mkl-Version hast du? Meins ist 2019.1 (Build 144) und andere Pakete, die mkl in ihrem Namen enthalten, sind:

mkl-service 1.1.2 py37he904b0f_5
mkl_fft 1.0.6 py37hd81dba3_0
mkl_random 1.0.2 py37hd81dba3_0

conda list | grep mkl
mkl                       2018.0.1             h19d6760_4
mkl-service               1.1.2            py36h17a0993_4

Wenn Sie im neuesten pytorch immer noch hängen sehen, wäre es sehr hilfreich, wenn Sie ein kurzes Skript bereitstellen könnten, das das Problem reproduziert. Danke!

Ich sehe immer noch diesen Deadlock, ich werde sehen, ob ich ein Skript erstellen kann, das reproduziert.

pin_memory=True das Problem für mich gelöst.

Scheint bei mir mit pin_memory=True nicht zu funktionieren, bin nach 70 Epochen immer noch stecken geblieben. Das einzige, was bei mir bisher funktioniert hat, ist das Einstellen von num_workers=0 , aber es ist merklich langsamer.

Ich erlebe auch den Deadlock (tritt ziemlich zufällig auf). Habe pin_memory versucht und Numpy aktualisiert. Ich werde versuchen, es auf einem anderen Computer auszuführen.

Wenn Sie mehrere Threads mit darin enthaltenen Datenladern verwenden, versuchen Sie es mit Multiprocessing anstelle von Multithreading. Damit ist das Problem für mich komplett gelöst (und übrigens auch besser für rechenintensive Aufgaben in Python wegen der GIL)

gleicher Fehler in Pytorch1.0, Pillow5.0.0 numpy1.16.1 python3.6

Ich bekomme auch den gleichen Fehler. Ich habe pin_memory=True und num_workers=0 . Obwohl mir aufgefallen ist, dass dieser Fehler nicht auftritt, wenn ich einen kleinen Teil des Datasets verwende. Nur die Verwendung des gesamten Datensatzes verursacht diesen Fehler.

Edit: Nur ein einfacher Neustart des Systems hat es für mich behoben.

Ich hatte ein ähnliches Problem. In manchen Codes würde diese Funktion (fast immer) an d_iter.next() hängen bleiben:

def get_next_batch(d_iter, loader):
    try:
        data, label = d_iter.next()
    except StopIteration:
        d_iter = iter(loader)
        data, label = d_iter.next()
    return data, label

Der Hack, der für mich funktioniert hat, war, nach dem Aufrufen dieser Funktion eine kleine Verzögerung hinzuzufügen

trn_X, trn_y = get_next_batch(train_data_iter, train_loader)
time.sleep(0.003)
val_X, val_y = get_next_batch(valid_data_iter, valid_loader)

Ich denke, die Verzögerung hat dazu beigetragen, einen Stillstand zu vermeiden?

Dieses Problem treffe ich immer noch. Verwenden von pytorch 1.0 und python 3.7. Wenn ich mehrere data_loader verwendet habe, tritt dieser Fehler auf. Wenn ich weniger als 3 data_loader verwende oder eine einzelne GPU verwende, wird dieser Fehler nicht angezeigt. Versucht:

  1. time.sleep(0.003)
  2. pin_memory=Wahr/Falsch
  3. num_workers=0/1
  4. aus Torch.utils.data.dataloader importieren DataLoader
  5. 8192 nach /proc/sys/kernel/shmmni . schreiben
    Keiner von ihnen funktioniert. Sie wissen nicht, ob es Lösungen gibt?

Meine Lösungen fügen cv2.setNumThreads(0) beim Vorverarbeitungsprogramm hinzu
Ich habe 2 Dataloader, die für Zug und Val sind
Ich konnte den Evaluator nur einmal ausführen.

Ich bin gerade auf diesen Fehler mit pytorch 1.1 gestoßen. Derselbe blieb zweimal an derselben Stelle hängen: Ende der 99. Epoche. pin_memory wurde auf False .

Gleiches Problem bei Verwendung von Arbeitern > 0, Pin-Speicher hat das Problem nicht gelöst.

Meine Lösungen fügen cv2.setNumThreads(0) beim Vorverarbeitungsprogramm hinzu
Ich habe 2 Dataloader, die für Zug und Val sind
Ich konnte den Evaluator nur einmal ausführen.

Diese Lösung funktioniert bei mir, danke

der Datenlader stoppt, wenn ich eine Epoche beende und eine neue Epoche beginnen wird.

treffen auf das gleiche Problem. In meinem Fall tritt das Problem auf, wenn ich opencv-python installiere (ich habe opencv3 schon einmal installiert). Nach dem Verschieben von opencv-python wird das Training nicht aufhören.

das ist auch eine gute idee

Am 20.06.2019 10:51:02 schrieb "hongzhenwang" [email protected] :

der Datenlader stoppt, wenn ich eine Epoche beende und eine neue Epoche beginnen wird.

treffen auf das gleiche Problem. In meinem Fall tritt das Problem auf, wenn ich opencv-python installiere (ich habe opencv3 schon einmal installiert). Nach dem Verschieben von opencv-python wird das Training nicht aufhören.


Sie erhalten dies, weil Sie einen Kommentar abgegeben haben.
Antworten Sie direkt auf diese E-Mail, zeigen Sie sie auf GitHub an oder schalten Sie den Thread stumm.

Dieses Problem treffe ich immer noch. Verwenden von pytorch 1.0 und python 3.7. Wenn ich mehrere data_loader verwendet habe, tritt dieser Fehler auf. Wenn ich weniger als 3 data_loader verwende oder eine einzelne GPU verwende, wird dieser Fehler nicht angezeigt. Versucht:

1. time.sleep(0.003)

2. pin_memory=True/False

3. num_workers=0/1

4. from torch.utils.data.dataloader import DataLoader

5. writing 8192 to /proc/sys/kernel/shmmni
   None of them works. Don't know whether there is any solutions?

Versuche immer noch einen Workaround zu finden. Ich stimme zu, dass ich dieses Problem nur scheinbar habe, wenn ich 2 parallele Prozesse gleichzeitig auf verschiedenen GPUs ausführe. Einer macht weiter, während der andere innehält.

Wenn ich num_workers=4 setze, blieb das Programm alle 4 Batches für einige Sekunden (oder Minuten) hängen, was viel Zeit verschwendet. Irgendeine Idee, wie man es lösen kann?

Das Hinzufügen der Flags: pin_memory=True und num_workers=0 im Datenlader ist die Lösung!

Das Hinzufügen der Flags: pin_memory=True und num_workers=0 im Datenlader ist die Lösung!
@ArturoDeza
Dies könnte eine Lösung sein. Allerdings verlangsamt das Setzen von num_workers=0 den gesamten Datenabruf der CPU und die GPU-Nutzungsrate wird sehr niedrig sein.

Für mich lag der Grund darin, dass in meinem System nicht genügend CPUs vorhanden waren oder im Dataloader nicht genügend num_workers angegeben waren. Es kann auch eine gute Idee sein, Threading in den Dataloader-Workern zu deaktivieren, falls die Methode __get_item__ im Dataloader eine Threaded-Bibliothek wie numpy , librosa oder opencv (siehe unten, warum dies wichtig sein könnte). Dies können Sie erreichen, indem Sie Ihr Trainingsskript mit OMP_NUM_THREADS=1 MKL_NUM_THREADS=1 python train.py . Zur Klarstellung für die unten stehende Diskussion beachten Sie bitte, dass jeder Dataloader-Batch von einem einzelnen Mitarbeiter bearbeitet wird: Jeder Mitarbeiter bearbeitet batch_size Proben, um einen einzelnen Stapel zu vervollständigen, und beginnt dann mit der Verarbeitung eines neuen Datenstapels.

Sie müssen num_workers niedriger einstellen als die Anzahl der CPUs in der Maschine (oder im Pod, wenn Sie Kubernetes verwenden), aber hoch genug, damit die Daten immer für die nächste Iteration bereit sind. Wenn die GPU jede Iteration in t Sekunden ausführt und jeder Dataloader-Worker N*t Sekunden braucht, um einen einzelnen Batch zu laden/verarbeiten, dann sollten Sie num_workers auf mindestens N , um GPU-Störungen zu vermeiden. Natürlich müssen Sie mindestens N CPUs im System haben.

Wenn Dataloader eine Bibliothek verwendet, die K Threads verwendet, wird die Anzahl der erzeugten Prozesse leider zu num_workers*K = N*K . Dies kann deutlich höher sein als die Anzahl der CPUs in der Maschine. Dadurch wird der Pod gedrosselt und der Dataloader wird sehr langsam. Dies kann dazu führen, dass der Dataloader nicht alle t Sekunden einen Batch zurückgibt, was zu GPU-Störungen führt.

Eine Möglichkeit, K Threads zu vermeiden, besteht darin, das Hauptskript mit OMP_NUM_THREADS=1 MKL_NUM_THREADS=1 python train.py aufzurufen. Dies schränkt jeden Dataloader-Worker ein, einen einzelnen Thread zu verwenden, und vermeidet eine Überlastung des Computers. Sie müssen immer noch genug num_workers , um die GPU mit Strom zu versorgen.

Sie sollten Ihren Code auch in __get_item__ optimieren, damit jeder Worker seinen Batch in kurzer Zeit fertigstellt. Bitte stellen Sie sicher, dass die Zeit zum Abschließen der Vorverarbeitung eines Stapels durch den Mitarbeiter nicht durch die Zeit zum Lesen von Trainingsdaten von der Festplatte (insbesondere beim Lesen aus einem Netzwerkspeicher) oder die Netzwerkbandbreite (wenn Sie aus einem Netzwerk lesen) behindert wird Scheibe). Wenn Ihr Dataset klein ist und Sie über genügend RAM verfügen, ziehen Sie in Betracht, das Dataset in den RAM (oder /tmpfs ) zu verschieben und von dort aus zu lesen, um schnell darauf zugreifen zu können. Für Kubernetes können Sie eine RAM-Disk erstellen (suchen Sie in Kubernetes nach emptyDir ).

Wenn Sie Ihren __get_item__ Code optimiert und sichergestellt haben, dass der Festplattenzugriff/Netzwerkzugriff nicht die Schuldigen sind, Sie aber immer noch Blockaden sehen, müssen Sie mehr CPUs anfordern (für einen Kubernetes-Pod) oder Ihre GPU auf einen Maschine mit mehr CPUs.

Eine andere Möglichkeit besteht darin, die batch_size zu reduzieren, sodass jeder worker weniger Arbeit hat und die Vorverarbeitung schneller abgeschlossen wird. Letztere Option ist in manchen Fällen nicht wünschenswert, da im Leerlauf der GPU-Speicher nicht genutzt wird.

Sie könnten auch erwägen, einen Teil der Vorverarbeitung offline durchzuführen und jeden Mitarbeiter zu entlasten. Wenn beispielsweise jeder Worker eine WAV-Datei einliest und Spektrogramme für die Audiodatei berechnet, könnten Sie erwägen, die Spektrogramme offline vorab zu berechnen und das berechnete Spektrogramm einfach von der Festplatte im Worker zu lesen. Dadurch wird der Arbeitsaufwand jedes Mitarbeiters reduziert.

treffe das gleiche Problem mit horovod

Begegnen Sie einem ähnlichen Problem ... Deadlock, während gerade eine Epoche beendet wird und Daten zur Validierung geladen werden ...

@jinhou @jackroos Das Gleiche, bleibt zufällig am Anfang der Validierung mit Horovod hängen. Was ich derzeit als Problemumgehung mache, ist, ein Timeout festzulegen und die Validierung zu überspringen. Hast du eine Lösung?

@jinhou @jackroos Das Gleiche, bleibt zufällig am Anfang der Validierung mit Horovod hängen. Was ich derzeit als Problemumgehung mache, ist, ein Timeout festzulegen und die Validierung zu überspringen. Hast du eine Lösung?

Nein. In diesem Fall schalte ich das verteilte Training einfach aus.

Ich bin auf ein ähnliches Problem gestoßen: Der Datenlader stoppt, wenn ich eine Epoche beende und eine neue Epoche beginnen wird.

warum so viel zan?

Dieses Problem treffe ich immer noch. Verwenden von pytorch 1.0 und python 3.7. Wenn ich mehrere data_loader verwendet habe, tritt dieser Fehler auf. Wenn ich weniger als 3 data_loader verwende oder eine einzelne GPU verwende, wird dieser Fehler nicht angezeigt. Versucht:

  1. time.sleep(0.003)
  2. pin_memory=Wahr/Falsch
  3. num_workers=0/1
  4. aus Torch.utils.data.dataloader importieren DataLoader
  5. 8192 nach /proc/sys/kernel/shmmni . schreiben
    Keiner von ihnen funktioniert. Sie wissen nicht, ob es Lösungen gibt?

num_workers auf 0 gesetzt hat bei mir funktioniert. Sie sollten sicherstellen, dass sie überall auf 0 steht.

Einige andere mögliche Lösungen:

  1. aus Multiprocessing-Import set_start_method
    set_start_method('spawn')
  2. cv2.setNumThreads(0)

Es scheint, dass 3 oder 7 der richtige Weg sind.

Ich habe dieses Problem mit pytorch 1.3, ubuntu16, alle oben genannten Vorschläge funktionierten nicht, außer works=0, was die Ausführung verlangsamt. Dies geschieht nur beim Ausführen vom Terminal aus, innerhalb des Jupyter-Notebooks ist alles in Ordnung, sogar mit Workers=32.

Das Problem scheint nicht gelöst, sollte es erneut geöffnet werden? Ich sehe auch viele andere Leute, die das gleiche Problem melden...

Dieses Problem treffe ich immer noch. Verwenden von pytorch 1.0 und python 3.7. Wenn ich mehrere data_loader verwendet habe, tritt dieser Fehler auf. Wenn ich weniger als 3 data_loader verwende oder eine einzelne GPU verwende, wird dieser Fehler nicht angezeigt. Versucht:

  1. time.sleep(0.003)
  2. pin_memory=Wahr/Falsch
  3. num_workers=0/1
  4. aus Torch.utils.data.dataloader importieren DataLoader
  5. 8192 nach /proc/sys/kernel/shmmni . schreiben
    Keiner von ihnen funktioniert. Sie wissen nicht, ob es Lösungen gibt?

num_workers auf 0 gesetzt hat bei mir funktioniert. Sie sollten sicherstellen, dass sie überall auf 0 steht.

Einige andere mögliche Lösungen:

  1. aus Multiprocessing-Import set_start_method
    set_start_method('spawn')
  2. cv2.setNumThreads(0)

Es scheint, dass 3 oder 7 der richtige Weg sind.

Ich habe train.py wie folgt geändert:

from __future__ import division

import cv2
cv2.setNumThreads(0)

import argparse

...

Und es funktioniert für mich.

Hey Leute wenn ich helfen kann,
Ich hatte auch dieses ähnliche Problem, aber es passierte alle 100 oder so Epochen.

Mir ist aufgefallen, dass es nur bei aktiviertem CUDA passiert ist, auch dmesg hat diesen Log-Eintrag, wenn es abstürzt.

python[11240]: segfault at 10 ip 00007fabdd6c37d8 sp 00007ffddcd64fd0 error 4 in libcudart.so.10.1.243[7fabdd699000+77000]

Es ist für mich Kauderwelsch, aber es sagte mir, dass CUDA und Python-Multithreading nicht gut liefen.

Meine Lösung bestand darin, cuda in den Datathreads zu deaktivieren. Hier ist ein Ausschnitt meiner Python-Eintragsdatei.

from multiprocessing import set_start_method
import os

if __name__ == "__main__":
  set_start_method('spawn')
else:
  os.environ["CUDA_VISIBLE_DEVICES"] = ""

import torch
import application

Hoffentlich kann das jedem helfen, der hier landet, wie ich es damals brauchte.

@jinhou @jackroos Das Gleiche, bleibt zufällig am Anfang der Validierung mit Horovod hängen. Was ich derzeit als Problemumgehung mache, ist, ein Timeout festzulegen und die Validierung zu überspringen. Hast du eine Lösung?

Nein. In diesem Fall schalte ich das verteilte Training einfach aus.

Ich habe ein ähnliches Problem beim verteilten Training, ohne OpenCV zu verwenden, nach dem Update auf PyTorch 1.4.
Jetzt muss ich die Validierung einmal vor der Trainings- und Validierungsschleife ausführen.

Ich habe viel Mühe damit gehabt. Es scheint über Pytorch-Versionen, Python-Versionen und auch verschiedene physische Maschinen (die wahrscheinlich identisch eingerichtet wurden) bestehen zu bleiben.

Es ist jedes Mal der gleiche Fehler:

File "/home/<me>/miniconda2/envs/<my-module>/lib/python3.8/site-packages/bicep/loops.py", line 73, in __call__
    for data, target in self.dataloader:
File "/home/<me>/miniconda2/envs/<my-module>/lib/python3.8/site-packages/torch/utils/data/dataloader.py", line 345, in __next__
    data = self._next_data()
File "/home/<me>/miniconda2/envs/<my-module>/lib/python3.8/site-packages/torch/utils/data/dataloader.py", line 830, in _next_data
    self._shutdown_workers()
File "/home/<me>/miniconda2/envs/<my-module>/lib/python3.8/site-packages/torch/utils/data/dataloader.py", line 942, in _shutdown_workers
    w.join()
File "/home/<me>/miniconda2/envs/<my-module>/lib/python3.8/multiprocessing/process.py", line 149, in join
    res = self._popen.wait(timeout)
File "/home/<me>/miniconda2/envs/<my-module>/lib/python3.8/multiprocessing/popen_fork.py", line 47, in wait
    return self.poll(os.WNOHANG if timeout == 0.0 else 0)
File "/home/<me>/miniconda2/envs/<my-module>/lib/python3.8/multiprocessing/popen_fork.py", line 27, in poll
    pid, sts = os.waitpid(self.pid, flag)

Es gibt eindeutig ein Problem in der Art und Weise, wie Prozesse auf der Maschine gehandhabt werden, die ich verwende. Keine der oben genannten Lösungen scheint zu funktionieren, außer num_workers=0 zu setzen.

Ich würde dem wirklich gerne auf den Grund gehen, hat jemand eine Idee, wo ich anfangen soll oder wie man das abfragen kann?

Ich auch hier.

ERROR: Unexpected segmentation fault encountered in worker.
Traceback (most recent call last):
  File "/home/miniconda/lib/python3.6/site-packages/torch/utils/data/dataloader.py", line 480, in _try_get_batch
    data = self.data_queue.get(timeout=timeout)
  File "/home/miniconda/lib/python3.6/multiprocessing/queues.py", line 104, in get
    if not self._poll(timeout):
  File "/home/miniconda/lib/python3.6/multiprocessing/connection.py", line 257, in poll
    return self._poll(timeout)
  File "/home/miniconda/lib/python3.6/multiprocessing/connection.py", line 414, in _poll
    r = wait([self], timeout)
  File "/home/miniconda/lib/python3.6/multiprocessing/connection.py", line 911, in wait
    ready = selector.select(timeout)
  File "/home/miniconda/lib/python3.6/selectors.py", line 376, in select
    fd_event_list = self._poll.poll(timeout)
  File "/home/miniconda/lib/python3.6/site-packages/torch/utils/data/_utils/signal_handling.py", line 65, in handler
    _error_if_any_worker_fails()
RuntimeError: DataLoader worker (pid 95106) is killed by signal: Segmentation fault.

Eine interessante Sache ist

Wenn ich nur die Daten Zeile für Zeile parse, habe ich dieses Problem nicht:

        with open(current_file, mode='rb') as f:
            text = f.read().decode('utf-8')
            all_data.extend(text.split('\n'))

aber wenn ich nach dem zeilenweisen Lesen eine JSON-Parsing-Logik hinzufüge, wird dieser Fehler gemeldet

with open(current_file, mode='rb') as f:
            text = f.read().decode('utf-8')
            all_data.extend(text.split('\n'))

        json_data = []
        for line in all_data:
            try:
                json_data.append(json.loads(line))
            except:
                break
return json_data

Ich verstehe, dass es einen gewissen JSON-Speicher-Overhead geben wird, aber selbst wenn ich die Anzahl der Worker auf 2 verringere und der Datensatz sehr klein ist, besteht immer noch das gleiche Problem. Ich bezweifle, dass es mit Shm zu tun hat. irgendeine Ahnung?

Sollen wir dieses Thema noch einmal öffnen?

Ich denke wir sollten. Übrigens, ich habe ein GDB-Debugging durchgeführt und dort nichts gefunden. Daher bin ich mir nicht sicher, ob es sich um ein Problem mit dem gemeinsamen Speicher handelt.

(gdb) run

Starting program: /home/miniconda/bin/python performance.py

[Thread debugging using libthread_db enabled]

Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".

[New Thread 0x7fffa60a6700 (LWP 61963)]

[New Thread 0x7fffa58a5700 (LWP 61964)]

[New Thread 0x7fffa10a4700 (LWP 61965)]

[New Thread 0x7fff9e8a3700 (LWP 61966)]

[New Thread 0x7fff9c0a2700 (LWP 61967)]

[New Thread 0x7fff998a1700 (LWP 61968)]

[New Thread 0x7fff970a0700 (LWP 61969)]

[New Thread 0x7fff9489f700 (LWP 61970)]

[New Thread 0x7fff9409e700 (LWP 61971)]

[New Thread 0x7fff8f89d700 (LWP 61972)]

[New Thread 0x7fff8d09c700 (LWP 61973)]

[New Thread 0x7fff8a89b700 (LWP 61974)]

[New Thread 0x7fff8809a700 (LWP 61975)]

[New Thread 0x7fff85899700 (LWP 61976)]

[New Thread 0x7fff83098700 (LWP 61977)]

[New Thread 0x7fff80897700 (LWP 61978)]

[New Thread 0x7fff7e096700 (LWP 61979)]

[New Thread 0x7fff7d895700 (LWP 61980)]

[New Thread 0x7fff7b094700 (LWP 61981)]

[New Thread 0x7fff78893700 (LWP 61982)]

[New Thread 0x7fff74092700 (LWP 61983)]

[New Thread 0x7fff71891700 (LWP 61984)]

[New Thread 0x7fff6f090700 (LWP 61985)]

[Thread 0x7fff7e096700 (LWP 61979) exited]

[Thread 0x7fff6f090700 (LWP 61985) exited]

[Thread 0x7fff74092700 (LWP 61983) exited]

[Thread 0x7fff7b094700 (LWP 61981) exited]

[Thread 0x7fff80897700 (LWP 61978) exited]

[Thread 0x7fff83098700 (LWP 61977) exited]

[Thread 0x7fff85899700 (LWP 61976) exited]

[Thread 0x7fff8809a700 (LWP 61975) exited]

[Thread 0x7fff8a89b700 (LWP 61974) exited]

[Thread 0x7fff8d09c700 (LWP 61973) exited]

[Thread 0x7fff8f89d700 (LWP 61972) exited]

[Thread 0x7fff9409e700 (LWP 61971) exited]

[Thread 0x7fff9489f700 (LWP 61970) exited]

[Thread 0x7fff970a0700 (LWP 61969) exited]

[Thread 0x7fff998a1700 (LWP 61968) exited]

[Thread 0x7fff9c0a2700 (LWP 61967) exited]

[Thread 0x7fff9e8a3700 (LWP 61966) exited]

[Thread 0x7fffa10a4700 (LWP 61965) exited]

[Thread 0x7fffa58a5700 (LWP 61964) exited]

[Thread 0x7fffa60a6700 (LWP 61963) exited]

[Thread 0x7fff71891700 (LWP 61984) exited]

[Thread 0x7fff78893700 (LWP 61982) exited]

[Thread 0x7fff7d895700 (LWP 61980) exited]

total_files = 5040.  //customer comments

[New Thread 0x7fff6f090700 (LWP 62006)]

[New Thread 0x7fff71891700 (LWP 62007)]

[New Thread 0x7fff74092700 (LWP 62008)]

[New Thread 0x7fff78893700 (LWP 62009)]

ERROR: Unexpected segmentation fault encountered in worker.

ERROR: Unexpected segmentation fault encountered in worker.

Traceback (most recent call last):

File "/home/zhrui/.local/lib/python3.6/site-packages/torch/utils/data/dataloader.py", line 761, in _try_get_data

data = self._data_queue.get(timeout=timeout)

File "/home/miniconda/lib/python3.6/multiprocessing/queues.py", line 104, in get

if not self._poll(timeout):

File "/home/miniconda/lib/python3.6/multiprocessing/connection.py", line 257, in poll

return self._poll(timeout)

File "/home/miniconda/lib/python3.6/multiprocessing/connection.py", line 414, in _poll

r = wait([self], timeout)

File "/home/miniconda/lib/python3.6/multiprocessing/connection.py", line 911, in wait

ready = selector.select(timeout)

File "/home/miniconda/lib/python3.6/selectors.py", line 376, in select

fd_event_list = self._poll.poll(timeout)

File "/home/zhrui/.local/lib/python3.6/site-packages/torch/utils/data/_utils/signal_handling.py", line 66, in handler

_error_if_any_worker_fails()

RuntimeError: DataLoader worker (pid 62005) is killed by signal: Segmentation fault.

During handling of the above exception, another exception occurred:

Traceback (most recent call last):

File "performance.py", line 62, in <module>

main()

File "performance.py", line 48, in main

for i,batch in enumerate(rl_data_loader):

File "/home/zhrui/.local/lib/python3.6/site-packages/torch/utils/data/dataloader.py", line 345, in __next__

data = self._next_data()

File "/home/zhrui/.local/lib/python3.6/site-packages/torch/utils/data/dataloader.py", line 841, in _next_data

idx, data = self._get_data()

File "/home/zhrui/.local/lib/python3.6/site-packages/torch/utils/data/dataloader.py", line 808, in _get_data

success, data = self._try_get_data()

File "/home/zhrui/.local/lib/python3.6/site-packages/torch/utils/data/dataloader.py", line 774, in _try_get_data

raise RuntimeError('DataLoader worker (pid(s) {}) exited unexpectedly'.format(pids_str))

RuntimeError: DataLoader worker (pid(s) 62005) exited unexpectedly

[Thread 0x7fff78893700 (LWP 62009) exited]

[Thread 0x7fff74092700 (LWP 62008) exited]

[Thread 0x7fff71891700 (LWP 62007) exited]

[Thread 0x7fff6f090700 (LWP 62006) exited]

[Inferior 1 (process 61952) exited with code 01]

(gdb) backtrace

No stack.

Und ich denke, ich habe genug Shared Memory, zumindest erwarte ich, dass der Shared Memory für eine ziemlich lange Zeit gut genug ist, bis segfault, aber Segmentfehler treten fast unmittelbar nach dem Starten des Dataloader-Jobs auf

------ Messages Limits --------

max queues system wide = 32000

max size of message (bytes) = 8192

default max size of queue (bytes) = 16384

------ Shared Memory Limits --------

max number of segments = 4096

max seg size (kbytes) = 18014398509465599

max total shared memory (kbytes) = 18014398509481980

min seg size (bytes) = 1

------ Semaphore Limits --------

max number of arrays = 32000

max semaphores per array = 32000

max semaphores system wide = 1024000000

max ops per semop call = 500

semaphore max value = 32767

Hallo @soumith @apaszke , können wir dieses Problem erneut öffnen, ich habe alle vorgeschlagenen Lösungsvorschläge ausprobiert , z. aber Problem immer noch da. und ich glaube nicht, dass es mit shm zusammenhängt, da ich überprüft habe, dass ich den gesamten Speicher als gemeinsam genutzten Speicher öffne. Stacktrace zeigt dort auch nichts wie oben gepostet.

@apaszke , bezüglich Ihres Vorschlags an

„Ja, viele dieser Probleme sind darauf zurückzuführen, dass Bibliotheken von Drittanbietern nicht fork-sicher sind. Eine alternative Lösung könnte die Verwendung der Spawn-Start-Methode sein.“

Ich verwende Dataloader Multi Worker, wie kann ich die Methode ändern? Ich setze set_start_method('spawn') in meine main.py ein, aber es scheint nicht zu helfen

Außerdem habe ich hier eine allgemeine Frage, ob ich den Multi-Worker-(Multi-Prozess-)Datenlader aktiviere und in der Hauptschulung auch den Multi-Prozess starte, wie in https://pytorch.org/docs/stable/notes/multiprocessing.html vorgeschlagen #Multiprocessing -Best Practices

Wie verwaltet pytorch sowohl den Dataloader als auch den Haupttrainings-Multiprozess? werden sie alle möglichen Prozesse/Threading auf Multi-Core-GPU teilen? auch Shared Memory für Multiprozess wird von Data Loader und Haupttrainingsprozess "geteilt"? auch wenn ich einen Datenkochjob wie JSON-Parsing, CSV-Parsing, Pandas-Feature-Extraktion habe. etc, wo am besten hinstellen? im Dataloader, um perfekte Daten zu generieren, oder verwenden Sie einfach das Haupttraining, um dies zu tun, wie oben vorgeschlagen, um den Data Loader __get_item__ so einfach wie möglich zu halten

@zhangruiskyline Ihr Problem ist nicht wirklich eine Sackgasse. Es geht darum, dass die Arbeiter durch Segfault getötet werden. sigbus ist derjenige, der Shm-Probleme vorschlägt. Sie sollten Ihren Dataset-Code überprüfen und dort debuggen.

Um Ihre anderen Fragen zu beantworten,

  1. use kwarg multiproessing_context='spawn' im DataLoader wird Spawn setzen. set_start_method tut das auch.
  2. Normalerweise hat bei Multiprozess-Training jeder Prozess seinen eigenen DataLoader und damit DataLoader-Worker. Nichts wird zwischen Prozessen geteilt, es sei denn, dies wird ausdrücklich getan.

Danke @SsnL , ich habe multiproessing_context='spawn' hinzugefügt, aber der gleiche Fehler.

Ich habe im vorherigen Thread darauf hingewiesen, dass mein Code sehr einfach ist,

  • dieser Code funktioniert
        with open(current_file, mode='rb') as f:
            text = f.read().decode('utf-8')
            all_data.extend(text.split('\n'))
  • aber wenn ich nach dem zeilenweisen Lesen eine JSON-Parsing-Logik hinzufüge, wird dieser Fehler gemeldet
with open(current_file, mode='rb') as f:
            text = f.read().decode('utf-8')
            all_data.extend(text.split('\n'))

        json_data = []
        for line in all_data:
            try:
                json_data.append(json.loads(line))
            except:
                break
return json_data

Daher bezweifle ich, dass es sich um mein Codeproblem handelt. Ich versuche auch, kein JSON-Parsing zu verwenden, sondern direkt die Zeichenfolge aufzuteilen, dasselbe Problem. Es scheint, solange ich eine zeitaufwendige Logik für die Datenverarbeitung im Datenlader habe, tritt dieses Problem auf

Auch bezüglich

Multiprozess-Training, jeder Prozess hat seinen eigenen DataLoader und somit DataLoader-Arbeiter Nichts wird von Prozessen gemeinsam genutzt, es sei denn, dies wird ausdrücklich getan.

Mal sehen, dass ich 4 Prozesse für das Training habe, jeder mit einem 8-Worker-Datenlader, also insgesamt 32 Prozesse darunter?

@zhangruiskyline Ohne ein eigenständiges Skript zum Reproduzieren des Problems können wir Ihnen nicht helfen. Ja, es wird 32 Prozesse geben

Danke, ich habe auch ein ähnliches Problem gesehen in
https://github.com/pytorch/pytorch/issues/4969
https://github.com/pytorch/pytorch/issues/5040

beide geschlossen, aber ich sehe keine klare Lösung oder Lösung, ist dies immer noch ein weit verbreitetes Problem?

Ich werde sehen, ob ich ein eigenständiges Reproduktionsskript bereitstellen kann, aber es ist stark in unsere Plattform und Datenquelle integriert, also werde ich es versuchen

@zhangruiskyline Ihr Problem ähnelt keinem der verlinkten Probleme, wenn Sie sie lesen. sie sind geschlossen, weil das ursprüngliche / häufigste Problem, das in diesen Threads gemeldet wurde, bereits behoben wurde.

Danke @SsnL , ich bin mit Pytorch nicht so vertraut, also könnte ich mich irren, aber ich habe all diese durchgesehen und es sieht so aus, als ob einige von ihnen gelöst wurden

  • Anzahl der Arbeiter auf 0 reduzieren, dies ist für uns inakzeptabel, da es zu langsam ist,

  • Erhöhen Sie die SHM-Größe, aber ich glaube, wir haben genug SHM, und das Problem trat fast unmittelbar nach dem Start auf, und ich habe es mit einem viel kleineren Datensatz versucht

  • Einige Libs wie opencv funktionieren in Multi-Prozessen nicht gut, wir verwenden nur JSON/CSV, also nicht wirklich schickes Zeug

Unser Code ist ziemlich einfach, der Trainingsdatensatz enthält über 10000 Dateien, jede Datei besteht aus mehreren Zeilen JSON-Strings. Im Dataloader definieren wir __get_item__ , um jede Datei aus über 10.000 Dateien herauszuholen und den gesamten Inhalt dieser Datei zu lesen.

In Lösung 1 lesen und teilen wir zuerst Zeilen für Zeile in die JSON-String-Liste, wenn wir sofort zurückkehren, funktioniert es, die Leistung ist gut

        with open(current_file, mode='rb') as f:
            text = f.read().decode('utf-8')
            all_data.extend(text.split('\n'))
            return all_data

Da der zurückgegebene Wert immer noch ein JSON-String ist, möchten wir den Multi-Prozess-Datenlader zur Beschleunigung nutzen, also setzen Sie die JSON-Parsing-Logik hier und es schlägt fehl

with open(current_file, mode='rb') as f:
            text = f.read().decode('utf-8')
            all_data.extend(text.split('\n'))

        json_data = []
        for line in all_data:
            try:
                json_data.append(json.loads(line))
            except:
                break
return json_data

Wir dachten später, dass das JSON-Parsing zu umfangreich ist und auch JSON zu viel Speicherbedarf hat, dann entscheiden wir uns, den JSON-String zu parsen und manuell in die Feature-Liste zu konvertieren, der gleiche Fehler. habe eine Stack-Trace-Analyse gemacht und nichts da

Übrigens, wir führen unseren Code in Linux Docker Env, 24 Kernen CPU und 1 V100 aus.

Ich bin mir nicht sicher, wo ich als nächstes mit der Recherche beginnen soll. hast du irgendeine Idee?

Hallo,

Ich habe einen interessanten Kommentar in https://github.com/open-mmlab/mmcv gefunden , der in https://github.com/open-mmlab/mmdetection verwendet wird :

Der folgende Code wird zu Beginn der Zugepoche und der Val-Epoche verwendet.
time.sleep(2) # Verhindere einen möglichen Deadlock während des Epochenübergangs

https://github.com/open-mmlab/mmcv/blob/1cb3e36a1ea33caf272d2365c7d406123122b8d0/mmcv/runner/epoch_based_runner.py#L26

Vielleicht kannst du es versuchen.

Übrigens, wenn ich zu Multi-Prozess und jedem Prozess mit Multi-Worker-Dataloader gehe, wie kann ein anderer Prozess sicherstellen, dass der entsprechende Dataloader nicht dieselben Daten wie der Dataloader eines anderen Prozesses liest? wird ti bereits vom pytorch dataloader __get_item__ ?

Hallo @SsnL , Danke für deine Hilfe. Ich möchte diesem Thread nur ein wenig nachgehen, ich refaktoriere den Trainingscode mit Pytorch Multi Processing, um die Datenverarbeitung auf der CPU-Seite zu beschleunigen (um schneller an die GPU zu füttern), https://pytorch.org/docs/stable /notes/multiprocessing.html#multiprocessing -Best Practices

In jeder Verarbeitungsfunktion verwende ich auch Multi-Worker Data Loader, um die Verarbeitungszeit für das Laden von Daten zu beschleunigen. https://pytorch.org/docs/stable/data.html

Ich habe mein wuchtiges CPU-JSON-Parsing nicht in den Dataloader, sondern in den Haupttrainingsprozess gesteckt, und das Problem scheint verschwunden zu sein, ich weiß nicht warum, aber es scheint trotzdem zu funktionieren. aber habe eine Folgefrage: Angenommen, ich habe N Verarbeitung, jeder hat M Dataloader-Worker, also insgesamt NxM unter Threading dort.

Wenn ich in meinem Dataloader alle Daten in Indexform abrufen möchte, was bedeutet, dass __get_item__(self, idx) in M Dataloader in N verschiedene Verarbeitungen zusammenarbeiten können, um verschiedene Indizes zu verarbeiten, wie kann ich sicherstellen, dass sie keine Duplikate verarbeiten oder vermissen prozess einige?

Ich hatte das gleiche Problem, bei dem der Dataloader abstürzt, nachdem ich mich beschwert hatte, dass er zu Beginn einer neuen Trainings- oder Validierungsepoche keinen Speicher zuweisen konnte. Die obigen Lösungen haben bei mir nicht funktioniert (i) mein /dev/shm ist 32 GB und es wurde nie mehr als 2,5 GB verwendet, und (ii) das Setzen von pin_memory=False hat nicht funktioniert.

Hat das vielleicht etwas mit der Müllabfuhr zu tun? Mein Code sieht ungefähr wie folgt aus. Ich brauche einen unendlichen Iterator und daher versuche ich es / außer um die next() unten :-)

def train():
    train_iter = train_loader.__iter__()
    for i in xrange(max_batches):
        try:
            x, y = next(train_iter)
        except StopIteration:
            train_iter = train_loader.__iter__()
        ...
    del train_iter

train_loader ist ein DataLoader Objekt. Ohne die explizite del train_iter Zeile am Ende der Funktion stürzt der Prozess immer nach 2-3 Epochen ab ( /dev/shm zeigt immer noch 2,5 GB an). Hoffe das hilft!

Ich verwende 4 Arbeiter (Version 0.1.12_2 mit CUDA 8.0 auf Ubuntu 16.04).

Dies löste das Problem für mich nach wochenlangen Kämpfen. Ich muss explizit den Loader-Iterator verwenden, anstatt den Loader direkt zu loopen und mit dem del loader_iterator am Ende der Epoche endlich die Deadlocks zu entfernen

Ich glaube, ich stoße auf das gleiche Problem. Versuch, 8 Datenlader zu verwenden (MNIST, MNISTM, SVHN, USPS, jeweils zum Trainieren und Testen). Die Verwendung von 6 (beliebige 6) funktioniert gut. Immer 8 Blöcke verwenden, wenn der 6. MNIST-M-Test geladen wird. Es steckt in einer endlosen Schleife fest, in der versucht wird, das Bild abzurufen, fehlschlägt, ein wenig wartet und es dann erneut versucht. Der Fehler bleibt für jede batch_size bestehen, ich habe noch viel freien Speicher und er verschwindet nur, wenn ich num_workers auf 0 setze. Jede andere Menge verursacht das Problem

Ich habe einen Hinweis von https://stackoverflow.com/questions/54013846/pytorch-dataloader-stucked-if-using-opencv-resize-method
Wenn ich cv2.setNumThreads(0) , funktioniert es bei mir einwandfrei.

Hallo, ich hatte das gleiche Problem. Und es hatte mit ulimit -n zu tun, einfach erhöhen und das Problem ist gelöst, ich habe ulimit -n 500000 verwendet

@SebastienEske ulimit -n hat dies auch für mich unter Ubuntu

Vielleicht ist set ulimit -n ein richtiger Weg, Mit der Zunahme des Modells wird der Deadlock immer häufiger, ich cv2.setNumThreads(0) , aber es funktioniert nicht.

Fürs Protokoll, cv2.setNumThreads(0) hat bei mir funktioniert.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen

Verwandte Themen

bartolsthoorn picture bartolsthoorn  ·  3Kommentare

SeparateReality picture SeparateReality  ·  3Kommentare

kdexd picture kdexd  ·  3Kommentare

a1363901216 picture a1363901216  ·  3Kommentare

NgPDat picture NgPDat  ·  3Kommentare