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.01libnvcuvid.so.455.45.01复制到容器/usr/lib64下。
库文件可以find一下。
另外,可选项是同时相应建立软连接,.so.1的软连接主要是ffmpeg命令使用。

3.3 使用补丁包

Github原教程章节链接

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路径下,那么添加这个路径。

然后其他照常执行即可。

原文地址:https://www.cnblogs.com/geoffreyone/p/14715487.html