Theano: сбой cublasSgemm (14) сбой внутренней операции

Иногда, через некоторое время нормального запуска, я получаю такую ​​ошибку с Theano/CUDA:

RuntimeError: cublasSgemm failed (14) an internal operation failed
 unit=0 N=0, c.dims=[512 2048], a.dim=[512 493], alpha=%f, beta=%f, a=%p, b=%p, c=%p sa_0=%d, sa_1=%d, sb_0=%d, sb_1=%d, sc_0=%d, sc_1=%d
Apply node that caused the error: GpuDot22(GpuReshape{2}.0, GpuReshape{2}.0)
Inputs types: [CudaNdarrayType(float32, matrix), CudaNdarrayType(float32, matrix)]
Inputs shapes: [(512, 493), (493, 2048)]
Inputs strides: [(493, 1), (2048, 1)]
Inputs values: ['not shown', 'not shown']

Поскольку мой код некоторое время работает нормально (я занимаюсь обучением нейронной сети, и он работает большую часть времени, и даже когда эта ошибка возникает, он уже работает нормально для> 2000 мини-пакетов), я задаюсь вопросом о причине этого . Может какая-то аппаратная неисправность?

Это с CUDA 6.0 и совсем недавним Theano (вчера из Git), Ubuntu 12.04, GTX 580.

Я также получил ошибку с CUDA 6.5 на K20:

RuntimeError: cublasSgemm failed (14) an internal operation failed
 unit=0 N=0, c.dims=[2899 2000], a.dim=[2899 493], alpha=%f, beta=%f, a=%p, b=%p, c=%p sa_0=%d, sa_1=%d, sb_0=%d, sb_1=%d, sc_0=%d, sc_1=%d
Apply node that caused the error: GpuDot22(GpuReshape{2}.0, GpuReshape{2}.0)
Inputs types: [CudaNdarrayType(float32, matrix), CudaNdarrayType(float32, matrix)]
Inputs shapes: [(2899, 493), (493, 2000)]
Inputs strides: [(493, 1), (2000, 1)]
Inputs values: ['not shown', 'not shown']

(Другая ошибка, которую я иногда получал в прошлом, - это это теперь вместо этого. Не уверен, что это связано.)

Через Markus, который получил ту же ошибку:

RuntimeError: cublasSgemm failed (14) an internal operation failed
 unit=0 N=0, c.dims=[2 100], a.dim=[2 9919], alpha=%f, beta=%f, a=%p, b=%p, c=%p sa_0=%d, sa_1=%d, sb_0=%d, sb_1=%d, sc_0=%d, sc_1=%d
Apply node that caused the error: GpuDot22(GpuFlatten{2}.0, weight_hidden_)
Inputs types: [CudaNdarrayType(float32, matrix), CudaNdarrayType(float32, matrix)]
Inputs shapes: [(2, 9919), (9919, 100)]
Inputs strides: [(9919, 1), (100, 1)]
Inputs values: ['not shown', 'not shown']

С CUDA 6.5, Windows 8.1, Python 2.7, GTX 970M.

Ошибка возникает только в моей собственной сети, если я запускаю пример LeNet из Theano, он работает нормально. Хотя сеть компилируется и работает нормально на процессоре (а также на графическом процессоре у некоторых коллег, использующих Linux). Кто-нибудь знает, в чем может быть проблема?


