Docker取消Video Encoding Sessions并发数目限制(OpenEncodeSessionEx failed: out of memory)
1. 问题说明
问题是在多路视频使用GPU转码时出现的,问题复现是有条件的,相同的命令只有在session只要不超过改GPU限定数量才会触发异常。报错的内容是 OpenEncodeSessionEx failed: out of memory (10): (no details)
, 但是明显还有可用的显存,所以纠结了好几天才定位到问题。
原因是NVENC并发的Session数目超过了限制
,具体信息可以去官网查一下。我的2080Ti最大数是3.
Video Encode and Decode GPU Support Matrix
这里感谢大佬 突破NVIDIA NVENC并发Session数目限, 对问题原因讲述的很清楚。
2. 解决方案
由于动手能力有限,这里直接使用了开源的驱动补丁NVENC and NvFBC patches for Nvidia drivers, 移除了NVENC video encoding sessions的最大数量。
3. 解决步骤
3.1 在宿主机安装驱动
这一步不是重点,看本篇的相信已经完成,不做赘述。
大体步骤如下:
mkdir /opt/nvidia && cd /opt/nvidia
wget https://international.download.nvidia.com/XFree86/Linux-x86_64/430.50/NVIDIA-Linux-x86_64-430.50.run
chmod +x ./NVIDIA-Linux-x86_64-430.50.run
./NVIDIA-Linux-x86_64-430.50.run
3.2 将宿主机关键库文件拷贝到容器
库文件的版本根据宿主机安装的驱动版本决定,我这里是455.45.01. 需要把宿主机的libnvidia-encode.so.455.45.01
和libnvcuvid.so.455.45.01
复制到容器/usr/lib64
下。
库文件可以find一下。
另外,可选项是同时相应建立软连接,.so.1
的软连接主要是ffmpeg命令使用。
3.3 使用补丁包
a. 已有容器
如果容器已经启动,可以进行如下操作
git clone https://github.com/keylase/nvidia-patch.git
到容器任意位置,执行
chmod +x /usr/local/bin/patch.sh
bash docker-entrypoint.sh
b. Dockfile
如果想从头构建容器,项目已经提供了打补丁的方法,直接复制即可。
FROM nvidia/cuda:latest
ENV NVIDIA_VISIBLE_DEVICES all
ENV NVIDIA_DRIVER_CAPABILITIES compute,video,utility
RUN mkdir -p /usr/local/bin /patched-lib
COPY patch.sh docker-entrypoint.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/patch.sh /usr/local/bin/docker-entrypoint.sh
ENTRYPOINT ["/usr/local/bin/docker-entrypoint.sh"]
3.4 注意点
如果提示找不到驱动文件路径ERROR: cannot detect driver directory
, 是因为该项目预设了一些库文件的可能路径,如:'/usr/lib/x86_64-linux-gnu'
、/usr/lib/x86_64-linux-gnu/nvidia/current/
、/usr/lib64
、等,这也是上面建议拷贝到/usr/lib64
的原因。
如果库文件拷贝到容器中的路径不在这个列表,也可以手动添,如图我的是存放在容器的/lib64路径下,那么添加这个路径。
然后其他照常执行即可。