文章目录
- 问题背景
- 本文适用场景
- 作者环境
- 问题提出
- 问题解决方案
- 画面回传(步骤一)
- 解决方案
- 方法一
- 方法二
- 步骤一可能遇到的坑
- 解决spinning up视频回传问题(步骤二)
- 解决方案
- 步骤二可能遇到的坑
- 结语
问题背景
对于计算机专业的学生来说,尤其是研究牲,Mac的用户还是非常多的,自从苹果推出M芯片系列MacBook,关于一些开发环境的配置就成了大问题,很多软件并不支持ARM架构,作为一名人工智能领域的研究生,python的支持问题首当其冲,目前ARM架构下的python只支持3.8以后的版本,所以很多比较久远的项目在本地上难以运行。不过研究牲平时跑代码也主要在服务器上进行,所以这个问题并没有那么严重。更严重的问题是对于AI研究者来说,我们经常需要去plot一些图出来,图像回传到本地显示就成了大问题,对于强化学习来说,这个问题更加严重,因为强化学习往往需要回传的不仅是图片 ,而是视频。这个问题在X86架构(intel)下的Windows上很好解决,有大量的生态软件可以解决。而在ARM架构下的Mac OS下就很麻烦。
本文适用场景
本文主要讲解如何在M1系列(ARM架构) Mac环境下使用Vscode连接远程服务器配置spinning up环境,实现服务器跑代码,本地显示画面的功能。所实现的方法不仅用于spinning up环境也用于其他需要远程回传图像、openGL动画的需求。
作者环境
- MacBook pro(2021年 M1 pro芯片)
- Ubuntu 20.04.6 LTS
- Vscode 1.78.0
问题提出
今天想要学习一下强化学习算法,在网上搜到了著名的OpenAI spinning up教程1,在安装上就踩坑了,首先是我们的ARM架构笔记本无法安装spinning up要求的python3.6环境,这里我第一个想到的办法是,那就不用3.6用支持ARM的3.8就行了呗,很快就遇到了第一个问题:需求的库版本和python3.8版本不兼容导致无法安装的问题
可以看到项目依赖的tensorflow版本在python3.8下无法正常安装,而spinning up提供的安装方式pip install -e .
使得我们无法指定安装的库版本,所以在ARM架构下的新mac是无法在本地跑Spinning up环境的!这条路走死了,于是我们只能借助实验室的服务器配置环境并回传画面。
问题解决方案
接下来进入博客正题,本文尽量从简,只描述我们关心的问题,诸如VScode如何连接服务器写代码,网上有很多的博客教你,本文不再赘述,以下将主要解决如何从服务器上回传动画问题给出方案。
画面回传(步骤一)
解决方案
远程画面回传的原理是通过一个叫做X Window System的东西实现,具体原理本文不再赘述,这里给出一篇我解决这个问题时参考到的博客2,有兴趣的自行了解。
首先第一步,在我们的本地Mac机子上还需要再去安装一个XQuartz,不同于Windows丰富的生态,这是Mac上唯一的一个官方支持的X11客户端,作者当时也是苦苦搜寻了很久才找到。安装后一定要先运行XQuartz,它是一个应用程序,首次打开会请求系统权限并且初始化软件,打开后应该是一个终端页面,不用管它,直接关闭即可。
方法一
如果你的服务器和Mac本地主机是在一个网段(局域网)内,那么恭喜你无需配置,直接连接服务器只需要设置一个环境参数DISPLAY即可,export DISPLAY=macIP地址:0.0
。冒号后面数字的意思是:第0个设备的第0个屏幕。 mac的ip地址请在本地终端输入ifconfig
查看,或者通过系统的网络设置查看,完成后输出xclock即可在Mac看到时钟画面,具体画面在下文中。
如果你没有正常显示或者有报错,请检查Mac地址能不能在服务器上ping通,或者请尝试下面方法。
方法二
当然更加通用的方法是通过SSH方法连接。
我们需要对本地vscode SSH连接进行配置,打开Users/xxx/.ssh/config
文件进行设置(xxx代表用户名)或在选择连接远程服务器时选择Configure SSH Hosts
。
配置文件代码如下:
Host 服务器ipHostName 主机名User登录的账户名ForwardX11 yes(重点)ForwardX11Trusted yes(重点)ForwardAgent yes (重点)IdentityFile ~/.ssh/id_rsa (ssh秘钥文件)Host *AddKeysToAgent yes IdentityFile ~/.ssh/id_ed25519
这里的重点是ForwardX11
、ForwardX11Trusted
、ForwardAgent
要开启,代表开启X11服务,关于秘钥配置请自行百度,与本文无关。
然后通过SSH连接服务器,打开sudo vim /etc/ssh/sshd_config
,修改服务器的X11配置,打开文件后,找到
X11Forwarding yes
X11DisplayOffset 10
这两项在系统的默认设置里是被注释掉的,我们只需要去掉注释,或者你的配置里没有的话直接复制即可。完成后,执行指令sudo service sshd restart
然后退出终端重新ssh连接一下。
此时我们在本地和服务端的X11服务就都配置好了,安装完成后,ssh连接服务器,输入xclock
在我们本地的画面中应该出现了时钟的小动画,代表已经配置完成。
步骤一可能遇到的坑
- 第一次安装好的XQuartz是个app应用,应在本地先启动运行,并给予必要系统权限后再调用远程程序,避免因XQuartz应用未初始化而不能正常使用。
- ssh连接过去后,执行x11应用报错:
Error: Can't open display: localhost:10.0
,这时候要查看ssh命令执行后的第一条提示,如果出现了X11 forwarding request failed on channel 0
这表示实际本地和远端没有能建立起来X11协议的转发体系,原因可能有很多,比如连接端口不是10.0,或者认证没通过等等。 可以做以下的尝试:
方法一: 检查ping localhost是否能ping通,有可能是/etc/hosts中,没有把localhost指向127.0.0.1本机地址。这种情况可以设置显示到127.0.0.1:10.0就可以。
方法二: 在sudo vi /etc/ssh/sshd_config
增加一行:X11UseLocalhost yes
,接着sudo service sshd restart
。然后ssh重新连过来再试试。
方法三:
1.去掉自己设置$DISPLAY环境参数的脚本,比如我通常设置在.bashrc中最后一条,把这个设置删除,使用系统的自动设置功能。
(!!!这一条特别强调,如果你是在学校的实验室,服务器和他人共用,那么一定要使用系统的自动设置功能,因为这种情况下X服务器针对你的ssh连接生成的X会话DISPLAY端口会变,如果你是一个人独占服务器那么就不需要但心了。)
2.sudo vi /etc/ssh/sshd_config
,把刚才增加的X11UseLocalhost yes
改成:X11UseLocalhost no
,接着sudo service sshd restart
3.sudo apt purge xauth
然后sudo apt install xauth
重新安装xauth授权。
4.断开ssh连接,使用ssh -AX username@ip
地址重新连过来,-A的意思是使用X11认证授权方式,这样连接之后,linux主机会生成一个~/.Xauthority保存授权允许连接的远程终端信息。
5.echo $DISPLAY可以显示当前xauth自动生成的显示端口,比如我这里是:ubuntu:10.0,ubuntu是我的linux主机名,其实在我这里ubuntu跟localhost是一样的。
6.再次尝试执行x11应用,比如xclock,应当能成功了。
7.以后连接远程主机的时候,使用ssh -X …或者ssh -Y …而不用增加-A选项了,我们使用-A只是为了生成~/.Xauthority授权文件。
解决spinning up视频回传问题(步骤二)
在完成了基础的X会话画面回传后,这里我们解决第二个问题,当你运行spinning up检查安装的程序python -m spinup.run ppo --hid "[32,32]" --env LunarLander-v2 --exp_name installtest --gamma 0.999
结束后,想要查看你训练的策略效果如何时python -m spinup.run test_policy data/installtest/installtest_s0
又会报错:
根据报错的描述,可以发现是因为gym中的模块使用到了pyglet库,同时这个库的底层需要OPENGL做支撑。到这里我相信很多朋友都会直接复制libGL error: No matching fbConfigs or visuals found libGL error: failed to load driver: swrast
这两行去各大搜索引擎寻找解决方案,或者问chatgpt。很遗憾博主也这么干了,结果呢就是浪费了半天的时间,还差点搞乱了环境的配置。在网上确实有同样报错的问题,你去搜肯定会有贴子,比如说我当时看到的ask Ubuntu上面的回答,你可以参考他们的回答,然后就会发现具体出问题的地方又不一样。
博主在这里总结一下大家的解决方案,基本上就围绕三个方面:
- OpenGL库依赖错误
- NVIDIA显卡驱动问题
- Ubuntu系统问题
这是网上解决问题的方案,我推荐大家去看看网络上关于这个问题的讨论,但如果你想快速解决问题,同时你对上面三个问题没有很深的了解,我不建议你采用他们的方案,很容易把服务器的环境搞乱。我这里采用的方法实质上是一种间接的方法解决了问题,如果你搞明白了这个问题的原因,有了新的方案欢迎在评论区分享~
解决方案
接下来分享我采用的解决方案。首先介绍两个工具VirtualGL和TurboVNC:
VirtualGL 是一个能将 OpenGL 命令重定向到远程3D显示器的工具,而 TurboVNC 则是 VNC 的一个变体,专为3D或视频应用程序优化。
VirtualGL其实是一个传输OpenGL的服务器,TurboVNC则是视频的接收端,这一点也是作者在写作的时候想明白的,解决我们这个问题,TurboVNC也可以安装在你本地的Mac上,如果你只安装在服务器上,那么其实就是在服务器上本地接收,也就不存在网络通信的问题,但是其实你走的还是X协议,就是相当于绕过了服务器本地上的OpenGL环境问题,最终传输到Mac画面上的其实是通过X会话传输,如果你安装在Mac上,那么就不通过X会话,而是直接网络通信传输,说实话,当时作者解决这个问题的时候没有想到这一点。所以我采取的是将TurboVNC安装在服务器上的方式。但这样做也有一个好处就是避免了可能在Mac系统上M芯片导致的兼容问题。反正无论哪种方式,你都需要在服务器安装TurboVNC,后一种方式作者未做测试交给读者尝试。
在大多数基于Debian的Linux发行版(例如Ubuntu)上,你可以使用以下命令来安装:
sudo apt-get update
sudo apt-get install virtualgl turbovnc
安装完成后首先运行sudo vglserver_config
命令配置VirtualGL选第一项,然后就一路按照推荐配置选y就行。
接下来我们启动VNC服务器。运行vncserver
命令即可
记住这里出现的端口号zkti:1,我们一会要用。
接着我们新开一个终端会话,或者你可以使用tmux
新建一个会话,在这里我们运行vglclient
实例化一个vgl客户端,用于监听vgl服务端发送来的OpenGL程序。打开后界面就会停留在这里,不用的时候可以按ctrl+c退出。然后我们用另一个终端去spinningup目录中,运行vglrun -d :1 python -m spinup.run test_policy data/installtest/installtest_s0
然后我们的程序就跑起来啦!!!!
最后我要特别说明一点!!!!这一点非常重要,不然会导致出现另外一个错误!当我们跑完程序,退出终端时要使用ctrl+c手动关闭vglclient,如果你直接退出终端,那么vglclient也会关闭,因为每个终端分配一个X会话,vglclient通过绑定X会话传输动画。这样强制退出后,下次开启可能会有问题。当然你也可以采用我之前说过的第二种方法,这样理论上就不存在X会话的问题,欢迎读者朋友们踊跃尝试!
第二个步骤出现的坑非常多,我解决也用了非常多的时间,如果你遇到任何问题请在下面我总结出的坑中找答案。
步骤二可能遇到的坑
1.安装两个软件的时候报错,找不到软件源。
如果你的apt无法自动为你安装,那么你可以采取官网安装包安装的方式
VirtualGL 和 TurboVNC 的官方网站如下:
- VirtualGL:https://www.virtualgl.org/
- TurboVNC:https://www.turbovnc.org/
在这两个网站上,你可以找到各种系统和架构的安装包,以及详细的安装和使用说明。
2.运行sudo vglserver_config
出现提示
这个其实我们可以不管,在我测试是没有对我们的需求产生影响,如果影响到了你,那么你可以按照建议尝试执行modprobe -r nvidia_uvm nvidia_drm nvidia_modeset nvidia
来卸载显卡驱动相关模块,注意:如果你是多人共用服务器,我建议不要运行,当他们占用显卡时,这条指令也不会成功执行,具体你可以再去找找网上的解释。我这里因为不影响操作,不做过多赘述。
3.vncserver命令找不到
输入find /opt -name vncserver
,将显示的路径,通过export命令导入环境,也可在你的bash文件中添加这一行命令export PATH=$PATH:显示的路径
,然后再重新运行命令。
4.运行动画程序,一闪而过,服务端报错
这里是因为没有开启vglclient的原因,请按照上文顺序,先开启vglclient再运行动画程序。
结语
以上就是今天给大家分享的如何解决M1 Mac配置Linux服务器强化学习教程Spinning up环境实现画面回传(包含OPENGL问题解决方案),作者在解决这个问题的时候,由于缺少网络资料,前前后后花了两天多的时间,才算彻底搞明白。写出这篇博客又花了一天时间复盘,写作。写完能帮助读者快速的解决问题,节约自己的时间。创作不易,希望大家一键三连~感谢!
OpenAI spinning up教程 ↩︎
X Window System原理介绍 ↩︎