分布式训练中SSH远程执行命令时环境失效的解决方法咨询
问题根源
SSH直接执行命令时,启动的是非交互式非登录Shell,不会自动加载~/.bashrc、~/.bash_profile这类用户配置文件,而conda的环境变量(包括conda命令路径、环境激活逻辑)都是在这些文件里初始化的,所以会出现conda: command not found,进而导致激活环境失败、依赖包找不到的问题。
具体解决方法
方法1:直接使用conda的绝对路径
先在远程机器手动执行which conda,得到conda的绝对路径(比如/home/xxx/miniconda3/bin/conda),然后替换命令中的conda:ssh -o StrictHostKeyChecking=no -p 22 43.0.0.1 'cd /sgnn/dist; /home/xxx/miniconda3/bin/conda activate sgnn;(export OMP_NUM_THREADS=2; python3 distDemo.py)'方法2:先加载用户配置文件
在执行conda命令前,先source加载~/.bashrc(如果用zsh则是~/.zshrc),让conda的环境变量生效:ssh -o StrictHostKeyChecking=no -p 22 43.0.0.1 'source ~/.bashrc; cd /sgnn/dist; conda activate sgnn;(export OMP_NUM_THREADS=2; python3 distDemo.py)'方法3:使用conda run直接指定环境执行
conda提供run命令,无需提前激活环境,直接指定环境名即可执行后续命令,简化逻辑:ssh -o StrictHostKeyChecking=no -p 22 43.0.0.1 'cd /sgnn/dist; conda run -n sgnn export OMP_NUM_THREADS=2 && python3 distDemo.py'如果还是找不到conda命令,同样换成绝对路径的conda执行。
方法4:修改远程机器的Shell配置(长期生效)
打开远程机器的~/.bashrc,找到conda初始化的代码段(通常是类似__conda_setup="$('/home/xxx/miniconda3/bin/conda' 'shell.bash' 'hook' 2> /dev/null)"的内容),把这段代码移到~/.profile文件中,或者删除~/.bashrc中判断是否为交互式Shell的逻辑(默认conda初始化代码会被包裹在if [ -z "${PS1:-}" ]; then return; fi这类判断里,删掉这段判断),这样非交互式Shell也能加载conda的环境变量。
内容的提问来源于stack exchange,提问作者BearBiscuit