person Albert    schedule 28.01.2015    source источник
comment
Какая ОС? Какой графический процессор? Ваш графический процессор также используется в качестве устройства отображения?   -  person Michal Hosala    schedule 28.01.2015
comment
@MichalHosala: Ubuntu 12.04, кажется, GTX 580 (не уверен — я уже удалил журнал). Он используется исключительно этим процессом.   -  person Albert    schedule 28.01.2015
comment
Я достаточно уверен, что код ошибки обычно указывает на то, что время ожидания ядра внутри вызова истекло. Поскольку время выполнения SGEMM примерно пропорционально произведению размерностей nmk, ваши матрицы могут оказаться слишком большими. Но если я правильно интерпретирую ваши данные выше, матрицы кажутся не такими уж большими, а GTX 580 довольно быстра. Но, может быть, ваше приложение под капотом создает большие промежуточные матрицы? Я бы предложил изучить время работы ядра с помощью профилировщика. Кроме того, попробуйте графический процессор, который не используется для графического интерфейса, а работает только как вычислительное устройство.   -  person njuffa    schedule 28.01.2015
comment
@njuffa: В случае тайм-аута, могу ли я просто увеличить тайм-аут или полностью отключить его? (Зачем он там вообще?) А GPU я и так использую исключительно для вычислений.   -  person Albert    schedule 28.01.2015
comment
@Albert: GPU может либо запускать вычислительное ядро, либо обслуживать графический интерфейс операционной системы. Все операционные системы, поддерживаемые CUDA, имеют сторожевой таймер, предотвращающий зависание графического интерфейса пользователя на неопределенное время и уничтожающий ядро ​​CUDA, которое превышает лимит времени (обычно пару секунд). Я думаю, что в Windows все графические процессоры, работающие под управлением WDDM, подлежат сторожевому таймеру, в Linux это происходит, если вы запускаете X на графическом процессоре. Да, вы можете изменить лимит времени ожидания, это зависит от ОС, и у меня нет под рукой подробностей. На данный момент тайм-аут — это всего лишь рабочая гипотеза.   -  person njuffa    schedule 28.01.2015
comment
@njuffa: на графическом процессоре не работает X-сервер. Это в эксклюзивном режиме, и только мой процесс использует его.   -  person Albert    schedule 28.01.2015
comment
@Albert: В настоящее время у меня нет других гипотез, вы можете попробовать запустить отладчик, чтобы выяснить, что происходит под капотом в Theano. Проблема может возникнуть в восходящем направлении вызова SGEMM.   -  person njuffa    schedule 28.01.2015


Ответы (2)


Просто для справки, если кто-то наткнется на это:

Это больше не происходит для меня. Я не совсем уверен, что это исправило, но я думаю, что главное отличие в том, что я избегаю многопоточности и форков (без exec). Это вызвало много подобных проблем, например. Ошибка Theano CUDA: обнаружен незаконный доступ к памяти (StackOverflow) и ошибка Theano CUDA: обнаружен незаконный доступ к памяти ( обсуждение в группах Google). особ. что обсуждение в группах Google очень полезно.

Функции Theano не являются безопасными для многопоточности. Однако для меня это не проблема, потому что я использую его только в одном потоке. Тем не менее, я все еще думаю, что другие потоки могут вызвать эти проблемы. Возможно, это связано с GC Python, который освобождает часть Cuda_Ndarray в каком-то другом потоке, пока работает theano.function.

Я немного просмотрел соответствующий код Theano И не уверен, что это охватывает все такие случаи.

Обратите внимание, что вы можете даже не знать, что у вас есть фоновые потоки. Некоторый код Python stdlib может порождать такие фоновые потоки. Например. multiprocessing.Queue сделает это.

Я не могу избежать нескольких потоков, и пока это не будет исправлено в Theano, я создаю новый подпроцесс с одним потоком, в котором выполняю всю работу Theano. Это также имеет несколько преимуществ, таких как: более четкое разделение кода, в некоторых случаях более быстрое выполнение, потому что все действительно выполняется параллельно, и возможность использования нескольких графических процессоров.

Обратите внимание, что простое использование многопроцессорного модуля не сработало для меня, потому что есть несколько библиотек (Numpy и другие, и, возможно, сама Theano), которые могут плохо себя вести в разветвленном процессе (в зависимости от версии, ОС и условий гонки). . Таким образом, мне нужен был настоящий подпроцесс (fork + exec, а не просто fork).

Мой код здесь, если кому-то это интересно.

Существует ExecingProcess, который смоделирован по образцу multiprocessing.Process, но выполняет fork+exec. (Кстати, в Windows модуль многопроцессорности все равно сделает это, потому что в Windows нет форка.) И есть AsyncTask, который добавляет к этому дуплексный канал, который работает как с ExecingProcess, так и со стандартным multiprocessing.Process.

См. также: Theano Wiki: Использование нескольких GPU

person Albert    schedule 01.07.2015

Столкнулся с похожей проблемой, и в моем случае она была решена путем устранения импорта другой библиотеки, которая использовала pycuda. Похоже, theano действительно не любит делиться.

person Av Shrikumar    schedule 19.01.2016