配置环境填坑小记
Posted on January 21, 2019
计算机科学除了有丰富的理论内涵,也是一门锻炼工程能力的实践科学,填坑力 就成为了解决问题的能力中一个重要的方面。 类似医院里的实习医师、法庭内外的年轻律师、中学里的青年教师,ta们的能力同样是在不断的实践摸索中成长的。要学会投入工作, 加入自己的思考,不断填坑又爬坑逐渐掌握无可替代的经验和能力。计算机的专家也是在坐得住地debug中、不断参与比赛、解决项目中, 成长为能写出bug-free clean and elegant的代码。理论和实践,都值得投入学习取得进步。
CUDA和显卡驱动以及pytorch版本的对应关系
参考文章安装多版本CUDA时
- 历史版本 cuda https://developer.nvidia.com/cuda-toolkit-archive cudnn https://developer.nvidia.com/rdp/cudnn-archive
- 多版本 https://blog.csdn.net/Tesion_001/article/details/89737044
- 检查nvcc https://stackoverflow.com/questions/53422407/different-cuda-versions-shown-by-nvcc-and-nvidia-smi
nvcc --version和nvidia-smi显示的cuda版本不一致。务必以nvcc的为准。安装cuda时遵循指南,并且检查必要的环境要求。
Linux更改用户环境变量和所有用户环境变量
- 创建用户 https://www.cnblogs.com/sunyllove/p/9772053.html
- 修改用户环境 https://blog.csdn.net/weixin_38361347/article/details/93392842
- 具体修改CUDA环境 https://blog.csdn.net/Tesion_001/article/details/89737044
- 关于沿用root配置的环境 usermod -g root devonn
安装CUDA
去官网,会生成所需版本的安装命令,如:wget http://developer.download.nvidia.com/compute/cuda/10.1/Prod/local_installers/cuda_10.1.243_418.87.00_linux.run
sudo sh cuda_10.1.243_418.87.00_linux.run
附2:看看别人的填坑记 https://blog.csdn.net/QLULIBIN/article/details/78714596
注1:配置环境一般考虑较新的稳定版,而不是追求最新。版本还可以再更新,而不要现在去冒着driver、toolkit、platform兼容上的风险。
安装版本检查
pip安装一般会自动检查,只可以安装和系统适配的whl(Wheel,是Python软件包的一种二进制分发格式)。 但希望pip install xx.whl时,一般可以根据名称检查是否适配。下载合适的whl文件。python -m pip debug --verbose可以检查环境版本。
xxx-cp310-cp310-manylinux_2_28_x86_64.whl名称指示了适配的环境版本。
python3 -m site 可查看默认的安装目录
apt或pip install遇到网络问题
问题link1, link2. 可以猜测是DNS问题。可增加公共DNS服务器: cat << EOF > /etc/resolv.conf nameserver 8.8.8.8 nameserver 8.8.4.4 EOF
TensorFlow安装
通常和CUDA版本安装一起考虑。
- tensorflow for windows
https://www.cnblogs.com/xianhan/p/9084815.html
https://www.cnblogs.com/guoyaohua/p/9265268.html
https://blog.csdn.net/gyp2448565528/article/details/79451212
PyTorch奇怪的报错
RuntimeError: cuDNN error: CUDNN_STATUS_NOT_SUPPORTED. This error may appear if you passed in a non-contiguous input.- 原因:版本不匹配
- 解决方法: 使用torch.backends.cudnn.enabled = False
anaconda
nvidia断电驱动崩溃
- 驱动卸载重装 https://blog.csdn.net/Netooo/article/details/84888755
- 记得chmod赋予run文件执行的权限
关于调试
- |tee log.txt 可以将终端内容输出记录到文本
- Compare IDE中 Select for Compare & Compare with Selected
关于GCC (redhat系)
- 有许多模型算子,对部署的GCC版本有要求。比如某些DCNv2,需要gcc 5以上
# 使用scl软解集 yum install centos-release-scl scl-utils -y yum install devtoolset-4-gcc.x86_64 devtoolset-4-gcc-c++.x86_64 devtoolset-4-gcc-gdb-plugin.x86_64 -y scl enable devtoolset-4 bash
关于并发读取权重
有些比较huge的权重(数百兆~吉),并发torch.load是可能出问题的。 但是目前我也没想到最佳方案,下面的方案能有所缓解: try solution 1: with tempfile.NamedTemporaryFile(delete=True) as temp_file: temp_model_path = temp_file.name shutil.copy(model_path, temp_model_path) statedict = torch.load(temp_model_path, map_location=args_device) model.load_state_dict(statedict) try solution 2: from filelock import FileLock lock_path = model_path + ".lock" with FileLock(lock_path): statedict = torch.load(model_path, map_location=args_device) model.load_state_dict(statedict) try solution 3: 甚至自己手写文件锁,主要利用os.path.exists(lockpath)来判断。也没有用。 总之这个并发问题还比较棘手。或许大模型的应用还是一开始加载到内存,要稳定一点。
关于OpenCV
- PIP3依赖有:opencv-python-headless, opencv-python, opencv-contrib-python
- 这三者在完整性上是递增的,常用的opencv-python,如果你的环境报错缺少libSM,这是图形界面的库, 如果你的环境不需要,可以把opencv-python的依赖改成opencv-python-headless。如果要用一些有专利 收费的算法,则使用opencv-contrib-python.
- Of course there is opencv-contrib-python-headless
python中安装OpenCV提供四种依赖包 1,如果只需要主要模块 pip install opencv-python 2,如果需要更全的模块 pip install opencv-contrib-python 3,如果资源较少,不需要任何GUI功能 pip install opencv-python-headless 4,如果资源较少,不需要任何GUI功能,包含contrib模块 pip install opencv-contrib-python-headless
有些仓库,比如MMCV需要opencv-python,可以采取如下方式: ''' export DEBIAN_FRONTEND=noninteractive apt-get -y install tzdata apt-get update apt-get install ffmpeg libsm6 libxext6 -y pip3 install opencv-python ''' 再就是opencv如果不是在ffmpeg之后构建的,可能会有视频数据I/O方面的问题。 ''' apt update apt install -y ffmpeg pip uninstall -y opencv pip install opencv-python-headless (or apt install -y python3-opencv) ''' 最后可以打印python3 -c "import cv2; print(cv2.getBuildInformation())"|grep FFMPEG看是不是yes
nvidia-smi显存被占用,却没显示进程
- 使用fuser命令 fuser用于显示哪些进程正在使用给定的文件、文件系统或unix套接字
- sudo fuser -v /dev/nvidia* 记住最好加sudo,因为有些进程是只有系统管理员可见的。 查看占用指定显卡的进程id之后,kill掉就好了。
- kill -9 PID
远程终端标准输出的恢复
如果使用tmux、screen、supervisor,它们有进程托管的功能可以很好的恢复。但关闭普通的远程终端,如何恢复标准输出呢?Terminal (/dev/ttyX or /dev/pts/x) device | (screen)<--[And there is no way to plug some new Process3 like this:
Terminal device | (screen)<---o---[What screen (and others) does is allocating some pseudo terminal device (like xterm does) and redirect it to one or more "real" terminals (physical, virtual, or emulated):
Terminal pseudo devices ,--> Terminal (/dev/pts/x) | _______/ device Terminal <--[Using screen -x you can attach one more terminal, xterm, whatever (say Terminal 3) to the screen session.
So no, you can't communicate directly through stdin/stdout with processes attached to a different terminal. You can only do so through the process that is controlling this terminal if it happens to be a pseudo terminal, and if this process was concieved to do so (like screen is). https://unix.stackexchange.com/questions/17838/how-can-i-switch-between-ttys-without-using-screen
The simple answer is that if you want to reconnect to a terminal from a different place, use screen or tmux.
磁盘推出
- 磁盘没有被推出,因为一个或多个程序可能正在使用它。
df -lh 查看硬盘编号,如/dev/disk2s1 lsof /Volumes/Seagate/ 打开活动监视器 Activity Monitor,找到 QuickLook,强制退出 如果 lsof /Volumes/Seagate/ 没有输出的话,加上 sudo 再执行 sudo lsof /Volumes/Seagate/, 估计会发现是 mds 和 mds_store 在后台搞鬼, 这两个是 SpotLight 的进程,强退之!
跳板机掉线
- 检查机器是否设置永不休眠
Mac os 在设置关闭显示器不休眠中有两个状态分别为“电池”与“电源适配器” Step1:系统编好设置 — 节能——电池,勾选“当显示器关闭时,防止电脑自动进入睡眠”,取消“如果可能,使硬盘自动进入睡眠”。 Step1:系统编好设置 — 节能——电源适配器,勾选“当显示器关闭时,防止电脑自动进入睡眠”,取消“如果可能,使硬盘自动进入睡眠”。
Shell下不能使用Tab补全命令
-
这是因为/etc/passwd中该用户的默认shell不是/bin/bash
- 修改方式 1. chsh命令
- 修改方式 2. sudo vim /etc/passwd /home/hdw:/bin/bash
- 修改方式 3. usermod - s /bin/bash 用户名 -s 修改用户登入后所使用的shell。
服务器禁止内核自动更新
内核默认会自动更新,更新到某些版本可能和显卡驱动不适配。 所以最好是禁止自动更新: https://blog.csdn.net/weixin_43064339/article/details/88370372 如果已经发生内核变动、更新,显卡显示不出来,可以稍微补救下: https://www.jianshu.com/p/3cedce05a481 如果是没死机的情况显卡出现问题,nvidia也提供了自检命令: https://blog.csdn.net/u012759006/article/details/103629003 不过这个还没正式用过,不晓得有帮助不 宕机查看下 /var/log/kern.log 也可以看看last -F 宕机当天的用户登录情况
编程程序CPU过高
内存不足、忙等待、并发、... 其它原因:程序本身在循环执行CPU密集型的操作,瞬时CPU占用会极高。假设此操作耗时很短,很快会释放CPU,但如果程序没有任何间隔,紧接着循环进行该操作,CPU将持续处于高负载状态,这不仅会导致CPU温度升高,还可能影响其他进程的性能。
Linux crontab 定期执行程序
crontab [ -u user ] { -l | -r | -e } -e : 执行文字编辑器来设定时程表 -r : 删除目前的时程表 -l : 列出目前的时程表 注:定时执行top命令需要 -b http://blog.itpub.net/25311408/viewspace-686412
Chrome连接问题
Chrome您的连接不是私密连接 解决:就是在当前页面用键盘输入 thisisunsafe ,不是在地址栏输入,就直接敲键盘就行了,页面即会自动刷新进入网页。 thisisunsafe 这个命令,说明你已经了解并确认这是个不安全的网站,你仍要访问就给你访问了。
根据安全要求升级软件包
sudo apt update apt list --upgradable sudo apt-get install --only-upgrade package1 package2 ... 或 sudo apt upgrade package1 package2 ...
man apt查看手册
apt-get 是在基于 Debain 的机器(如Ubuntu)中进行包/应用程序管理的命令。 更新和升级选项之间存在细微差别。 ・sudo apt-get update # 获取最新资源包 是更新源列表的命令,如果您修改源列表或者想要进行同步刷新或添加新的ppa源,那么您应该执行上面的命令。 ・sudo apt-get upgrade # 更新本机已安装的软件包 命令将尝试下载在apt服务器上具有更新的所有软件包,然后尝试按下“y”时安装它们。这就像系统升级到新包。 ・sudo apt-get dist-upgrade # 本机系统软件更新 dist-upgrade命令也算更新所有软件包,但是当 upgrade 更新时,如果依赖关系无法解决时可能会报错或者停止,但是 dist-upgrade 命令可以自动解决依赖关系 但是 dist-update 有一定的危险性,因为可能会更新很大您不希望更新的软件,导致原理的一些需要依赖旧包的软件无法运行。 所以,使用 apt-get dist-upgrade 时,请慎重使用,一般是 apt-get update && apt-get upgrade 可以保证系统的完整性。
apt-get是某些linux发行版使用的一个“包管理器”(还有别的发行版使用yum等,以及brew等其他平台上的包管理器,工作原理类似)。 包管理器的作用是从 源(Source)服务器那里下载最新的软件包列表 (PS:软件源服务器地址可以在/etc/apt/sources.list里面看到。),然后在你需要安装某个软件包(apt-get install)的时候从列表里面查询这个软件包的版本信息、系统要求、翻译、依赖项(该软件正常运行必须安装的其它软件)并且添加到同时安装的列表里面,再查询所有安装列表里面的软件包的.deb文件下载地址,最后批量下载,自动分析安装顺序然后安装完成。 但是这个软件包列表是不会被自动下载的,需要用户使用apt-get update更新。这样,apt-get才能知道每个软件包的最新信息,从而正确地下载最新版本的软件。 至于apt-get upgrade,则是对已经安装的软件包本身进行更新的过程。由于确定要更新的软件包需要对本地安装的版本和列表的版本进行比较,所以要在update以后运行这一条。 apt-get dist-upgrade会识别出当依赖关系改变的情形并作出处理(所以通常这个会被认为是有点风险的升级),而apt-get upgrade对此情形不处理。 例如软件包 a 原先依赖 b c d,但是在源里面可能已经升级了,现在是 a 依赖 b c e。这种情况下,dist-upgrade 会删除 d 安装 e,并把 a 软件包升级,而 upgrade 会认为依赖关系改变而拒绝升级 a 软件包。
请改用 apt 命令 apt-get 是一个传统的低级命令,可以做很多事情。它适合由其他工具或系统管理员在脚本中使用。 apt 命令是一个简化版本,面向普通的临时用户。它比 apt-get 做得更好、更简单。 apt 命令被设计为对用户更加友好的 apt-get 替代方案,来自AWS建议
安装nvidia显卡驱动
方式1:官网下载run包,然后运行即可。 会询问 是否安装32位兼容库;是否安装NVIDIA 3D媒体库;是否更新X配置;是否要安装DKMS。 方式2:可以依次执行sudo apt-get update, sudo apt-get upgrade, sudo ubuntu-drivers autoinstall 自动安装驱动。 但英伟达驱动有bug,会导致机器能进入自动休眠,可以查看/var/log/syslog | grep sleep了解。 以下操作关闭自动休眠: sudo systemctl stop nvidia-suspend.service nvidia-hibernate.service nvidia-resume.services sudo systemctl mask nvidia-suspend.service nvidia-hibernate.service nvidia-resume.service sudo rm /lib/systemd/system-sleep/nvidia sudo systemctl stop sleep.target suspend.target hibernate.target hybrid-sleep.target sudo systemctl mask sleep.target suspend.target hibernate.target hybrid-sleep.target
关于显卡的温度监控
指定显卡重启: nvidia-smi --gpu-reset -i 0 如果没能正常重启,有可能是烧坏了。 nvidia-smi窗口直接就有显示温度,下面的命令进行温度持续监控。 nvidia-smi --query-gpu=temperature.gpu -i 7 --format=csv >> xxx.log
关于youtube视频下载器
做CV,经常会到youtube收集数据集。有时会有一些downloader的库找不到视频,其实是被禁了。这时不用被block,果断换一个库尝试。 而且几个库可以换着尝试,它们都在不断维护、更新,上一次落伍的库可能下一次更新在前面了。比如: https://github.com/AliaksandrSiarohin/video-preprocessing的issue:
def download(video_id, args): video_path = os.path.join(args.video_folder, video_id + ".mp4") subprocess.call([args.youtube, '-f', "''best/mp4''", '--write-auto-sub', '--write-sub', '--sub-lang', 'en', '--skip-unavailable-fragments', "https://www.youtube.com/watch?v=" + video_id, "--output", video_path], stdout=DEVNULL, stderr=DEVNULL) return video_path替换为(youtube-dl替换为yt-dlp或pytube)
def download(ytb_id, args, proxy=None): """ ytb_id: youtube_id save_folder: save video folder proxy: proxy url, defalut None """ video_path = os.path.join(args.video_folder, ytb_id + ".mp4") if proxy is not None: proxy_cmd = "--proxy {}".format(proxy) else: proxy_cmd = "" if not os.path.exists(video_path): down_video = " ".join([ "yt-dlp", proxy_cmd, '-f', "'bestvideo[ext=mp4]+bestaudio[ext=m4a]/bestvideo+bestaudio'", '--skip-unavailable-fragments', '--merge-output-format', 'mp4', "https://www.youtube.com/watch?v=" + ytb_id, "--output", video_path, "--external-downloader", "aria2c", "--external-downloader-args", '"-x 16 -k 1M"' ]) print(down_video) status = os.system(down_video) if status != 0: print(f"video not found: {ytb_id}") return video_path
yt-dlp参数: yt-dlp -f [下载ID] [代理配置] [视频链接] [合并语句] [外部下载器选择] [下载器参数] -f [id] #选择下载内容,注意和 -F 区分。例子中使用137+140,如果你只下载720p则填写22就好,后面的合并语句可不填写。 --proxy #代理配置 见前文 --merge-output-format [合并输出格式] #例子中选择mp4作为输出格式 --external-downloader [下载器名称] #下载器选择 例子中选择aria2c --downloader-args [下载器名称]:"[下载器配置]" #下载器配置语句 例子中 x 16 代表16线程下载 -k 1M 代表块大小为1M 但youtube不支持分块故此句可忽略