Linux深度学习环境搭建:从报错到运行的排障全路径
|
跟产品吵。去年八月,CUDA 11.8 镜像推到 staging 的那天下午三点十七分,PM 把需求文档第一页右上角“支持 TensorRT 8.6”用红笔圈了三道,说“这个必须卡在灰度开关没推完前上线”。我盯着他笔尖悬停的那滴墨,没接话——倒不是怕他,是当时 oncall 手机震了一下,震动模式,但没亮屏,只在裤兜里发烫,像块刚从烤箱里夹出来的铜片。 先扔结论后补细节。Linux 深度学习环境搭建这事儿,根本就不是技术问题,是筛人机制。优胜劣汰。不是优胜劣汰出“高手”,是劣汰掉所有还信“pip install torch==2.1.0+cu118 -f https://download.pytorch.org/whl/torch_stable.html”能跑通的人。我原以为装完 driver 就算过了第一关,结果 nvidia-smi 回显正常,torch.cuda.is_available() 返回 False,查了四小时,发现 /dev/nvidiactl 权限被 ansible 脚本里一句 copy mode=0644 硬生生覆盖成 644 了——而那个脚本三个月前就进了 prod 分支,上周才被前端调 API 时顺手 trigger 了一次,就那么巧。 测试那天,王工在隔壁工位啃凉掉的饭团,塑料包装纸窸窣响了至少七次。他边嚼边问:“你那个 NCCL_ASYNC_ERROR_HANDLING=1 加了没?”我没答,因为监控大屏上左下角那个标着“nginx_5xx_rate_1m”的曲线,正毫无征兆地抖了一下,幅度小得像打了个嗝,持续十八毫秒,然后归零。没人盯它,但我知道——那是 GPU 节点上某个没被 register 的 metric collector 进程崩了又自启,和深度学习一毛钱关系没有,但它抖的时候,我们仨都抬了下头。
文章配图,仅供参考 我说不准为什么 conda install pytorch torchvision torchaudio pytorch-cuda=11.8 -c pytorch -c nvidia 那条命令在离线环境里死活不认 cuda-toolkit 包,查 manifest 发现它依赖一个叫 “cuda-toolkit-dev” 的 meta package,而这个包在 conda-forge 的 latest channel 里已被弃用,但镜像同步脚本还在抓它;可我敢打包票:你只要把 /opt/conda/pkgs/cache 下那个 .tar.bz2 文件名末尾的 “_2” 改成 “_1”,重 hash,再 touch 一下 timestamps,conda 就会把它当新鲜货塞进 transaction,接着装——这事儿我试了三十七次,中间穿插两次 coffee break,咖啡杯上印的公司 logo 已经掉漆,露出底下泛黄的陶瓷底。 张婷——就是那个总穿靛蓝工装裤的测试——拿她的 M2 MacBook 跑 inference bench 对比结果,报错居然是 “libgomp.so.1: cannot open shared object file”,她发截图给我看的时候,我第一反应是她本地 brew install gcc 没生效,结果她回我:“没装 brew,我就开了个 Docker Desktop 里的 Ubuntu 22.04,什么都没动。” 我愣了三秒才想起来,Docker Desktop for Mac 的 LinuxKit VM 默认关闭 cgroup v2,而 PyTorch 2.1 的 CUDA backend 里某处有个 __attribute__((constructor)) 函数,在 v1 模式下会静默跳过一段内存对齐校验……但这事跟她没关系,她只是测了个 latency,不该管底层 mmap 失败是不是因 namespace 不匹配。 去年 KPI 里有条“降低新成员环境部署平均耗时”,我填的是“2.3 天→1.7 天”,HR 要求附证明,我甩了份内部 Wiki 页面链接过去——页面最后更新时间是去年十月,作者署名是我,内容却是“请确认是否已安装 NVIDIA Driver v525.60.13”,而我们线上早就切到 535.129.03 了。谁也没改那页。没人有空。就像我们上线流程里那个“需 DBA 签字确认 GPU 显存隔离策略”的环节,实际三年来签过字的只有老陈,他去年七月退休,章还在测试环境的 Jenkins 配置里挂着,名字栏自动填充为“DBA (vacant)”,没人删,也没人动。 最荒的是分布式训练跑一半 OOM,日志里满屏 “NCCL WARN Failed to open libibverbs.so[.1]”,但服务器压根没 InfiniBand 卡。查 nccl_kernel.c 源码才发现,它启动时会硬加载 libibverbs,失败就 warn,但不影响运行——warn 是真 warn,不是 debug 级别,它会冲掉真正该打的日志行。我原以为要重编译 NCCL,结果发现只需 export NCCL_IB_DISABLE=1,一行解决。可这行命令得写进每个 pod 的 initContainer,不能漏,不能拼错大小写,不能落在 volumeMount 后面——上次漏了,漏在 YAML 第 83 行缩进多了一个空格,Pod 卡在 Pending,整整五十二分钟没人 notice,直到运维巡检时扫了眼 kubectl get events,随口问了句“你们今天发啥版?” 现在我在等 GPU 节点的 firmware 升级窗口,周四凌晨两点到四点,要重启物理机。但我得先把 /etc/default/grub 里 splash quiet 改成 rdblacklist=nouveau,否则重启后驱动挂载顺序乱,nvidia-persistenced 启不来。这事不能 automation,得人工 ssh 进去改,因为 Ansible 某次批量执行时把 grub.cfg 写炸过三次,后来加了 checksum 校验,但校验逻辑本身有 race condition——上周五又炸了一次,炸在凌晨一点五十一分,我正泡面,水还没沸,手机就来了告警。面汤后来凉了,浮着一层凝固的油花,像显卡散热鳍片上的灰尘堆积图。 所以你说排障全路径?哪有什么全路径。全是断点、盲区、临时 patch 和忘记 revert 的 hotfix。我现在手边开着三个 terminal:一个 tail -f /var/log/nvidia-persistenced.log,一个 watch -n 0.5 'nvidia-smi -q -d MEMORY | grep -A5 "FB Memory Usage"',第三个终端里光标在 vim 的 /etc/docker/daemon.json 第二行闪着,我还没敲完 "default-runtime": "nvidia", 后面那个逗号,到底要不要加。 (编辑:站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |


嵌入式Linux开发者Unix环境搭建避坑指南
Linux运维老手也常踩的5个Unix环境搭建陷阱
深度学习服务器选型避坑与全栈调优实战
运营中心深度学习优化:交互响应提速40%
Windows数据科学环境搭建:15年工程师避坑与高效配置
Linux下H5开发环境与数据库一键配置