conda 与 screen 运维速查:环境隔离与断线重连
📝 笔记摘要:conda 与 screen 运维速查
原笔记是两份速查表,一份 conda 命令清单,一份 screen 快捷键清单。命令本身都在,缺的是三样东西:conda 和 venv 到底差在哪、为什么同一个环境里不能 conda 和 pip 混着装、screen 的 attach 与 detach 究竟是什么状态。
这三件事不搞清楚,命令背得再熟也会卡在同一个地方——装对了跑不起来,或者SSH 一断训练就没了。VSR 字幕抹除那篇要用到的 conda 环境和 screen 会话,源头都在这里。
1. conda 管的是依赖隔离
conda 最主要的功能是给每个项目开一个独立的「工作空间」。同一个 Python 解释器装不下两套互相冲突的依赖,环境的作用是把它们物理隔开。
conda 和 venv 的区别在哪
venv 只做一件事:复制一份 Python 解释器和空的 site-packages,纯 Python 隔离
conda 除了这个,还管非 Python 的东西——CUDA、cuDNN、NCCL、MKL、编译器,这些在 venv 里 pip 管不了
要装 GPU 相关的框架(PyTorch、Paddle、TensorFlow),conda 的环境才算完整
base 里不要装业务库
conda 自己和 pip 活在 base 里是正常的,但随手conda install装进去的包会被所有环境间接看到
base 一旦被污染,出问题时排查范围是全部环境
环境之间可以同时存在,不能同时激活
conda activate只改变当前 shell 的PATH,切到哪个就只有一个生效
磁盘上三份目录互不干扰,这才是隔离的意义
2. 环境的生命周期
一条命令走完一条路径:
# 建环境,顺手把依赖装上
conda create -n myproject python=3.9 numpy pandas
# 激活,提示符前面会多出 (myproject)
conda activate myproject
# 看有哪些环境,当前激活的那个前面有 *
conda env list
# 看这个环境里装了什么、来自哪个源
conda list
# 退出
conda deactivate
# 不再需要了,整个删掉
conda remove -n myproject --all
命名用小写加短横线,别用空格和中文
带空格的conda activate "my project"能用,但 shell 补全、脚本里引用都会麻烦
环境名会直接拼进目录路径~/anaconda3/envs/<名字>/
同一个名字 activate 两次不报错
但如果先后建过同名环境,旧的目录不会被覆盖,实际用的可能是第一次那个
建完先conda env list看一眼路径对不对
环境删了包还在缓存里
conda 有一份全局包缓存,删环境不会清缓存
conda clean --all能回收,但下次重建环境会重新走一遍解算
3. 包管理
# 装
conda install numpy
conda install numpy=1.26 # 锁版本
conda install numpy pandas # 一次多个
# 查
conda search numpy # 搜可用版本
conda list # 当前环境已装的
conda list --show-channel-urls # 顺便看每个包从哪个源来的
# 改
conda update numpy
conda update --all # 整环境升到最新兼容版本
# 删
conda remove numpy
conda 和 pip 在同一个环境里混装会打架
两个管理器互不认账,各自算各自的依赖
conda 觉得numpy 1.26满足要求,pip 又把目录里的文件换成了2.1
结果conda list显示的版本和python -c "import numpy; print(numpy.__version__)"打印的不一致
这类不一致 conda 不会报错,等到跑代码才炸
一旦要装的框架自带 CUDA 组件,别用 conda 装 CUDA 那套,见 video-subtitle-remover 字幕抹除部署里第五节讲的库加载冲突
选一个当主力
conda 能装的用 conda,conda 频道里没有的(大部分深度学习框架、纯工具类库)再用 pip
最省事的做法是pip install之后立刻conda list对一遍版本号
批量装库走 requirements.txt
pip install -r requirements.txt在任何环境里都能跑,包括别人机器上
这比在environment.yml里手写强,代价是丢失了「这个包来自哪个频道」的信息
导出环境做备份
conda env export > environment.yml带频道信息,还原时用conda env create -f
pip freeze > requirements.txt只有版本号,跨渠道复用更稳
4. Ubuntu 上装 Miniconda
# 1. 下载安装脚本
cd ~
wget https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh
# 2. 校验,输出和官网公布的哈希值比对
sha256sum Miniconda3-latest-Linux-x86_64.sh
# 3. 运行安装器
bash Miniconda3-latest-Linux-x86_64.sh
安装器会问两件事。安装路径默认 ~/miniconda3,回车确认即可,也可以自己指定。第二个问题是问要不要执行 conda init,选 yes。
# 4. 让配置生效(选过 yes 的话)
source ~/.bashrc
# 5. 验证
conda --version
conda info
conda activate 报 CommandNotFoundError
说明 shell 钩子没写进去,conda init bash重新生成,之后source ~/.bashrc
非 bash 的 shell 对应conda init zsh、conda init fish
用 Miniconda 还是 Anaconda
Miniconda 最小安装,几十 MB,后面装什么装什么
Anaconda 自带几百个科学计算包,几个 G,装完什么都不用也能直接用
服务器上选 Miniconda,磁盘和网络都省;本地想省事选 Anaconda
关掉 base 自动激活
conda config --set auto_activate_base false开回去改成true
每次开终端就进(base),容易让人忘了自己没激活目标环境
国内下载慢
Miniconda 脚本直连 repo.anaconda.com,不稳就浏览器下完再传上去
pip 换源:pip config set global.index-url https://mirrors.aliyun.com/pypi/simple/
5. screen 是跑在服务器上的物理终端
SSH 连上服务器开的那个终端,本质上是一根接到显示器的线。线一拔,显示器就没了。screen 在服务器上放一个虚拟显示器,你手上的终端只是一根可以随时插拔的线。
会话独立于 SSH 连接存在
screen 进程、shell、跑着的任务都活在服务器上,跟你用哪个终端连过来无关
重连时插回原来的显示器,输出还在往上滚
detach 的按键
Ctrl+a然后d,两步不能连着按成Ctrl+a+d
正确姿势:按住 Ctrl 按一下 a,松开两个键,再按 d
detach 之后训练才算真正安全
直接关 SSH 窗口,进程会收到 SIGHUP 被杀掉
必须先 detach,再关连接,这两步顺序不能反
6. 会话操作
# 建会话,起名字
screen -S training
# 列出所有会话,Detached 的后面带状态
screen -ls
# 重连
screen -r # 只有一个 detached 会话时直接进
screen -r training # 按名字
screen -r 12345 # 按 PID,PID 就是 screen -ls 里显示的那个数
# 已经有人连着的时候,踢掉旧连接自己进
screen -r -d training
# 强拆会话,不进去
screen -S training -X quit
# 关掉当前窗口,最后一个窗口关掉时会话自动结束
exit
screen -ls 的输出怎么读
12345.training (Detached)PID 是 12345,会话名 training,当前是分离状态
(Attached)表示已经有终端连着,screen -r会报refused
screen 不是 tmux
一个会话同一时刻只能被一个终端 attach,这是 screen 和 tmux 最容易踩的差别
tmux 支持多个客户端同时接入同一个会话,screen 不支持
会话残留了怎么清
机器重启过或者异常退出会留下(Detached)的僵尸会话
screen -S 名字 -X quit能强拆;不行就kill PID
为什么必须起名字
不命名的话screen -ls全是12345.pts-0这种,多开几个根本分不清
名字按任务起:training、vsr-batch、tail-log
7. 一个会话里开多个窗口
一个会话里可以有多个窗口,每个窗口是一个独立的 shell,可以分别跑不同的事。
Ctrl+a 然后 c 新建窗口
Ctrl+a 然后 n 切到下一个窗口
Ctrl+a 然后 p 切到上一个窗口
Ctrl+a 然后 数字 直接跳到指定编号,0-9
Ctrl+a 然后 " 列出所有窗口,选一个回车
Ctrl+a 然后 k 关掉当前窗口
窗口编号是 0 开始的
第一个窗口是 0 不是 1,新建窗口会占用下一个编号
编号只在当前会话内有意义,换个会话就对不上了
窗口切掉了但后台还挂着
关掉一个窗口不杀进程,进程会跟着 shell 一起结束
长任务跑完之前别随手按Ctrl+a k
screen 没有窗格
想一屏同时看训练输出和日志,用 tmux 的 split
screen 只能切换,看不到并排的两个窗口
8. 完整走一遍
# 1. 建一个专门给这个任务的环境
conda create -n myproject python=3.9
conda activate myproject
# 2. 建一个带名字的会话,进去了
screen -S training
# 3. 在会话里激活环境,起训练
conda activate myproject
python train.py -c config.yaml --resume checkpoints/latest.pth
# 4. 想关掉终端,但让训练继续
# Ctrl+a 然后 d,看到 [detached from training] 提示
# 5. 回本地终端了,该干嘛干嘛
# 6. 一天后想看进度
screen -ls # 确认 training 还在
screen -r training # 插回显示器
# 7. 看完再拔
# Ctrl+a 然后 d
# 8. 训练跑完了,在会话里 exit 结束
环境和会话是两件事
screen 保证进程活着,conda 保证依赖是对的
只做前者,重装系统后代码跑不起来;只做后者,SSH 一断进程就没了
两件都要做,而且要养成在会话里面激活环境的习惯
退出重登后环境激活状态不保留
conda activate只改当前 shell 的 PATH
重连进会话后要重新conda activate myproject
shell 变量不跨会话,这是设计上如此,不是 bug
训练输出别只看屏幕
屏幕滚回去了就找不回来,重定向到文件更保险
python train.py 2>&1 | tee train.log,屏幕和文件各留一份
💡 补充几个原文没写的:
screen 在 Ubuntu 上要单独装
最小化安装的服务器不带它,apt install screen
macOS 自带,Windows 得用 WSL
命令名是 Detach 不是 Detatch
原笔记写的 Detatch 是笔误,命令行输出里也是 Detached
conda 装非 Python 依赖的优势在这
conda install cudatoolkit这种操作 venv 做不到,只能装进 conda 环境
但注意 conda-forge 在 CUDA 12 迁移时已经移除了cudatoolkit这个包名,改成按组件拆分的cuda-*系列
老笔记里的conda install cudatoolkit=11.8在新版本 conda-forge 上会直接 PackagesNotFound
conda activate 之后 sudo 的行为会变
sudo conda activate会报环境变量丢失
要装系统级的包别加 sudo,会把包装到系统 Python 里,等于白装
多用户服务器注意环境路径权限
环境建在自己的~/anaconda3/envs/下,用 sudo 跑别人的环境可能没权限读
screen -X quit 会强拆,不给确认
里面正在跑的任务会直接收信号被杀
只是想让会话留在后台,用Ctrl+a d,不要用这条
🔥 一句话总结:conda 解决依赖隔离,环境之间用
conda create开、conda activate进、conda remove --all删,同一个环境里 conda 和 pip 不要混着装;screen 解决断线不掉线,起会话screen -S 名字、分离Ctrl+a再d、重连screen -r 名字;长任务的标准配置是「会话里面 conda activate 环境 → 起任务 → 分离走人」,环境要落成environment.yml或requirements.txt提交进仓库,否则 screen 留住了进程,留不住可复现性。
