らんだむな記憶

blogというものを体験してみようか!的なー

YOLOv3 とか darknet

Yolo, Darknetを用いたリアルタイム物体検出(QuickStart用リポジトリ作成) - Qiita
そのままでは動かないのか・・・。ということで参考になりそう・・・。

そして darknet をビルドしてみようとしたら yolo with cudnn · Issue #2257 · pjreddie/darknet · GitHub の問題に遭遇してしまった・・・。CUDA 10.2 の環境でいけたやつもあるのだが、今回 CUDA 11.0 で引っかかった・・・。(最後のコメントに CUDA 11.3 でも問題が出ていると書いてあるのが気になる・・・)

cd /usr/local/cuda
find . -name "*.h" | xargs grep -n CUDNN_CONVOLUTION_FWD_
./targets/x86_64-linux/include/cudnn_ops_infer.h:1015:    CUDNN_CONVOLUTION_FWD_ALGO_IMPLICIT_GEMM         = 0,
./targets/x86_64-linux/include/cudnn_ops_infer.h:1016:    CUDNN_CONVOLUTION_FWD_ALGO_IMPLICIT_PRECOMP_GEMM = 1,
./targets/x86_64-linux/include/cudnn_ops_infer.h:1017:    CUDNN_CONVOLUTION_FWD_ALGO_GEMM                  = 2,
./targets/x86_64-linux/include/cudnn_ops_infer.h:1018:    CUDNN_CONVOLUTION_FWD_ALGO_DIRECT                = 3,
./targets/x86_64-linux/include/cudnn_ops_infer.h:1019:    CUDNN_CONVOLUTION_FWD_ALGO_FFT                   = 4,
./targets/x86_64-linux/include/cudnn_ops_infer.h:1020:    CUDNN_CONVOLUTION_FWD_ALGO_FFT_TILING            = 5,
./targets/x86_64-linux/include/cudnn_ops_infer.h:1021:    CUDNN_CONVOLUTION_FWD_ALGO_WINOGRAD              = 6,
./targets/x86_64-linux/include/cudnn_ops_infer.h:1022:    CUDNN_CONVOLUTION_FWD_ALGO_WINOGRAD_NONFUSED     = 7,
./targets/x86_64-linux/include/cudnn_ops_infer.h:1023:    CUDNN_CONVOLUTION_FWD_ALGO_COUNT                 = 8

なので、確かになさそう。Colab でも nvcc -V で確認すると V11.1.105 らしい。Colab 上で GPU 対応の darknet をビルドするのは厳しいかも・・・?

無理矢理コンパイルを通してうまく動くのかよく分からないので、CPU 向けのビルドをしてみる。こっちはコンパイルできるようだ。

*****

Colab 上でダメ元で本家のビルドを

rm -rf darknet && git clone https://github.com/pjreddie/darknet && cd darknet && perl -pi -e 's/GPU=0/GPU=1/; s/CUDNN=0/CUDNN=1/;' Makefile && cat Makefile && make

でやったら、上記とは違うエラーが出た。nvidia - Unsupported gpu architecture compute_30 on a CUDA 5 capable gpu - Stack Overflow の内容だが、CUDA 10.2 までの機能を参照しているらしい。この内容を参考に

rm -rf darknet && git clone https://github.com/pjreddie/darknet && cd darknet && perl -pi -e 's/GPU=0/GPU=1/; s/CUDNN=0/CUDNN=1/; s/# ARCH= -gencode arch=compute_52,code=compute_52/ARCH= -gencode arch=compute_50,code=compute_50/' Makefile && cat Makefile && make

をしたら Colab 上でビルドできた。

/usr/include/x86_64-linux-gnu/cudnn_v7.h

CUDNN_CONVOLUTION_FWD_SPECIFY_WORKSPACE_LIMIT = 2,

として見えているようだ。

  • CUDA 10.2, 11.1: OK
  • CUDA 11.0, 11.3: NG

という情報に見えているが、なんか変だな。cuDNN のバージョンのほうかな?現在

$ cat /usr/local/cuda/include/cudnn_version.h | grep CUDNN_MAJOR -A 2
#define CUDNN_MAJOR 8
#define CUDNN_MINOR 0
#define CUDNN_PATCHLEVEL 5
--
#define CUDNN_VERSION (CUDNN_MAJOR * 1000 + CUDNN_MINOR * 100 + CUDNN_PATCHLEVEL)

#endif /* CUDNN_VERSION_H */

なので、cuDNN 8.0.5 を使用している。

cudnnConvolutionFwdPreference_t が見えている必要がありそう?

convolutional_layer.c に強引に

typedef enum {↲
    CUDNN_CONVOLUTION_FWD_NO_WORKSPACE            = 0,
    CUDNN_CONVOLUTION_FWD_PREFER_FASTEST          = 1,
    CUDNN_CONVOLUTION_FWD_SPECIFY_WORKSPACE_LIMIT = 2,
} cudnnConvolutionFwdPreference_t;

typedef enum {
    CUDNN_CONVOLUTION_BWD_FILTER_NO_WORKSPACE            = 0,
    CUDNN_CONVOLUTION_BWD_FILTER_PREFER_FASTEST          = 1,
    CUDNN_CONVOLUTION_BWD_FILTER_SPECIFY_WORKSPACE_LIMIT = 2,
} cudnnConvolutionBwdFilterPreference_t;

typedef enum {↲
    CUDNN_CONVOLUTION_BWD_DATA_NO_WORKSPACE            = 0,
    CUDNN_CONVOLUTION_BWD_DATA_PREFER_FASTEST          = 1,
    CUDNN_CONVOLUTION_BWD_DATA_SPECIFY_WORKSPACE_LIMIT = 2,
} cudnnConvolutionBwdDataPreference_t;

を追加するとコンパイルは通る(但し undefined declaration を伴う)のだが、リンク時に

libdarknet.a(convolutional_layer.o): In function `cudnn_convolutional_setup':
convolutional_layer.c:(.text+0xe28): undefined reference to `cudnnGetConvolutionForwardAlgorithm'
convolutional_layer.c:(.text+0xe7b): undefined reference to `cudnnGetConvolutionBackwardDataAlgorithm'
convolutional_layer.c:(.text+0xeb8): undefined reference to `cudnnGetConvolutionBackwardFilterAlgorithm'

が出てしまう。どうも cuDNN 7.x を入れておかないと良くなさそうだ。cuDNN は
異なるバージョンのCUDAを使い分ける単純な方法 - Qiita によると共存できるようなので(Colab 上でも 7.x と 8.x が共存して見えた)追加で入れたら良いのかもしれない*1。実際、Installation Guide :: NVIDIA Deep Learning cuDNN Documentation にも共存するとある。(後から古いバージョンを入れる場合がやや不安だが・・・。)

Installation Guide :: NVIDIA Deep Learning cuDNN Documentation の Tar File Installation の安心感は凄い!sudo update-alternatives --config libcudnn でデフォルトの切り替えもできるようだ。

GCPでのディープラーニング学習環境構築方法 - Qiita も参考にしたい。

*1:但し、cuDNN 7.6.5 は CUDA 10.2 まで用しかないのでこれを使いたいなら CUDA 10.2 も入れないとならない・・・。